diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 1c31e002eb4..55c7a2d2d64 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -28,18 +28,10 @@ library Constants { uint256 internal constant MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 2; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; uint256 internal constant MAX_NEW_NOTE_HASHES_PER_TX = 64; - uint256 internal constant MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; - uint256 internal constant MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX = 64; - uint256 internal constant MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; - uint256 internal constant MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; uint256 internal constant MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX = 8; uint256 internal constant MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX = 8; - uint256 internal constant MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX = 3; - uint256 internal constant MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX = 5; uint256 internal constant MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 32; - uint256 internal constant MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 16; - uint256 internal constant MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 16; uint256 internal constant MAX_PUBLIC_DATA_READS_PER_TX = 32; uint256 internal constant MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2; uint256 internal constant MAX_NOTE_HASH_READ_REQUESTS_PER_TX = 128; diff --git a/noir-projects/noir-protocol-circuits/Nargo.toml b/noir-projects/noir-protocol-circuits/Nargo.toml index ee1eda1c511..d3f3c3d55b0 100644 --- a/noir-projects/noir-protocol-circuits/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/Nargo.toml @@ -11,6 +11,8 @@ members = [ "crates/private-kernel-inner-simulated", "crates/private-kernel-tail", "crates/private-kernel-tail-simulated", + "crates/private-kernel-tail-to-public", + "crates/private-kernel-tail-to-public-simulated", "crates/public-kernel-lib", "crates/public-kernel-setup", "crates/public-kernel-setup-simulated", diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr index 32f7895e376..a152eb992f1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; -use dep::types::PrivateKernelInnerCircuitPublicInputs; +use dep::types::PrivateKernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelInnerCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_initial() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr index 7b1ad814c18..7c89bdaaa97 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; -use dep::types::PrivateKernelInnerCircuitPublicInputs; +use dep::types::PrivateKernelCircuitPublicInputs; -fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelInnerCircuitPublicInputs { +fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_initial() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr index a6d630389b2..5d067c6bdb1 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; -use dep::types::PrivateKernelInnerCircuitPublicInputs; +use dep::types::PrivateKernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelInnerCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_inner() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr index 9ea712f5d35..d4a0f8bd28d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; -use dep::types::PrivateKernelInnerCircuitPublicInputs; +use dep::types::PrivateKernelCircuitPublicInputs; -fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelInnerCircuitPublicInputs { +fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_inner() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr index 416aefca438..791edcfeb99 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/common.nr @@ -1,11 +1,11 @@ use dep::std; use dep::types::{ abis::{ - call_request::CallRequest, accumulated_data::CombinedAccumulatedData, + call_request::CallRequest, accumulated_data::PrivateAccumulatedData, kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputsBuilder, max_block_number::MaxBlockNumber, membership_witness::NoteHashReadRequestMembershipWitness, private_circuit_public_inputs::PrivateCircuitPublicInputs, - private_kernel::private_call_data::PrivateCallData, kernel_data::PrivateKernelInnerData, + private_kernel::private_call_data::PrivateCallData, kernel_data::PrivateKernelData, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, EthAddress, PartialAddress, compute_initialization_hash}, @@ -15,10 +15,9 @@ use dep::types::{ MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL }, - grumpkin_private_key::GrumpkinPrivateKey, hash::{ - compute_l2_to_l1_hash, compute_logs_hash, pedersen_hash, private_functions_root_from_siblings, - silo_note_hash, silo_nullifier, stdlib_recursion_verification_key_compress_native_vk + compute_l2_to_l1_hash, compute_logs_hash, private_functions_root_from_siblings, silo_note_hash, + silo_nullifier, stdlib_recursion_verification_key_compress_native_vk }, merkle_tree::check_membership, utils::{arrays::{array_length, array_to_bounded_vec, validate_array}}, @@ -85,7 +84,7 @@ pub fn validate_note_hash_read_requests( } pub fn initialize_end_values( - previous_kernel: PrivateKernelInnerData, + previous_kernel: PrivateKernelData, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder ) { public_inputs.constants = previous_kernel.public_inputs.constants; @@ -345,7 +344,7 @@ pub fn contract_logic(private_call: PrivateCallData) { assert(computed_address.eq(contract_address), "computed contract address does not match expected one"); } -pub fn validate_previous_kernel_values(end: CombinedAccumulatedData) { +pub fn validate_previous_kernel_values(end: PrivateAccumulatedData) { assert(end.new_nullifiers[0].value != 0, "The 0th nullifier in the accumulated nullifier array is zero"); } @@ -379,28 +378,3 @@ pub fn validate_call_against_request(private_call: PrivateCallData, request: Cal ); } } - -fn field_to_grumpkin_private_key(val: Field) -> GrumpkinPrivateKey { - let bytes = val.to_be_bytes(32); - let mut v = 1; - let mut high = 0; - let mut low = 0; - - for i in 0..16 { - high = high + (bytes[15 - i] as Field) * v; - low = low + (bytes[16 + 15 - i] as Field) * v; - v = v * 256; - } - - GrumpkinPrivateKey { high, low } -} - -pub fn compute_siloed_nullifier_secret_key(secret_key: GrumpkinPrivateKey, contract_address: AztecAddress) -> GrumpkinPrivateKey { - // TODO: Temporary hack. Should replace it with a secure way to derive the secret key. - // Match the way keys are derived in circuits.js/src/keys/index.ts - let hash = pedersen_hash( - [secret_key.high, secret_key.low, contract_address.to_field()], - 0 - ); - field_to_grumpkin_private_key(hash) -} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr new file mode 100644 index 00000000000..c2a16634303 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/kernel_circuit_public_inputs_composer.nr @@ -0,0 +1,210 @@ +use crate::common; +use dep::std::{cmp::Eq, option::Option, unsafe}; +use dep::reset_kernel_lib::{NullifierReadRequestHints, PrivateValidationRequestProcessor}; +use dep::types::{ + abis::{ + kernel_data::PrivateKernelData, + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder, PublicKernelCircuitPublicInputs}, + side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX +}, + grumpkin_private_key::GrumpkinPrivateKey, + hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, + utils::arrays::{array_length, array_to_bounded_vec, assert_sorted_array}, traits::{Empty, is_empty} +}; + +fn asc_sort_by_counters(a: T, b: T) -> bool where T: Ordered { + a.counter() < b.counter() +} + +struct KernelCircuitPublicInputsComposer { + public_inputs: PrivateKernelCircuitPublicInputsBuilder, + previous_kernel: PrivateKernelData, + sorted_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], + transient_note_hash_index_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], +} + +impl KernelCircuitPublicInputsComposer { + pub fn new( + previous_kernel: PrivateKernelData, + sorted_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + sorted_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], + transient_note_hash_index_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX] + ) -> Self { + let public_inputs: PrivateKernelCircuitPublicInputsBuilder = unsafe::zeroed(); + + KernelCircuitPublicInputsComposer { + public_inputs, + previous_kernel, + sorted_note_hashes, + sorted_note_hashes_indexes, + sorted_nullifiers, + sorted_nullifiers_indexes, + transient_note_hash_index_hints + } + } + + pub fn compose(&mut self) -> Self { + assert_eq( + array_length(self.previous_kernel.public_inputs.end.private_call_stack), 0, "Private call stack must be empty when executing the tail circuit" + ); + + self.propagate_rollup_validation_requests(); + + self.propagate_constant_data(); + + self.propagate_sorted_arrays(); + + // TODO: Should be done in a reset circuit. + self.squash_transient_note_hashes_and_nullifiers(); + + self.silo_values(); + + *self + } + + pub fn compose_public(&mut self) -> Self { + let _ = self.compose(); + + self.propagate_sorted_public_call_requests(); + + *self + } + + pub fn finish(self) -> KernelCircuitPublicInputs { + self.public_inputs.finish_tail() + } + + pub fn finish_to_public(self) -> PublicKernelCircuitPublicInputs { + let min_revertible_side_effect_counter = self.previous_kernel.public_inputs.min_revertible_side_effect_counter; + self.public_inputs.finish_to_public(min_revertible_side_effect_counter) + } + + fn silo_values(&mut self) { + self.silo_note_hashes(); + // TODO: Move siloing from init/inner circuits to here. + } + + fn silo_note_hashes(&mut self) { + let first_nullifier = self.public_inputs.end.new_nullifiers.get_unchecked(0); + assert(first_nullifier.value != 0, "The 0th nullifier in the accumulated nullifier array is zero"); + + let note_hashes = self.public_inputs.end.new_note_hashes.storage; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + let note_hash = note_hashes[i]; + if note_hash.value != 0 { + let nonce = compute_note_hash_nonce(first_nullifier.value, i); + let unique_note_hash = compute_unique_siloed_note_hash(nonce, note_hash.value); + self.public_inputs.end.new_note_hashes.storage[i].value = unique_note_hash; + } + } + } + + fn propagate_rollup_validation_requests(&mut self) { + self.public_inputs.validation_requests.max_block_number = self.previous_kernel.public_inputs.validation_requests.for_rollup.max_block_number; + } + + fn propagate_constant_data(&mut self) { + self.public_inputs.constants = self.previous_kernel.public_inputs.constants; + } + + fn propagate_sorted_arrays(&mut self) { + let accumulated_data = self.previous_kernel.public_inputs.end; + + assert_sorted_array( + accumulated_data.new_note_hashes, + self.sorted_note_hashes, + self.sorted_note_hashes_indexes, + asc_sort_by_counters + ); + self.public_inputs.end.new_note_hashes = array_to_bounded_vec(self.sorted_note_hashes); + + assert_sorted_array( + accumulated_data.new_nullifiers, + self.sorted_nullifiers, + self.sorted_nullifiers_indexes, + asc_sort_by_counters + ); + self.public_inputs.end.new_nullifiers = array_to_bounded_vec(self.sorted_nullifiers); + + // TODO: Sort all the side effects below. + self.public_inputs.end.new_l2_to_l1_msgs = array_to_bounded_vec(accumulated_data.new_l2_to_l1_msgs); + self.public_inputs.end.encrypted_logs_hash = accumulated_data.encrypted_logs_hash; + self.public_inputs.end.unencrypted_logs_hash = accumulated_data.unencrypted_logs_hash; + self.public_inputs.end.encrypted_log_preimages_length = accumulated_data.encrypted_log_preimages_length; + self.public_inputs.end.unencrypted_log_preimages_length = accumulated_data.unencrypted_log_preimages_length; + } + + fn propagate_sorted_public_call_requests(&mut self) { + let accumulated_data = self.previous_kernel.public_inputs.end; + self.public_inputs.end.public_call_stack = array_to_bounded_vec(accumulated_data.public_call_stack); + } + + fn squash_transient_note_hashes_and_nullifiers(&mut self) { + // Remark: The commitments in public_inputs.end have already been siloed by contract address! + // Match nullifiers/nullified_commitments to commitments from the previous call(s) + let mut new_note_hashes = self.public_inputs.end.new_note_hashes.storage; + let mut new_nullifiers = self.public_inputs.end.new_nullifiers.storage; + + // Should start from 1 to skip the first nullifier? + for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { + let nullifier = new_nullifiers[n_idx]; + // TODO - should not be able to squash the first nullifier. + let nullified_note_hash = nullifier.note_hash; + let hint_pos = self.transient_note_hash_index_hints[n_idx]; + + // Nullified_commitment of value `0` implies non-transient (persistable) + // nullifier in which case no attempt will be made to match it to a hash. + // Non-empty nullified_note_hash implies transient nullifier which MUST be matched to a hash below! + // 0-valued nullified_note_hash is empty and will be ignored + if nullified_note_hash != 0 { + assert( + hint_pos < MAX_NEW_NOTE_HASHES_PER_TX, "New nullifier is transient but hint is invalid" + ); + let hash = new_note_hashes[hint_pos]; + assert_eq(nullified_note_hash, hash.value, "Hinted hash does not match"); + assert( + nullifier.counter > hash.counter, "Nullifier counter must be greater than hash counter" + ); + // match found! + // squash both the nullifier and the hash + // (set to 0 here and then rearrange array after loop) + new_note_hashes[hint_pos] = SideEffect::empty(); + new_nullifiers[n_idx] = SideEffectLinkedToNoteHash::empty(); + } + // non-transient (persistable) nullifiers are just kept in new_nullifiers array and forwarded + // to public inputs (used later by base rollup circuit) + } + + // Move all zero-ed (removed) entries of these arrays to the end and preserve ordering of other entries + + let mut new_note_hashes_vec = BoundedVec::new(); + + for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { + if new_note_hashes[c_idx].value != 0 { + new_note_hashes_vec.push(new_note_hashes[c_idx]); + } + } + + self.public_inputs.end.new_note_hashes = new_note_hashes_vec; + + let mut new_nullifiers_vec = BoundedVec::new(); + + for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { + if new_nullifiers[n_idx].value != 0 { + new_nullifiers_vec.push(new_nullifiers[n_idx]); + } + } + + self.public_inputs.end.new_nullifiers = new_nullifiers_vec; + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr index e892008b41a..d4d12a8b06a 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/lib.nr @@ -1,10 +1,13 @@ +mod kernel_circuit_public_inputs_composer; mod private_kernel_init; mod private_kernel_inner; mod private_kernel_tail; +mod private_kernel_tail_to_public; use private_kernel_init::PrivateKernelInitCircuitPrivateInputs; use private_kernel_inner::PrivateKernelInnerCircuitPrivateInputs; use private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; +use private_kernel_tail_to_public::PrivateKernelTailToPublicCircuitPrivateInputs; // TODO: rename to be precise as to what its common to. mod common; diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr index 73139ca59b2..afbdb75445e 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_init.nr @@ -3,7 +3,7 @@ use dep::std::unsafe; use dep::types::{ abis::{ combined_constant_data::CombinedConstantData, private_kernel::private_call_data::PrivateCallData, - kernel_circuit_public_inputs::{PrivateKernelInnerCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, + kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, PublicKeysHash, compute_initialization_hash}, @@ -76,9 +76,8 @@ impl PrivateKernelInitCircuitPrivateInputs { // https://github.com/AztecProtocol/aztec-packages/issues/660 } - pub fn native_private_kernel_circuit_initial(self) -> PrivateKernelInnerCircuitPublicInputs { + pub fn native_private_kernel_circuit_initial(self) -> PrivateKernelCircuitPublicInputs { let mut public_inputs: PrivateKernelCircuitPublicInputsBuilder = unsafe::zeroed(); - public_inputs.is_private = true; self.initialize_end_values(&mut public_inputs); @@ -107,7 +106,7 @@ impl PrivateKernelInitCircuitPrivateInputs { public_inputs.aggregation_object = updated_aggregation_object; - public_inputs.to_inner() + public_inputs.finish() } } @@ -115,7 +114,7 @@ mod tests { use crate::private_kernel_init::PrivateKernelInitCircuitPrivateInputs; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, nullifier_key_validation_request::NullifierKeyValidationRequest, private_kernel::private_call_data::PrivateCallData, read_request::ReadRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} @@ -142,7 +141,7 @@ mod tests { PrivateKernelInitInputsBuilder { tx_request, private_call } } - pub fn execute(self) -> PrivateKernelInnerCircuitPublicInputs { + pub fn execute(self) -> PrivateKernelCircuitPublicInputs { let kernel = PrivateKernelInitCircuitPrivateInputs { tx_request: self.tx_request, private_call: self.private_call.finish() }; kernel.native_private_kernel_circuit_initial() diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr index 3b03d951d47..4faf0831bf9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -2,15 +2,15 @@ use crate::common; use dep::std::unsafe; use dep::types::{ abis::{ - kernel_data::PrivateKernelInnerData, private_kernel::private_call_data::PrivateCallData, - kernel_circuit_public_inputs::{PrivateKernelInnerCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, + kernel_data::PrivateKernelData, private_kernel::private_call_data::PrivateCallData, + kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PrivateKernelCircuitPublicInputsBuilder}, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, mocked::verify_previous_kernel_state }; struct PrivateKernelInnerCircuitPrivateInputs { - previous_kernel: PrivateKernelInnerData, + previous_kernel: PrivateKernelData, private_call: PrivateCallData, } @@ -24,14 +24,10 @@ impl PrivateKernelInnerCircuitPrivateInputs { let this_call_stack_item = self.private_call.call_stack_item; let function_data = this_call_stack_item.function_data; assert(function_data.is_private, "Private kernel circuit can only execute a private function"); - assert( - self.previous_kernel.public_inputs.is_private, "Can only verify a private kernel snark in the private kernel circuit" - ); } - pub fn native_private_kernel_circuit_inner(self) -> PrivateKernelInnerCircuitPublicInputs { + pub fn native_private_kernel_circuit_inner(self) -> PrivateKernelCircuitPublicInputs { let mut public_inputs : PrivateKernelCircuitPublicInputsBuilder = unsafe::zeroed(); - public_inputs.is_private = true; common::validate_previous_kernel_values(self.previous_kernel.public_inputs.end); @@ -61,7 +57,7 @@ impl PrivateKernelInnerCircuitPrivateInputs { public_inputs.aggregation_object = updated_aggregation_object; - public_inputs.to_inner() + public_inputs.finish() } } @@ -70,24 +66,28 @@ mod tests { use dep::types::constants::{MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX}; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, + kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, max_block_number::MaxBlockNumber, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, address::{AztecAddress, EthAddress}, hash::compute_logs_hash, messaging::l2_to_l1_message::L2ToL1Message, utils::{arrays::array_length}, - tests::{kernel_data_builder::PreviousKernelDataBuilder, private_call_data_builder::PrivateCallDataBuilder} + tests::{private_call_data_builder::PrivateCallDataBuilder, fixture_builder::FixtureBuilder} }; + use dep::std::unsafe; struct PrivateKernelInnerInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, private_call: PrivateCallDataBuilder, } impl PrivateKernelInnerInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(false); + let mut previous_kernel = FixtureBuilder::new(); let private_call = PrivateCallDataBuilder::new(); + // 0th nullifier must be non-zero. + previous_kernel.append_new_nullifiers(1); + PrivateKernelInnerInputsBuilder { previous_kernel, private_call } } @@ -101,13 +101,13 @@ mod tests { *self } - pub fn execute(&mut self) -> PrivateKernelInnerCircuitPublicInputs { + pub fn execute(&mut self) -> PrivateKernelCircuitPublicInputs { let private_call = self.private_call.finish(); // Update the previous_kernel's private_call_stack with the current call_stack_item. let hash = private_call.call_stack_item.hash(); let is_delegate_call = private_call.call_stack_item.public_inputs.call_context.is_delegate_call; self.previous_kernel.push_private_call_request(hash, is_delegate_call); - let previous_kernel = self.previous_kernel.to_private_kernel_inner_data(); + let previous_kernel = self.previous_kernel.to_private_kernel_data(); let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call }; @@ -185,7 +185,7 @@ mod tests { let hash = private_call.call_stack_item.hash(); // Set the first call stack hash to a wrong value (the correct hash + 1). builder.previous_kernel.push_private_call_request(hash + 1, false); - let previous_kernel = builder.previous_kernel.to_private_kernel_inner_data(); + let previous_kernel = builder.previous_kernel.to_private_kernel_data(); let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call }; @@ -227,7 +227,7 @@ mod tests { // Caller context is empty for regular calls. let is_delegate_call = false; builder.previous_kernel.push_private_call_request(hash, is_delegate_call); - let previous_kernel = builder.previous_kernel.to_private_kernel_inner_data(); + let previous_kernel = builder.previous_kernel.to_private_kernel_data(); let kernel = PrivateKernelInnerCircuitPrivateInputs { previous_kernel, private_call }; @@ -466,14 +466,7 @@ mod tests { builder.private_call.public_inputs.new_note_hashes.push(SideEffect { value: 4321, counter: 0 }); // Mock the previous new note hashes to be full, therefore no more commitments can be added. - let mut full_new_note_hashes = [SideEffect::empty(); MAX_NEW_NOTE_HASHES_PER_TX]; - for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - full_new_note_hashes[i] = SideEffect { - value: i as Field + 1, - counter: i as u32, - }; - } - builder.previous_kernel.end.new_note_hashes.extend_from_array(full_new_note_hashes); + builder.previous_kernel.append_new_note_hashes(MAX_NEW_NOTE_HASHES_PER_TX); builder.failed(); } @@ -487,15 +480,6 @@ mod tests { builder.failed(); } - #[test(should_fail_with="Can only verify a private kernel snark in the private kernel circuit")] - fn previous_kernel_is_private_false_fails() { - let mut builder = PrivateKernelInnerInputsBuilder::new(); - - builder.previous_kernel.is_private = false; - - builder.failed(); - } - #[test(should_fail_with="note hash tree root mismatch")] fn native_note_hash_read_request_bad_request() { let mut builder = PrivateKernelInnerInputsBuilder::new(); @@ -553,7 +537,7 @@ mod tests { #[test] fn propagate_previous_kernel_max_block_number() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13); + builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); let public_inputs = builder.execute(); assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13); @@ -571,7 +555,7 @@ mod tests { #[test] fn ignore_larger_max_block_number() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13); + builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); // A private call requesting a larger max_block_number should not change the current one as that constraint is // already satisfied. builder.private_call.request_max_block_number(42); @@ -729,7 +713,7 @@ mod tests { fn zero_0th_nullifier_fails() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - builder.previous_kernel.end.new_nullifiers = BoundedVec::new(); + builder.previous_kernel.new_nullifiers = BoundedVec::new(); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr index 3e8493f596c..a655a8f017c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -1,25 +1,19 @@ -use crate::common; -use dep::std::{cmp::Eq, option::Option, unsafe}; -use dep::reset_kernel_lib::{NullifierReadRequestHints, reset_read_requests}; +use crate::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; +use dep::reset_kernel_lib::{NullifierReadRequestHints, PrivateValidationRequestProcessor}; use dep::types::{ abis::{ - call_request::CallRequest, nullifier_key_validation_request::NullifierKeyValidationRequestContext, - kernel_data::PrivateKernelInnerData, - kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputsBuilder, PrivateKernelTailCircuitPublicInputs}, - side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} + kernel_data::PrivateKernelData, kernel_circuit_public_inputs::KernelCircuitPublicInputs, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, constants::{ MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX }, - grumpkin_private_key::GrumpkinPrivateKey, - hash::{compute_note_hash_nonce, compute_unique_siloed_note_hash}, - utils::{arrays::{array_length, array_eq}}, traits::{Empty, is_empty} + grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length }; struct PrivateKernelTailCircuitPrivateInputs { - previous_kernel: PrivateKernelInnerData, + previous_kernel: PrivateKernelData, sorted_new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], sorted_new_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX], read_commitment_hints: [u64; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], @@ -31,249 +25,59 @@ struct PrivateKernelTailCircuitPrivateInputs { } impl PrivateKernelTailCircuitPrivateInputs { - fn validate_inputs(self) { + pub fn native_private_kernel_circuit_tail(self) -> KernelCircuitPublicInputs { + let previous_public_inputs = self.previous_kernel.public_inputs; assert_eq( - array_length(self.previous_kernel.public_inputs.end.private_call_stack), 0, "Private call stack must be empty when executing the tail circuit" + array_length(previous_public_inputs.end.public_call_stack), 0, "Public call stack must be empty when executing the tail circuit" ); - } - - fn validate_nullifier_read_requests(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - let requests = self.previous_kernel.public_inputs.validation_requests.nullifier_read_requests; - - let pending_nullifiers = self.previous_kernel.public_inputs.end.new_nullifiers; - - let hints = self.nullifier_read_request_hints; - - let nullifier_tree_root = public_inputs.constants.historical_header.state.partial.nullifier_tree.root; - - public_inputs.validation_requests.nullifier_read_requests = reset_read_requests( - requests, - pending_nullifiers, - hints.read_request_statuses, - hints.pending_read_hints, - hints.settled_read_hints, - nullifier_tree_root, - ); - // When we have a separate reset circuit, we can allow unverified requests and process them later after the - // corresponding values are added to public inputs in nested executions. - // But right now, all the request must be cleared in one go. - assert( - public_inputs.validation_requests.nullifier_read_requests.len() == 0, "All nullifier read requests must be verified" - ); - } - - fn validate_nullifier_keys(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - let requests = self.previous_kernel.public_inputs.validation_requests.nullifier_key_validation_requests; - for i in 0..MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX { - let request = requests[i]; - if !is_empty(request) { - let master_secret_key = self.master_nullifier_secret_keys[i]; - let computed_public_key = master_secret_key.derive_public_key(); - assert( - computed_public_key.eq(request.public_key), "Cannot derive nullifier public key from the master key." - ); - - let computed_secret_key = common::compute_siloed_nullifier_secret_key(master_secret_key, request.contract_address); - assert( - computed_secret_key.eq(request.secret_key), "Cannot derive siloed secret key from the master key." - ); - } - } - - // Empty out nullifier key validation requests after verifying them. - public_inputs.validation_requests.nullifier_key_validation_requests = BoundedVec::new(); - } - - fn match_reads_to_commitments(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - let new_note_hashes = public_inputs.end.new_note_hashes; - let read_requests = public_inputs.validation_requests.note_hash_read_requests; - - // match reads to commitments from the previous call(s) - for rr_idx in 0..MAX_NOTE_HASH_READ_REQUESTS_PER_TX { - let read_request = read_requests.get_unchecked(rr_idx); - let read_commitment_hint = self.read_commitment_hints[rr_idx]; - - if (read_request.value != 0) { - let hash = new_note_hashes.get_unchecked(read_commitment_hint); - assert_eq(read_request.value, hash.value, "Hinted hash does not match read request"); - assert( - read_request.counter > hash.counter, "Read request counter must be greater than hash counter" - ); - } - } - - // Empty out read requests after matching them to commitments - public_inputs.validation_requests.note_hash_read_requests = BoundedVec::new(); - } - - fn assert_sorted_counters(original: [T; N], sorted: [T; N], indexes: [u64; N]) where T: Eq + Ordered + Empty { - let mut prev_was_empty = false; - for i in 0..N { - let item = if prev_was_empty { - sorted[i] - } else { - sorted[indexes[i]] - }; - assert(item.eq(original[i]), "Sorted item is not equal"); - let is_empty = is_empty(item); - - if prev_was_empty { - assert(is_empty, "Empty items must be at the end"); - } else if (i != 0) & !is_empty { - assert(sorted[i].counter() > sorted[i - 1].counter(), "Not sorted"); - } - - prev_was_empty = is_empty; - } - } - - fn sort_arrays(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( - public_inputs.end.new_note_hashes.storage, + let nullifier_tree_root = previous_public_inputs.constants.historical_header.state.partial.nullifier_tree.root; + let request_processor = PrivateValidationRequestProcessor { + validation_requests: previous_public_inputs.validation_requests, + note_hash_read_request_hints: self.read_commitment_hints, + pending_note_hashes: previous_public_inputs.end.new_note_hashes, + nullifier_read_request_hints: self.nullifier_read_request_hints, + pending_nullifiers: previous_public_inputs.end.new_nullifiers, + master_nullifier_secret_keys: self.master_nullifier_secret_keys, + nullifier_tree_root + }; + request_processor.validate(); + + let mut composer = KernelCircuitPublicInputsComposer::new( + self.previous_kernel, self.sorted_new_note_hashes, - self.sorted_new_note_hashes_indexes - ); - PrivateKernelTailCircuitPrivateInputs::assert_sorted_counters( - public_inputs.end.new_nullifiers.storage, + self.sorted_new_note_hashes_indexes, self.sorted_new_nullifiers, - self.sorted_new_nullifiers_indexes + self.sorted_new_nullifiers_indexes, + self.nullifier_commitment_hints ); - public_inputs.end.new_note_hashes.storage = self.sorted_new_note_hashes; - public_inputs.end.new_nullifiers.storage = self.sorted_new_nullifiers; - } - - fn match_nullifiers_to_note_hashes_and_squash(self, public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - // Remark: The commitments in public_inputs.end have already been siloed by contract address! - // Match nullifiers/nullified_commitments to commitments from the previous call(s) - let mut new_note_hashes = public_inputs.end.new_note_hashes.storage; - let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; - - for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { - let nullifier = new_nullifiers[n_idx]; - // TODO - should not be able to squash the first nullifier. - let nullified_note_hash = nullifier.note_hash; - let hint_pos = self.nullifier_commitment_hints[n_idx]; - - // Nullified_commitment of value `0` implies non-transient (persistable) - // nullifier in which case no attempt will be made to match it to a hash. - // Non-empty nullified_note_hash implies transient nullifier which MUST be matched to a hash below! - // 0-valued nullified_note_hash is empty and will be ignored - if nullified_note_hash != 0 { - assert( - hint_pos < MAX_NEW_NOTE_HASHES_PER_TX, "New nullifier is transient but hint is invalid" - ); - let hash = new_note_hashes[hint_pos]; - assert_eq(nullified_note_hash, hash.value, "Hinted hash does not match"); - assert( - nullifier.counter > hash.counter, "Nullifier counter must be greater than hash counter" - ); - // match found! - // squash both the nullifier and the hash - // (set to 0 here and then rearrange array after loop) - new_note_hashes[hint_pos] = SideEffect::empty(); - new_nullifiers[n_idx] = SideEffectLinkedToNoteHash::empty(); - } - // non-transient (persistable) nullifiers are just kept in new_nullifiers array and forwarded - // to public inputs (used later by base rollup circuit) - } - - // Move all zero-ed (removed) entries of these arrays to the end and preserve ordering of other entries - - let mut new_note_hashes_vec = BoundedVec::new(); - - for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { - if new_note_hashes[c_idx].value != 0 { - new_note_hashes_vec.push(new_note_hashes[c_idx]); - } - } - - public_inputs.end.new_note_hashes = new_note_hashes_vec; - - let mut new_nullifiers_vec = BoundedVec::new(); - - for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { - if new_nullifiers[n_idx].value != 0 { - new_nullifiers_vec.push(new_nullifiers[n_idx]); - } - } - - public_inputs.end.new_nullifiers = new_nullifiers_vec; - } - - fn apply_note_hash_nonces(public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder) { - // Remark: The commitments in public_inputs.end have already been siloed by contract address! - // tx hash - let first_nullifier = public_inputs.end.new_nullifiers.get(0); - let mut siloed_note_hashes = public_inputs.end.new_note_hashes.storage; - - for c_idx in 0..MAX_NEW_NOTE_HASHES_PER_TX { - // Apply nonce to all non-zero/non-empty note hashes - // Nonce is the hash of the first (0th) nullifier and the note hash's index into new_note_hashes array - let nonce = compute_note_hash_nonce(first_nullifier.value, c_idx); - let hash = siloed_note_hashes[c_idx]; - if hash.value != 0 { - let unique_note_hash = compute_unique_siloed_note_hash(nonce, hash.value); - siloed_note_hashes[c_idx] = SideEffect{ - value: unique_note_hash, - counter: hash.counter - }; - } - } - - public_inputs.end.new_note_hashes.storage = siloed_note_hashes; - } - - pub fn native_private_kernel_circuit_tail(self) -> PrivateKernelTailCircuitPublicInputs { - let mut public_inputs : PrivateKernelCircuitPublicInputsBuilder = unsafe::zeroed(); - public_inputs.is_private = true; - - self.validate_inputs(); - - common::validate_previous_kernel_values(self.previous_kernel.public_inputs.end); - - // Do this before any functions can modify the inputs. - common::initialize_end_values(self.previous_kernel, &mut public_inputs); - - self.validate_nullifier_read_requests(&mut public_inputs); - - self.validate_nullifier_keys(&mut public_inputs); - - self.sort_arrays(&mut public_inputs); - - self.match_reads_to_commitments(&mut public_inputs); - - self.match_nullifiers_to_note_hashes_and_squash(&mut public_inputs); - - PrivateKernelTailCircuitPrivateInputs::apply_note_hash_nonces(&mut public_inputs); - - public_inputs.to_tail() + composer.compose().finish() } } mod tests { - use dep::std::{cmp::Eq, unsafe}; - use crate::{private_kernel_tail::PrivateKernelTailCircuitPrivateInputs}; + use dep::std::unsafe; + use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; use dep::reset_kernel_lib::{ tests::nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus} }; use dep::types::constants::{ MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NULLIFIER_READ_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX + MAX_NULLIFIER_READ_REQUESTS_PER_TX }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, - max_block_number::MaxBlockNumber, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} + kernel_circuit_public_inputs::KernelCircuitPublicInputs, max_block_number::MaxBlockNumber, + side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} }, - hash::compute_unique_siloed_note_hashes, tests::kernel_data_builder::PreviousKernelDataBuilder, + hash::compute_unique_siloed_note_hashes, + tests::{fixture_builder::FixtureBuilder, sort::sort_get_sorted_hints}, utils::{arrays::{array_eq, array_length}}, traits::{Empty, is_empty, is_empty_array} }; struct PrivateKernelTailInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, read_commitment_hints: [u64; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], nullifier_commitment_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder, @@ -281,48 +85,33 @@ mod tests { impl PrivateKernelTailInputsBuilder { pub fn new() -> Self { + let mut previous_kernel = FixtureBuilder::new(); + previous_kernel.append_new_nullifiers(1); + PrivateKernelTailInputsBuilder { - previous_kernel: PreviousKernelDataBuilder::new(false), + previous_kernel, read_commitment_hints: [0; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder::new(MAX_NULLIFIER_READ_REQUESTS_PER_TX) } } - pub fn get_new_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.previous_kernel.end.new_note_hashes.storage - } - - pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { - self.previous_kernel.end.new_nullifiers.storage - } - - pub fn get_unique_siloed_note_hashes(self) -> [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX] { - self.compute_unique_siloed_note_hashes(self.previous_kernel.end.new_note_hashes.storage) - } - // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed - // commitments for the given commitments. - pub fn compute_unique_siloed_note_hashes(self, commitments: [SideEffect; N]) -> [SideEffect; N] { - let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); - compute_unique_siloed_note_hashes(first_nullifier.value, commitments) + // note_hashes for the given note_hashes. + pub fn compute_unique_siloed_note_hashes( + self, + note_hashes: [SideEffect; N] + ) -> [SideEffect; N] { + let first_nullifier = self.previous_kernel.new_nullifiers.get_unchecked(0); + compute_unique_siloed_note_hashes(first_nullifier.value, note_hashes) } - pub fn append_transient_commitments(&mut self, num_commitments: u64) { - // All new note hashes aggregated in the previous kernel are transient commitments. - self.previous_kernel.append_new_note_hashes(num_commitments); + pub fn add_pending_note_hash_read_request(&mut self, note_hash_index: u64) { + let read_request_index = self.previous_kernel.add_read_request_for_pending_note_hash(note_hash_index); + self.read_commitment_hints[read_request_index] = note_hash_index; } - pub fn add_transient_read(&mut self, commitment_index: u64) { - let read_request_index = self.previous_kernel.add_read_request_for_transient_commitment(commitment_index); - self.read_commitment_hints[read_request_index] = commitment_index; - } - - pub fn append_nullifiers(&mut self, num_nullifiers: u64) { - self.previous_kernel.append_new_nullifiers_from_private(num_nullifiers); - } - - pub fn add_nullifier_pending_read(&mut self, nullifier_index_offset_one: u64) { + pub fn add_pending_nullifier_read_request(&mut self, nullifier_index_offset_one: u64) { let nullifier_index = nullifier_index_offset_one + 1; // + 1 is for the first nullifier let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); @@ -331,52 +120,38 @@ mod tests { self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } - pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: u64) { - self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_note_hashes.get(commitment_index).value; - self.nullifier_commitment_hints[nullifier_index] = commitment_index; + pub fn nullify_pending_note_hash(&mut self, nullifier_index: u64, note_hash_index: u64) { + self.previous_kernel.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.new_note_hashes.get(note_hash_index).value; + self.nullifier_commitment_hints[nullifier_index] = note_hash_index; } - fn sort_sideffects(original: [T; N]) -> ([T; N], [u64; N]) where T: Ordered + Eq + Empty { - let mut indexes = [0; N]; - for i in 0..N { - indexes[i] = i; - } - let sorted_indexes = indexes.sort_via( - |a_index: u64, b_index: u64| { - let a = original[a_index]; - let b = original[b_index]; - if is_empty(b) { - true - } else if is_empty(a) { - false - } else { - a.counter() < b.counter() - } - } + pub fn execute(&mut self) -> KernelCircuitPublicInputs { + let sorted = sort_get_sorted_hints( + self.previous_kernel.new_note_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter ); - let sorted_sideffects = sorted_indexes.map(|i: u64| original[i]); - let mut reverse_map = [0; N]; - for i in 0..N { - reverse_map[sorted_indexes[i]] = i; - } - - (sorted_sideffects, reverse_map) - } + let sorted_new_note_hashes = sorted.sorted_array; + let sorted_new_note_hashes_indexes = sorted.sorted_index_hints; - pub fn execute(&mut self) -> PrivateKernelTailCircuitPublicInputs { - let (sorted_new_note_hashes, sorted_new_note_hashes_indexes) = PrivateKernelTailInputsBuilder::sort_sideffects(self.get_new_note_hashes()); let mut sorted_read_commitment_hints = [0; MAX_NOTE_HASH_READ_REQUESTS_PER_TX]; for i in 0..sorted_read_commitment_hints.len() { sorted_read_commitment_hints[i] = sorted_new_note_hashes_indexes[self.read_commitment_hints[i]]; } - let (sorted_new_nullifiers, sorted_new_nullifiers_indexes) = PrivateKernelTailInputsBuilder::sort_sideffects(self.get_new_nullifiers()); + + let sorted = sort_get_sorted_hints( + self.previous_kernel.new_nullifiers.storage, + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.counter < b.counter + ); + let sorted_new_nullifiers = sorted.sorted_array; + let sorted_new_nullifiers_indexes = sorted.sorted_index_hints; + let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; for i in 0..sorted_nullifier_commitment_hints.len() { sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]]; } let kernel = PrivateKernelTailCircuitPrivateInputs { - previous_kernel: self.previous_kernel.to_private_kernel_inner_data(), + previous_kernel: self.previous_kernel.to_private_kernel_data(), sorted_new_note_hashes, sorted_new_note_hashes_indexes, read_commitment_hints: sorted_read_commitment_hints, @@ -398,64 +173,35 @@ mod tests { } } - #[test] - unconstrained fn splits_tx_nullifier_to_non_revertible() { - let mut builder = PrivateKernelTailInputsBuilder::new(); - let public_inputs = builder.execute(); - assert(array_length(public_inputs.end_non_revertible.new_nullifiers) == 1); - assert(array_length(public_inputs.end.new_nullifiers) == 0); - } - #[test] unconstrained fn native_matching_one_read_request_to_commitment_works() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(1); - builder.add_transient_read(0); + builder.previous_kernel.append_new_note_hashes(1); + builder.add_pending_note_hash_read_request(0); - let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes(builder.previous_kernel.new_note_hashes.storage); let public_inputs = builder.execute(); assert(array_length(public_inputs.end.new_note_hashes) == 1); assert(public_inputs.end.new_note_hashes[0].eq(unique_siloed_note_hashes[0])); } - #[test] - unconstrained fn native_matching_some_read_requests_to_commitments_works() { - let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(MAX_NEW_NOTE_HASHES_PER_TX); - // prepare for the split: first MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX are added to end_non_revertible_accumulted_data - // neeed to take the counter of the side effect at the given index because - builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.end.new_note_hashes.get(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX).counter; - // Read the hash at index 1; - builder.add_transient_read(1); - // Read the hash at index 3; - builder.add_transient_read(3); - let unique_siloed_note_hashes = builder.get_unique_siloed_note_hashes(); - let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_note_hashes), MAX_REVERTIBLE_NOTE_HASHES_PER_TX); - for i in 0..MAX_REVERTIBLE_NOTE_HASHES_PER_TX { - assert( - public_inputs.end.new_note_hashes[i].eq(unique_siloed_note_hashes[MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX + i]) - ); - } - } - - #[test(should_fail_with="Hinted hash does not match read request")] + #[test(should_fail_with="Hinted note hash does not match read request")] unconstrained fn native_read_request_unknown_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(1); - builder.add_transient_read(0); + builder.previous_kernel.append_new_note_hashes(1); + builder.add_pending_note_hash_read_request(0); // Tweak the read request so that it does not match the hash at index 0; - let read_request = builder.previous_kernel.validation_requests.note_hash_read_requests.pop(); - builder.previous_kernel.validation_requests.note_hash_read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); + let read_request = builder.previous_kernel.note_hash_read_requests.pop(); + builder.previous_kernel.note_hash_read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); builder.failed(); } #[test] fn propagate_previous_kernel_max_block_number() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13); + builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); let public_inputs = builder.execute(); assert_eq(public_inputs.rollup_validation_requests.max_block_number.unwrap(), 13); @@ -465,8 +211,8 @@ mod tests { unconstrained fn one_pending_nullifier_read_request() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); builder.succeeded(); } @@ -475,9 +221,9 @@ mod tests { unconstrained fn two_pending_nullifier_read_requests() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); - builder.add_nullifier_pending_read(0); + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + builder.add_pending_nullifier_read_request(0); builder.succeeded(); } @@ -486,8 +232,8 @@ mod tests { unconstrained fn pending_nullifier_read_request_wrong_hint_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); let mut hint = builder.nullifier_read_request_hints_builder.pending_read_hints.pop(); assert(hint.pending_value_index == 2); hint.pending_value_index = 1; @@ -500,12 +246,12 @@ mod tests { unconstrained fn pending_nullifier_read_request_reads_before_value_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); - let nullifier_being_read = builder.get_new_nullifiers()[2]; - let mut read_request = builder.previous_kernel.validation_requests.nullifier_read_requests.pop(); + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + let nullifier_being_read = builder.previous_kernel.new_nullifiers.storage[2]; + let mut read_request = builder.previous_kernel.nullifier_read_requests.pop(); read_request.counter = nullifier_being_read.counter - 1; - builder.previous_kernel.validation_requests.nullifier_read_requests.push(read_request); + builder.previous_kernel.nullifier_read_requests.push(read_request); builder.failed(); } @@ -513,21 +259,19 @@ mod tests { #[test] unconstrained fn native_squash_one_of_one_transient_matches_works() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(1); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_note_hashes(1); + builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 0; - builder.nullify_transient_commitment(1, 0); - let new_nullifiers = builder.get_new_nullifiers(); + builder.nullify_pending_note_hash(1, 0); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; let public_inputs = builder.execute(); assert(is_empty_array(public_inputs.end.new_note_hashes)); // The nullifier at index 1 is chopped. - assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[2]])); - // tx nullifier is part of non revertible accumulated data assert( array_eq( - public_inputs.end_non_revertible.new_nullifiers, - [new_nullifiers[0]] + public_inputs.end.new_nullifiers, + [new_nullifiers[0], new_nullifiers[2]] ) ); } @@ -535,14 +279,14 @@ mod tests { #[test] unconstrained fn native_squash_one_of_two_transient_matches_works() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(2); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 0; - builder.nullify_transient_commitment(1, 0); - let new_note_hashes = builder.get_new_note_hashes(); + builder.nullify_pending_note_hash(1, 0); + let new_note_hashes = builder.previous_kernel.new_note_hashes.storage; // The 0th hash will be chopped. let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes([new_note_hashes[1]]); - let new_nullifiers = builder.get_new_nullifiers(); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; let public_inputs = builder.execute(); assert( array_eq( @@ -551,12 +295,10 @@ mod tests { ) ); // The nullifier at index 1 is chopped. - assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[2]])); - // tx nullifier is part of non revertible accumulated data assert( array_eq( - public_inputs.end_non_revertible.new_nullifiers, - [new_nullifiers[0]] + public_inputs.end.new_nullifiers, + [new_nullifiers[0], new_nullifiers[2]] ) ); } @@ -564,68 +306,63 @@ mod tests { #[test] unconstrained fn native_squash_two_of_two_transient_matches_works() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(2); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 1; - builder.nullify_transient_commitment(1, 1); + builder.nullify_pending_note_hash(1, 1); // The nullifier at index 2 is nullifying the hash at index 0; - builder.nullify_transient_commitment(2, 0); - let new_nullifiers = builder.get_new_nullifiers(); + builder.nullify_pending_note_hash(2, 0); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; let public_inputs = builder.execute(); - // app logic will be completely empty after squashing + // Only the first nullifier is left after squashing. assert(is_empty_array(public_inputs.end.new_note_hashes)); - assert(is_empty_array(public_inputs.end.new_nullifiers)); - - // and the 0th nullifier will be moved to the non-revertible array - assert( - array_eq( - public_inputs.end_non_revertible.new_nullifiers, - [new_nullifiers[0]] - ) - ); + assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[0]])); } #[test] unconstrained fn ordering_of_commitments_and_nullifiers() { let mut builder = PrivateKernelTailInputsBuilder::new(); - let mut sorted_new_note_hashes = [SideEffect::empty(); 10]; - let mut sorted_new_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; + builder.previous_kernel.append_new_note_hashes(10); + builder.previous_kernel.append_new_nullifiers(10); - for i in 0..10 { - sorted_new_note_hashes[i] = SideEffect { value: (i + 1) as Field, counter: builder.previous_kernel.next_sideffect_counter() }; - sorted_new_nullifiers[i] = SideEffectLinkedToNoteHash { value: (i + 11) as Field, counter: builder.previous_kernel.next_sideffect_counter(), note_hash: 0 }; - } + let sorted_note_hashes = builder.previous_kernel.new_note_hashes.storage; + let sorted_nullifiers = builder.previous_kernel.new_nullifiers.storage; + + let mut reversed_note_hashes = [SideEffect::empty(); 10]; + let mut reversed_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; for i in 0..10 { - builder.previous_kernel.end.new_note_hashes.push(sorted_new_note_hashes[9 - i]); - builder.previous_kernel.end.new_nullifiers.push(sorted_new_nullifiers[9 - i]); + reversed_note_hashes[9 - i] = builder.previous_kernel.new_note_hashes.pop(); + reversed_nullifiers[9 - i] = builder.previous_kernel.new_nullifiers.pop(); } - let public_inputs = builder.execute(); + builder.previous_kernel.new_note_hashes.extend_from_array(reversed_note_hashes); + builder.previous_kernel.new_nullifiers.extend_from_array(reversed_nullifiers); let sorted_unique_note_hashes = compute_unique_siloed_note_hashes( // tx nullifier is part of non revertible accumulated data - public_inputs.end_non_revertible.new_nullifiers[0].value, - sorted_new_note_hashes + builder.previous_kernel.new_nullifiers.get_unchecked(0).value, + sorted_note_hashes ); + let public_inputs = builder.execute(); + for i in 0..10 { assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashes[i])); - assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); + assert(public_inputs.end.new_nullifiers[i].eq(sorted_nullifiers[i])); } } #[test] unconstrained fn native_empty_nullified_commitment_means_persistent_nullifier_0() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(2); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); let public_inputs = builder.execute(); assert_eq(array_length(public_inputs.end.new_note_hashes), 2); - assert_eq(array_length(public_inputs.end.new_nullifiers), 2); - assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); + assert_eq(array_length(public_inputs.end.new_nullifiers), 3); } // same as previous test, but this time there are 0 commitments! // (Do we really need this test?) @@ -633,20 +370,19 @@ mod tests { #[test] unconstrained fn native_empty_nullified_commitment_means_persistent_nullifier_1() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_nullifiers(2); let public_inputs = builder.execute(); assert(array_length(public_inputs.end.new_note_hashes) == 0); - assert(array_length(public_inputs.end.new_nullifiers) == 2); - assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); + assert(array_length(public_inputs.end.new_nullifiers) == 3); } #[test(should_fail)] unconstrained fn invalid_nullifier_commitment_hint_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(1); - builder.append_nullifiers(1); + builder.previous_kernel.append_new_note_hashes(1); + builder.previous_kernel.append_new_nullifiers(1); // The nullifier at index 1 is nullifying the hash at index 0; - builder.nullify_transient_commitment(1, 0); + builder.nullify_pending_note_hash(1, 0); // Change the hint to be out of bounds. builder.nullifier_commitment_hints[1] = MAX_NEW_NOTE_HASHES_PER_TX; builder.failed(); @@ -655,12 +391,12 @@ mod tests { #[test(should_fail_with="Hinted hash does not match")] unconstrained fn wrong_nullifier_commitment_hint_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.append_transient_commitments(2); - builder.append_nullifiers(2); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); // The nullifier at index 1 is nullifying the hash at index 1; - builder.nullify_transient_commitment(1, 1); + builder.nullify_pending_note_hash(1, 1); // The nullifier at index 2 is nullifying the hash at index 0; - builder.nullify_transient_commitment(2, 0); + builder.nullify_pending_note_hash(2, 0); // Tweak the hint to be for the hash at index 1. builder.nullifier_commitment_hints[2] = 1; builder.failed(); @@ -673,93 +409,17 @@ mod tests { builder.failed(); } - #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] - unconstrained fn zero_0th_nullifier_fails() { + #[test(should_fail_with="Public call stack must be empty when executing the tail circuit")] + unconstrained fn non_empty_public_call_stack_should_fail() { let mut builder = PrivateKernelTailInputsBuilder::new(); - builder.previous_kernel.end.new_nullifiers = BoundedVec::new(); + builder.previous_kernel.push_public_call_request(1, false); builder.failed(); } - #[test] - unconstrained fn split_nullifiers_into_non_revertible() { - let mut builder = PrivateKernelTailInputsBuilder::new(); - // expect 3 non-revertible nullifiers: the tx nullifier + 2 new ones - builder.previous_kernel.append_new_nullifiers_from_private(2); - builder.previous_kernel.capture_min_revertible_side_effect_counter(); - - // expect 2 revertible nullifiers - builder.previous_kernel.append_new_nullifiers_from_private(2); - - let new_nullifiers = builder.previous_kernel.end.new_nullifiers.storage; - let public_inputs = builder.execute(); - - assert( - array_eq( - public_inputs.end_non_revertible.new_nullifiers, - [new_nullifiers[0], new_nullifiers[1], new_nullifiers[2]] - ) - ); - - assert( - array_eq( - public_inputs.end.new_nullifiers, - [new_nullifiers[3], new_nullifiers[4]] - ) - ); - } - - #[test] - unconstrained fn split_commitments_into_non_revertible() { - let mut builder = PrivateKernelTailInputsBuilder::new(); - - // expect 2 non-revertible commitments - builder.previous_kernel.append_new_note_hashes(2); - builder.previous_kernel.capture_min_revertible_side_effect_counter(); - - // expect 2 revertible commitments - builder.previous_kernel.append_new_note_hashes(2); - - let new_note_hashes = builder.previous_kernel.end.new_note_hashes.storage; - let public_inputs = builder.execute(); - - let siloed_note_hashes = compute_unique_siloed_note_hashes( - // tx nullifier is part of non revertible accumulated data - public_inputs.end_non_revertible.new_nullifiers[0].value, - new_note_hashes - ); - - assert( - array_eq( - public_inputs.end_non_revertible.new_note_hashes, - [siloed_note_hashes[0], siloed_note_hashes[1]] - ) - ); - - assert( - array_eq( - public_inputs.end.new_note_hashes, - [siloed_note_hashes[2], siloed_note_hashes[3]] - ) - ); - } - - #[test] - unconstrained fn split_side_effect_squashing() { + #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] + unconstrained fn zero_0th_nullifier_fails() { let mut builder = PrivateKernelTailInputsBuilder::new(); - - // add one hash in non-revertible part - builder.previous_kernel.append_new_note_hashes(1); - builder.previous_kernel.capture_min_revertible_side_effect_counter(); - - // nullify it in revertible part - builder.previous_kernel.append_new_nullifiers_from_private(1); - builder.nullify_transient_commitment(1, 0); - - let public_inputs = builder.execute(); - - assert(!is_empty_array(public_inputs.end_non_revertible.new_nullifiers)); - assert(is_empty_array(public_inputs.end_non_revertible.new_note_hashes)); - assert(is_empty_array(public_inputs.end.new_note_hashes)); - assert(is_empty_array(public_inputs.end.new_nullifiers)); + builder.previous_kernel.new_nullifiers = BoundedVec::new(); + builder.failed(); } } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr new file mode 100644 index 00000000000..7d0635d44c4 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-lib/src/private_kernel_tail_to_public.nr @@ -0,0 +1,513 @@ +use crate::kernel_circuit_public_inputs_composer::KernelCircuitPublicInputsComposer; +use dep::reset_kernel_lib::{NullifierReadRequestHints, PrivateValidationRequestProcessor}; +use dep::types::{ + abis::{ + kernel_data::PrivateKernelData, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX +}, + grumpkin_private_key::GrumpkinPrivateKey, utils::arrays::array_length +}; + +struct PrivateKernelTailToPublicCircuitPrivateInputs { + previous_kernel: PrivateKernelData, + sorted_new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + sorted_new_note_hashes_indexes: [u64; MAX_NEW_NOTE_HASHES_PER_TX], + read_commitment_hints: [u64; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], + sorted_new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + sorted_new_nullifiers_indexes: [u64; MAX_NEW_NULLIFIERS_PER_TX], + nullifier_read_request_hints: NullifierReadRequestHints, + nullifier_commitment_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + master_nullifier_secret_keys: [GrumpkinPrivateKey; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], +} + +impl PrivateKernelTailToPublicCircuitPrivateInputs { + pub fn execute(self) -> PublicKernelCircuitPublicInputs { + let previous_public_inputs = self.previous_kernel.public_inputs; + assert( + array_length(previous_public_inputs.end.public_call_stack) != 0, "Public call stack must not be empty when exporting public kernel data from the tail circuit" + ); + + let nullifier_tree_root = previous_public_inputs.constants.historical_header.state.partial.nullifier_tree.root; + let request_processor = PrivateValidationRequestProcessor { + validation_requests: previous_public_inputs.validation_requests, + note_hash_read_request_hints: self.read_commitment_hints, + pending_note_hashes: previous_public_inputs.end.new_note_hashes, + nullifier_read_request_hints: self.nullifier_read_request_hints, + pending_nullifiers: previous_public_inputs.end.new_nullifiers, + master_nullifier_secret_keys: self.master_nullifier_secret_keys, + nullifier_tree_root + }; + request_processor.validate(); + + let mut composer = KernelCircuitPublicInputsComposer::new( + self.previous_kernel, + self.sorted_new_note_hashes, + self.sorted_new_note_hashes_indexes, + self.sorted_new_nullifiers, + self.sorted_new_nullifiers_indexes, + self.nullifier_commitment_hints + ); + composer.compose_public().finish_to_public() + } +} + +mod tests { + use dep::std::unsafe; + use crate::private_kernel_tail_to_public::PrivateKernelTailToPublicCircuitPrivateInputs; + use dep::reset_kernel_lib::{ + tests::nullifier_read_request_hints_builder::NullifierReadRequestHintsBuilder, + read_request_reset::{PendingReadHint, ReadRequestState, ReadRequestStatus} + }; + use dep::types::constants::{ + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NULLIFIER_READ_REQUESTS_PER_TX + }; + use dep::types::{ + abis::{ + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} + }, + hash::compute_unique_siloed_note_hashes, + tests::{fixture_builder::FixtureBuilder, sort::sort_get_sorted_hints}, + utils::{arrays::{array_eq, array_length}}, traits::is_empty_array + }; + + struct PrivateKernelTailToPublicInputsBuilder { + previous_kernel: FixtureBuilder, + read_commitment_hints: [u64; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], + nullifier_commitment_hints: [u64; MAX_NEW_NULLIFIERS_PER_TX], + nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder, + } + + impl PrivateKernelTailToPublicInputsBuilder { + pub fn new() -> Self { + let mut previous_kernel = FixtureBuilder::new(); + previous_kernel.append_new_nullifiers(1); + previous_kernel.push_public_call_request(1, false); + + PrivateKernelTailToPublicInputsBuilder { + previous_kernel, + read_commitment_hints: [0; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], + nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], + nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder::new(MAX_NULLIFIER_READ_REQUESTS_PER_TX) + } + } + + // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed + // note_hashes for the given note_hashes. + pub fn compute_unique_siloed_note_hashes( + self, + note_hashes: [SideEffect; N] + ) -> [SideEffect; N] { + let first_nullifier = self.previous_kernel.new_nullifiers.get_unchecked(0); + compute_unique_siloed_note_hashes(first_nullifier.value, note_hashes) + } + + pub fn add_pending_note_hash_read_request(&mut self, note_hash_index: u64) { + let read_request_index = self.previous_kernel.add_read_request_for_pending_note_hash(note_hash_index); + self.read_commitment_hints[read_request_index] = note_hash_index; + } + + pub fn add_pending_nullifier_read_request(&mut self, nullifier_index_offset_one: u64) { + let nullifier_index = nullifier_index_offset_one + 1; // + 1 is for the first nullifier + let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); + let hint = PendingReadHint { read_request_index, pending_value_index: nullifier_index }; + self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); + self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; + } + + pub fn nullify_transient_note_hash(&mut self, nullifier_index: Field, note_hash_index: u64) { + self.previous_kernel.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.new_note_hashes.get(note_hash_index).value; + self.nullifier_commitment_hints[nullifier_index] = note_hash_index; + } + + pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { + let sorted = sort_get_sorted_hints( + self.previous_kernel.new_note_hashes.storage, + |a: SideEffect, b: SideEffect| a.counter < b.counter + ); + let sorted_new_note_hashes = sorted.sorted_array; + let sorted_new_note_hashes_indexes = sorted.sorted_index_hints; + + let mut sorted_read_commitment_hints = [0; MAX_NOTE_HASH_READ_REQUESTS_PER_TX]; + for i in 0..sorted_read_commitment_hints.len() { + sorted_read_commitment_hints[i] = sorted_new_note_hashes_indexes[self.read_commitment_hints[i]]; + } + + let sorted = sort_get_sorted_hints( + self.previous_kernel.new_nullifiers.storage, + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.counter < b.counter + ); + let sorted_new_nullifiers = sorted.sorted_array; + let sorted_new_nullifiers_indexes = sorted.sorted_index_hints; + + let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; + for i in 0..sorted_nullifier_commitment_hints.len() { + sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]]; + } + + let kernel = PrivateKernelTailToPublicCircuitPrivateInputs { + previous_kernel: self.previous_kernel.to_private_kernel_data(), + sorted_new_note_hashes, + sorted_new_note_hashes_indexes, + read_commitment_hints: sorted_read_commitment_hints, + sorted_new_nullifiers, + sorted_new_nullifiers_indexes, + nullifier_read_request_hints: self.nullifier_read_request_hints_builder.to_hints(), + nullifier_commitment_hints: sorted_nullifier_commitment_hints, + master_nullifier_secret_keys: unsafe::zeroed() + }; + kernel.execute() + } + + pub fn failed(&mut self) { + let _ = self.execute(); + } + + pub fn succeeded(&mut self) { + let _ = self.execute(); + } + } + + #[test] + unconstrained fn native_matching_one_read_request_to_commitment_works() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(1); + builder.add_pending_note_hash_read_request(0); + + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes(builder.previous_kernel.new_note_hashes.storage); + + let public_inputs = builder.execute(); + assert( + array_eq( + public_inputs.end.new_note_hashes, + [unique_siloed_note_hashes[0]] + ) + ); + } + + #[test] + unconstrained fn native_matching_some_read_requests_to_commitments_works() { + let num_non_revertible = 3; + let num_revertible = 2; + + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(num_non_revertible + num_revertible); + // prepare for the split: first MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX are added to end_non_revertible_accumulted_data + // neeed to take the counter of the side effect at the given index because + builder.previous_kernel.min_revertible_side_effect_counter = builder.previous_kernel.new_note_hashes.get(num_non_revertible).counter; + // Read the hash at index 1; + builder.add_pending_note_hash_read_request(1); + // Read the hash at index 3; + builder.add_pending_note_hash_read_request(3); + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes(builder.previous_kernel.new_note_hashes.storage); + let public_inputs = builder.execute(); + assert( + array_eq( + public_inputs.end_non_revertible.new_note_hashes, + [unique_siloed_note_hashes[0], unique_siloed_note_hashes[1], unique_siloed_note_hashes[2]] + ) + ); + assert( + array_eq( + public_inputs.end.new_note_hashes, + [unique_siloed_note_hashes[3], unique_siloed_note_hashes[4]] + ) + ); + } + + #[test(should_fail_with="Hinted note hash does not match read request")] + unconstrained fn native_read_request_unknown_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(1); + builder.add_pending_note_hash_read_request(0); + // Tweak the read request so that it does not match the hash at index 0; + let read_request = builder.previous_kernel.note_hash_read_requests.pop(); + builder.previous_kernel.note_hash_read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); + builder.failed(); + } + + #[test] + unconstrained fn one_pending_nullifier_read_request() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + + builder.succeeded(); + } + + #[test] + unconstrained fn two_pending_nullifier_read_requests() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + builder.add_pending_nullifier_read_request(0); + + builder.succeeded(); + } + + #[test(should_fail_with="Hinted value does not match read request")] + unconstrained fn pending_nullifier_read_request_wrong_hint_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + let mut hint = builder.nullifier_read_request_hints_builder.pending_read_hints.pop(); + assert(hint.pending_value_index == 2); + hint.pending_value_index = 1; + builder.nullifier_read_request_hints_builder.pending_read_hints.push(hint); + + builder.failed(); + } + + #[test(should_fail_with="Read request counter must be greater than counter of the value being read")] + unconstrained fn pending_nullifier_read_request_reads_before_value_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_nullifiers(3); + builder.add_pending_nullifier_read_request(1); + let nullifier_being_read = builder.previous_kernel.new_nullifiers.storage[2]; + let mut read_request = builder.previous_kernel.nullifier_read_requests.pop(); + read_request.counter = nullifier_being_read.counter - 1; + builder.previous_kernel.nullifier_read_requests.push(read_request); + + builder.failed(); + } + + #[test] + unconstrained fn native_squash_one_of_one_transient_matches_works() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(1); + builder.previous_kernel.append_new_nullifiers(2); + // The nullifier at index 1 is nullifying the hash at index 0; + builder.nullify_transient_note_hash(1, 0); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; + let public_inputs = builder.execute(); + assert(is_empty_array(public_inputs.end.new_note_hashes)); + + // The nullifier at index 1 is chopped. + assert( + array_eq( + public_inputs.end.new_nullifiers, + [new_nullifiers[0], new_nullifiers[2]] + ) + ); + } + + #[test] + unconstrained fn native_squash_one_of_two_transient_matches_works() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); + // The nullifier at index 1 is nullifying the hash at index 0; + builder.nullify_transient_note_hash(1, 0); + let new_note_hashes = builder.previous_kernel.new_note_hashes.storage; + // The 0th hash will be chopped. + let unique_siloed_note_hashes = builder.compute_unique_siloed_note_hashes([new_note_hashes[1]]); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; + let public_inputs = builder.execute(); + assert( + array_eq( + public_inputs.end.new_note_hashes, + [unique_siloed_note_hashes[0]] + ) + ); + // The nullifier at index 1 is chopped. + assert( + array_eq( + public_inputs.end.new_nullifiers, + [new_nullifiers[0], new_nullifiers[2]] + ) + ); + } + + #[test] + unconstrained fn native_squash_two_of_two_transient_matches_works() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); + // The nullifier at index 1 is nullifying the hash at index 1; + builder.nullify_transient_note_hash(1, 1); + // The nullifier at index 2 is nullifying the hash at index 0; + builder.nullify_transient_note_hash(2, 0); + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; + let public_inputs = builder.execute(); + + // Only the first nullifier is left after squashing. + assert(is_empty_array(public_inputs.end.new_note_hashes)); + assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[0]])); + } + + #[test] + unconstrained fn ordering_of_note_hashes_and_nullifiers() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + builder.previous_kernel.append_new_note_hashes(10); + builder.previous_kernel.append_new_nullifiers(10); + + let sorted_note_hashes = builder.previous_kernel.new_note_hashes.storage; + let sorted_nullifiers = builder.previous_kernel.new_nullifiers.storage; + + let mut reversed_note_hashes = [SideEffect::empty(); 10]; + let mut reversed_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; + + for i in 0..10 { + reversed_note_hashes[9 - i] = builder.previous_kernel.new_note_hashes.pop(); + reversed_nullifiers[9 - i] = builder.previous_kernel.new_nullifiers.pop(); + } + + builder.previous_kernel.new_note_hashes.extend_from_array(reversed_note_hashes); + builder.previous_kernel.new_nullifiers.extend_from_array(reversed_nullifiers); + + let sorted_unique_note_hashes = compute_unique_siloed_note_hashes( + // tx nullifier is part of non revertible accumulated data + builder.previous_kernel.new_nullifiers.get_unchecked(0).value, + sorted_note_hashes + ); + + let public_inputs = builder.execute(); + + for i in 0..10 { + assert(public_inputs.end.new_note_hashes[i].eq(sorted_unique_note_hashes[i])); + assert(public_inputs.end.new_nullifiers[i].eq(sorted_nullifiers[i])); + } + } + + #[test(should_fail)] + unconstrained fn invalid_nullifier_commitment_hint_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(1); + builder.previous_kernel.append_new_nullifiers(1); + // The nullifier at index 1 is nullifying the hash at index 0; + builder.nullify_transient_note_hash(1, 0); + // Change the hint to be out of bounds. + builder.nullifier_commitment_hints[1] = MAX_NEW_NOTE_HASHES_PER_TX; + builder.failed(); + } + + #[test(should_fail_with="Hinted hash does not match")] + unconstrained fn wrong_nullifier_commitment_hint_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.append_new_nullifiers(2); + // The nullifier at index 1 is nullifying the hash at index 1; + builder.nullify_transient_note_hash(1, 1); + // The nullifier at index 2 is nullifying the hash at index 0; + builder.nullify_transient_note_hash(2, 0); + // Tweak the hint to be for the hash at index 1. + builder.nullifier_commitment_hints[2] = 1; + builder.failed(); + } + + #[test(should_fail_with="Private call stack must be empty when executing the tail circuit")] + unconstrained fn non_empty_private_call_stack_should_fail() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.push_private_call_request(1, false); + builder.failed(); + } + + #[test(should_fail_with="Public call stack must not be empty when exporting public kernel data from the tail circuit")] + unconstrained fn empty_public_call_stack_should_fail() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.public_call_stack = BoundedVec::new(); + builder.failed(); + } + + #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] + unconstrained fn zero_0th_nullifier_fails() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + builder.previous_kernel.new_nullifiers = BoundedVec::new(); + builder.failed(); + } + + #[test] + unconstrained fn split_nullifiers_into_non_revertible() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + // expect 3 non-revertible nullifiers: the tx nullifier + 2 new ones + builder.previous_kernel.append_new_nullifiers(2); + builder.previous_kernel.capture_min_revertible_side_effect_counter(); + + // expect 2 revertible nullifiers + builder.previous_kernel.append_new_nullifiers(2); + + let new_nullifiers = builder.previous_kernel.new_nullifiers.storage; + let public_inputs = builder.execute(); + + assert( + array_eq( + public_inputs.end_non_revertible.new_nullifiers, + [new_nullifiers[0], new_nullifiers[1], new_nullifiers[2]] + ) + ); + + assert( + array_eq( + public_inputs.end.new_nullifiers, + [new_nullifiers[3], new_nullifiers[4]] + ) + ); + } + + #[test] + unconstrained fn split_commitments_into_non_revertible() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + // expect 2 non-revertible commitments + builder.previous_kernel.append_new_note_hashes(2); + builder.previous_kernel.capture_min_revertible_side_effect_counter(); + + // expect 2 revertible commitments + builder.previous_kernel.append_new_note_hashes(2); + + let new_note_hashes = builder.previous_kernel.new_note_hashes.storage; + let public_inputs = builder.execute(); + + let siloed_note_hashes = compute_unique_siloed_note_hashes( + // tx nullifier is part of non revertible accumulated data + public_inputs.end_non_revertible.new_nullifiers[0].value, + new_note_hashes + ); + + assert( + array_eq( + public_inputs.end_non_revertible.new_note_hashes, + [siloed_note_hashes[0], siloed_note_hashes[1]] + ) + ); + + assert( + array_eq( + public_inputs.end.new_note_hashes, + [siloed_note_hashes[2], siloed_note_hashes[3]] + ) + ); + } + + #[test] + unconstrained fn split_side_effect_squashing() { + let mut builder = PrivateKernelTailToPublicInputsBuilder::new(); + + // add one hash in non-revertible part + builder.previous_kernel.append_new_note_hashes(1); + builder.previous_kernel.capture_min_revertible_side_effect_counter(); + + // nullify it in revertible part + builder.previous_kernel.append_new_nullifiers(1); + builder.nullify_transient_note_hash(1, 0); + + let public_inputs = builder.execute(); + + assert(!is_empty_array(public_inputs.end_non_revertible.new_nullifiers)); + assert(is_empty_array(public_inputs.end_non_revertible.new_note_hashes)); + assert(is_empty_array(public_inputs.end.new_note_hashes)); + assert(is_empty_array(public_inputs.end.new_nullifiers)); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr index 2579872ed9e..3e8cb913733 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailCircuitPrivateInputs; -use dep::types::PrivateKernelTailCircuitPublicInputs; +use dep::types::KernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub PrivateKernelTailCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { input.native_private_kernel_circuit_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/Nargo.toml new file mode 100644 index 00000000000..b61a23eca7b --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "private_kernel_tail_to_public_simulated" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +private_kernel_lib = { path = "../private-kernel-lib" } +types = { path = "../types" } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr new file mode 100644 index 00000000000..d3acd17bfed --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr @@ -0,0 +1,6 @@ +use dep::private_kernel_lib::PrivateKernelTailToPublicCircuitPrivateInputs; +use dep::types::PublicKernelCircuitPublicInputs; + +unconstrained fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { + input.execute() +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Nargo.toml b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Nargo.toml new file mode 100644 index 00000000000..3e534aed52b --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "private_kernel_tail_to_public" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +private_kernel_lib = { path = "../private-kernel-lib" } +types = { path = "../types" } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr new file mode 100644 index 00000000000..8c9ecbe1591 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr @@ -0,0 +1,6 @@ +use dep::private_kernel_lib::PrivateKernelTailToPublicCircuitPrivateInputs; +use dep::types::PublicKernelCircuitPublicInputs; + +fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { + input.execute() +} diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr index 27db3eaf95b..35bb9ea802c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailCircuitPrivateInputs; -use dep::types::PrivateKernelTailCircuitPublicInputs; +use dep::types::KernelCircuitPublicInputs; -fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub PrivateKernelTailCircuitPublicInputs { +fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { input.native_private_kernel_circuit_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr index 9f47aa645f1..1008e0c0f49 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/common.nr @@ -11,10 +11,8 @@ use dep::types::{ constants::{ MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, - MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_CALL, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + MAX_PUBLIC_DATA_READS_PER_CALL }, hash::{silo_note_hash, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, utils::{arrays::{array_length, array_to_bounded_vec}}, traits::{is_empty, is_empty_array} @@ -44,10 +42,10 @@ pub fn initialize_revert_code( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder ) { - if previous_kernel.public_inputs.end_non_revertible.revert_code != 0 { - circuit_outputs.end_non_revertible.revert_code = previous_kernel.public_inputs.end_non_revertible.revert_code; + if previous_kernel.public_inputs.revert_code != 0 { + circuit_outputs.revert_code = previous_kernel.public_inputs.revert_code; } else if public_call.call_stack_item.public_inputs.revert_code != 0 { - circuit_outputs.end_non_revertible.revert_code = public_call.call_stack_item.public_inputs.revert_code; + circuit_outputs.revert_code = public_call.call_stack_item.public_inputs.revert_code; } } @@ -59,7 +57,7 @@ pub fn initialize_emitted_end_values( ) { circuit_outputs.constants = previous_kernel.public_inputs.constants; - if circuit_outputs.end_non_revertible.revert_code == 0 { + if circuit_outputs.revert_code == 0 { let start = previous_kernel.public_inputs.end; circuit_outputs.end.new_note_hashes = array_to_bounded_vec(start.new_note_hashes); circuit_outputs.end.new_nullifiers = array_to_bounded_vec(start.new_nullifiers); @@ -74,7 +72,12 @@ pub fn initialize_emitted_end_values( let start_non_revertible = previous_kernel.public_inputs.end_non_revertible; circuit_outputs.end_non_revertible.new_note_hashes = array_to_bounded_vec(start_non_revertible.new_note_hashes); circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers); + circuit_outputs.end_non_revertible.new_l2_to_l1_msgs = array_to_bounded_vec(start_non_revertible.new_l2_to_l1_msgs); circuit_outputs.end_non_revertible.public_data_update_requests = array_to_bounded_vec(start_non_revertible.public_data_update_requests); + circuit_outputs.end_non_revertible.unencrypted_logs_hash = start_non_revertible.unencrypted_logs_hash; + circuit_outputs.end_non_revertible.unencrypted_log_preimages_length = start_non_revertible.unencrypted_log_preimages_length; + circuit_outputs.end_non_revertible.encrypted_logs_hash = start_non_revertible.encrypted_logs_hash; + circuit_outputs.end_non_revertible.encrypted_log_preimages_length = start_non_revertible.encrypted_log_preimages_length; // TODO - should be propagated only in initialize_end_values() and clear them in the tail circuit. The // max_block_number must be propagated to the rollup however as a RollupValidationRequest. @@ -91,9 +94,8 @@ pub fn initialize_end_values( ) { initialize_emitted_end_values(previous_kernel, circuit_outputs); - if circuit_outputs.end_non_revertible.revert_code == 0 { + if circuit_outputs.revert_code == 0 { let start = previous_kernel.public_inputs.end; - // circuit_outputs.end.private_call_stack = array_to_bounded_vec(start.private_call_stack); // This is enforced in the private tail to always be empty. circuit_outputs.end.public_call_stack = array_to_bounded_vec(start.public_call_stack); } @@ -184,9 +186,8 @@ pub fn update_public_end_non_revertible_values( propagate_new_nullifiers_non_revertible(public_call, circuit_outputs); propagate_new_note_hashes_non_revertible(public_call, circuit_outputs); + propagate_new_l2_to_l1_messages(public_call, circuit_outputs); propagate_valid_non_revertible_public_data_update_requests(public_call, circuit_outputs); - // TODO(fees) propagate the following to non-revertible - // propagate_new_l2_to_l1_messages(public_call, circuit_outputs); } pub fn update_public_end_values(public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder) { @@ -248,10 +249,9 @@ fn propagate_valid_public_data_update_requests( let contract_address = public_call.call_stack_item.public_inputs.call_context.storage_contract_address; let update_requests = public_call.call_stack_item.public_inputs.contract_storage_update_requests; - // TODO(fees) should we have a MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL - let mut public_data_update_requests : BoundedVec = BoundedVec::new(); + let mut public_data_update_requests : BoundedVec = BoundedVec::new(); - for i in 0..MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL { let update_request = update_requests[i]; if (!update_request.is_empty()) { let public_data_update_request = PublicDataUpdateRequest { @@ -272,10 +272,9 @@ fn propagate_valid_non_revertible_public_data_update_requests( let contract_address = public_call.call_stack_item.contract_address; let update_requests = public_call.call_stack_item.public_inputs.contract_storage_update_requests; - // TODO(fees) should we have a MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL ? - let mut public_data_update_requests : BoundedVec = BoundedVec::new(); + let mut public_data_update_requests : BoundedVec = BoundedVec::new(); - for i in 0..MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL { let update_request = update_requests[i]; if (!update_request.is_empty()) { let public_data_update_request = PublicDataUpdateRequest { diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr index db9b2311809..439cf74e6e4 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -14,9 +14,9 @@ struct PublicKernelAppLogicCircuitPrivateInputs { impl PublicKernelAppLogicCircuitPrivateInputs { fn validate_inputs(self) { - let needs_setup = self.previous_kernel.public_inputs.needs_setup; + let needs_setup = self.previous_kernel.public_inputs.needs_setup(); assert(needs_setup == false, "Cannot run app logic circuit before setup circuit"); - let needs_app_logic = self.previous_kernel.public_inputs.needs_app_logic; + let needs_app_logic = self.previous_kernel.public_inputs.needs_app_logic(); assert(needs_app_logic == true, "Cannot run unnecessary app logic circuit"); } @@ -36,7 +36,7 @@ impl PublicKernelAppLogicCircuitPrivateInputs { common::update_validation_requests(self.public_call, &mut public_inputs); - if public_inputs.end_non_revertible.revert_code == 0 { + if public_inputs.revert_code == 0 { // Pops the item from the call stack and validates it against the current execution. let call_request = public_inputs.end.public_call_stack.pop(); common::validate_call_against_request(self.public_call, call_request); @@ -62,7 +62,7 @@ impl PublicKernelAppLogicCircuitPrivateInputs { ); } - public_inputs.to_inner() + public_inputs.finish() } } @@ -83,19 +83,19 @@ mod tests { address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_note_hash, silo_nullifier}, messaging::l2_to_l1_message::L2ToL1Message, - tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, + tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::arrays::{array_eq, array_length} }; use dep::types::constants::{MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL}; struct PublicKernelAppLogicCircuitPrivateInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, public_call: PublicCallDataBuilder, } impl PublicKernelAppLogicCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(true).is_public(); + let previous_kernel = FixtureBuilder::new(); let public_call = PublicCallDataBuilder::new(); PublicKernelAppLogicCircuitPrivateInputsBuilder { previous_kernel, public_call } @@ -124,7 +124,7 @@ mod tests { let hash = public_call.call_stack_item.hash(); let is_delegate_call = public_call.call_stack_item.public_inputs.call_context.is_delegate_call; self.previous_kernel.push_public_call_request(hash, is_delegate_call); - let previous_kernel = self.previous_kernel.to_public_kernel_data(); + let previous_kernel = self.previous_kernel.to_public_kernel_data(true); let kernel = PublicKernelAppLogicCircuitPrivateInputs { previous_kernel, public_call }; @@ -164,7 +164,7 @@ mod tests { #[test(should_fail_with="Cannot run unnecessary app logic circuit")] fn public_previous_kernel_private_previous_kernel_should_fail() { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); - builder.previous_kernel = PreviousKernelDataBuilder::new(true); + builder.previous_kernel = FixtureBuilder::new(); let public_call = builder.public_call.finish(); // the key difference in this test versus those that use builder.execute() @@ -172,7 +172,7 @@ mod tests { // this means that when we call `to_public_kernel_data` below, // it will say needs_app_logic is false - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(true); let kernel = PublicKernelAppLogicCircuitPrivateInputs { previous_kernel, public_call }; @@ -185,7 +185,7 @@ mod tests { let contract_address = builder.public_call.contract_address; // Setup 2 new note hashes on the previous kernel. builder.previous_kernel.append_new_note_hashes(2); - let previous = builder.previous_kernel.end.new_note_hashes.storage; + let previous = builder.previous_kernel.new_note_hashes.storage; // Setup 2 new note hashes on the current public inputs. let current = [ SideEffect { value: previous[1].value + 1, counter: 3 }, @@ -207,7 +207,7 @@ mod tests { let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); // Setup 2 data writes on the previous kernel. builder.previous_kernel.append_public_data_update_requests(2); - let previous = builder.previous_kernel.end.public_data_update_requests.storage; + let previous = builder.previous_kernel.public_data_update_requests.storage; // Setup 2 data writes on the current public inputs. builder.public_call.append_update_requests(2); let current = builder.get_current_public_data_update_requests(); @@ -226,7 +226,7 @@ mod tests { // Setup 2 data reads on the previous kernel. builder.previous_kernel.append_public_data_read_requests(2); - let previous = builder.previous_kernel.validation_requests.public_data_reads.storage; + let previous = builder.previous_kernel.public_data_reads.storage; // Setup 2 data reads on the current public inputs. builder.public_call.append_public_data_read_requests(2); let current = builder.get_current_public_data_reads(); @@ -245,8 +245,8 @@ mod tests { let contract_address = builder.public_call.contract_address; // Setup 2 new nullifiers on the previous kernel. - builder.previous_kernel.append_new_nullifiers_from_public(2); - let previous = builder.previous_kernel.end.new_nullifiers.storage; + builder.previous_kernel.append_new_nullifiers(2); + let previous = builder.previous_kernel.new_nullifiers.storage; // Setup 2 new note hashes on the current public inputs. let current = [ @@ -277,7 +277,7 @@ mod tests { // Setup 1 new l2 to l1 message on the previous kernel. let previous = [12345]; - builder.previous_kernel.end.new_l2_to_l1_msgs.extend_from_array(previous); + builder.previous_kernel.new_l2_to_l1_msgs.extend_from_array(previous); // Setup 1 new l2 to l1 message on the current public inputs. let current = [L2ToL1Message { recipient: portal_contract_address, content: 67890 }]; builder.public_call.public_inputs.new_l2_to_l1_msgs.extend_from_array(current); @@ -413,7 +413,6 @@ mod tests { let public_inputs = builder.execute(); - assert_eq_call_requests(public_inputs.end.private_call_stack, []); assert_eq_call_requests(public_inputs.end.public_call_stack, public_call_stack); assert_eq_public_data_update_requests( public_inputs.end.public_data_update_requests, diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr index c3003672c8a..2e46b97f832 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -1,9 +1,6 @@ use crate::common; use dep::types::abis::{ - kernel_circuit_public_inputs::{ - PrivateKernelTailCircuitPublicInputs, PublicKernelCircuitPublicInputs, - PublicKernelCircuitPublicInputsBuilder -}, + kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, kernel_data::PublicKernelData, public_call_data::PublicCallData }; use dep::std::unsafe; @@ -23,15 +20,7 @@ struct PublicKernelSetupCircuitPrivateInputs { impl PublicKernelSetupCircuitPrivateInputs { fn validate_inputs(self) { - let private_call_stack = self.previous_kernel.public_inputs.end.private_call_stack; - for i in 0..private_call_stack.len() { - let private_call = private_call_stack[i]; - assert( - private_call.is_empty(), "Private call stack must be empty when executing in the public kernel" - ); - } - - let needs_setup = self.previous_kernel.public_inputs.needs_setup; + let needs_setup = self.previous_kernel.public_inputs.needs_setup(); assert(needs_setup == true, "Cannot run unnecessary setup circuit"); } @@ -66,7 +55,7 @@ impl PublicKernelSetupCircuitPrivateInputs { &mut public_inputs ); - public_inputs.to_inner() + public_inputs.finish() } } @@ -87,7 +76,7 @@ mod tests { }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, contrakt::storage_read::StorageRead, hash::compute_logs_hash, - tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, + tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::{array_eq, array_length}} }; use dep::types::constants::{ @@ -96,16 +85,18 @@ mod tests { }; struct PublicKernelSetupCircuitPrivateInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, + previous_revertible: FixtureBuilder, public_call: PublicCallDataBuilder, } impl PublicKernelSetupCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(true); + let previous_kernel = FixtureBuilder::new(); + let previous_revertible = FixtureBuilder::new(); let public_call = PublicCallDataBuilder::new(); - PublicKernelSetupCircuitPrivateInputsBuilder { previous_kernel, public_call } + PublicKernelSetupCircuitPrivateInputsBuilder { previous_kernel, previous_revertible, public_call } } pub fn stub_teardown_call(&mut self) { @@ -113,13 +104,13 @@ mod tests { let teardown_call = teardown_call.finish(); let teardown_call_hash = teardown_call.call_stack_item.hash(); let teardown_is_delegate_call = teardown_call.call_stack_item.public_inputs.call_context.is_delegate_call; - self.previous_kernel.push_public_call_request_non_revertible(teardown_call_hash, teardown_is_delegate_call); + self.previous_kernel.push_public_call_request(teardown_call_hash, teardown_is_delegate_call); } pub fn push_public_call(&mut self, public_call: PublicCallData) { let public_call_hash = public_call.call_stack_item.hash(); let setup_is_delegate_call = public_call.call_stack_item.public_inputs.call_context.is_delegate_call; - self.previous_kernel.push_public_call_request_non_revertible(public_call_hash, setup_is_delegate_call); + self.previous_kernel.push_public_call_request(public_call_hash, setup_is_delegate_call); } pub fn is_delegate_call(&mut self) -> Self { @@ -149,7 +140,8 @@ mod tests { // Push the public call on top of the teardown call. let setup_call = self.public_call.finish(); self.push_public_call(setup_call); - let previous_kernel = self.previous_kernel.to_public_kernel_data(); + let mut previous_kernel = self.previous_kernel.to_public_kernel_data(false); + previous_kernel.public_inputs.end = self.previous_revertible.to_public_accumulated_data(); // Run the kernel on the setup call let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: setup_call }; @@ -237,8 +229,8 @@ mod tests { let hash = public_call.call_stack_item.hash(); // Tweak the call stack item hash. - builder.previous_kernel.push_public_call_request_non_revertible(hash + 1, false); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + builder.previous_kernel.push_public_call_request(hash + 1, false); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call }; @@ -281,8 +273,8 @@ mod tests { let hash = public_call.call_stack_item.hash(); // Caller context is empty for regular calls. let is_delegate_call = false; - builder.previous_kernel.push_public_call_request_non_revertible(hash, is_delegate_call); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + builder.previous_kernel.push_public_call_request(hash, is_delegate_call); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call }; @@ -357,14 +349,14 @@ mod tests { fn circuit_outputs_should_be_correctly_populated_with_previous_private_kernel() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); - builder.previous_kernel.validation_requests.max_block_number = MaxBlockNumber::new(13); + builder.previous_kernel.max_block_number = MaxBlockNumber::new(13); builder.public_call.append_public_call_requests_for_regular_calls(2); let storage = builder.public_call.public_call_stack.storage; builder.stub_teardown_call(); let non_revertible_call_stack = [ - builder.previous_kernel.end_non_revertible.public_call_stack.get(0), + builder.previous_kernel.public_call_stack.get(0), storage[0], storage[1] ]; @@ -379,7 +371,7 @@ mod tests { // Push the public call on top of the teardown call. let setup_call = builder.public_call.finish(); builder.push_public_call(setup_call); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); // Run the kernel on the setup call let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: setup_call }; @@ -387,7 +379,6 @@ mod tests { let public_inputs = kernel.public_kernel_setup(); assert_eq(public_inputs.validation_requests.for_rollup.max_block_number.unwrap(), 13); - assert_eq_call_requests(public_inputs.end.private_call_stack, []); assert_eq_call_requests( public_inputs.end_non_revertible.public_call_stack, non_revertible_call_stack @@ -400,14 +391,6 @@ mod tests { // assert_eq_public_data_reads(public_inputs.end.public_data_reads, read_requests); } - #[test(should_fail_with="Private call stack must be empty when executing in the public kernel")] - fn private_previous_kernel_non_empty_private_call_stack_should_fail() { - let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); - builder.previous_kernel.push_private_call_request(1, false); - - builder.failed(); - } - // TODO: Find another way to test this. Currently it will crash because we are popping from an empty array: // The application panicked (crashed). Message: Expected array index to fit in u64 // #[test(should_fail_with="Public call stack can not be empty")] @@ -430,8 +413,8 @@ mod tests { let teardown_call = builder.public_call.finish(); let teardown_call_hash = teardown_call.call_stack_item.hash(); let teardown_is_delegate_call = teardown_call.call_stack_item.public_inputs.call_context.is_delegate_call; - builder.previous_kernel.push_public_call_request_non_revertible(teardown_call_hash, teardown_is_delegate_call); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + builder.previous_kernel.push_public_call_request(teardown_call_hash, teardown_is_delegate_call); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); // Run the kernel on the setup call let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: teardown_call }; @@ -462,8 +445,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_revertible.set_unencrypted_logs( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr index 68c48968012..8240ae5d2d5 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_tail.nr @@ -5,11 +5,11 @@ use dep::reset_kernel_lib::{ }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, kernel_data::PublicKernelData, side_effect::SideEffectLinkedToNoteHash }, constants::MAX_NEW_NULLIFIERS_PER_TX, - utils::{arrays::{array_length, array_merge, array_concat, array_to_bounded_vec, assert_sorted_array}}, + utils::{arrays::{array_length, array_merge, array_to_bounded_vec, assert_sorted_array}}, hash::silo_nullifier, traits::is_empty }; use dep::std::unsafe; @@ -22,14 +22,14 @@ struct PublicKernelTailCircuitPrivateInputs { impl PublicKernelTailCircuitPrivateInputs { fn propagate_revert_code(self, public_inputs: &mut PublicKernelCircuitPublicInputsBuilder) { - public_inputs.end_non_revertible.revert_code = self.previous_kernel.public_inputs.end_non_revertible.revert_code; + public_inputs.revert_code = self.previous_kernel.public_inputs.revert_code; } fn validate_inputs(self) { let previous_public_inputs = self.previous_kernel.public_inputs; - assert(previous_public_inputs.needs_setup == false, "Previous kernel needs setup"); - assert(previous_public_inputs.needs_app_logic == false, "Previous kernel needs app logic"); - assert(previous_public_inputs.needs_teardown == false, "Previous kernel needs teardown"); + assert(previous_public_inputs.needs_setup() == false, "Previous kernel needs setup"); + assert(previous_public_inputs.needs_app_logic() == false, "Previous kernel needs app logic"); + assert(previous_public_inputs.needs_teardown() == false, "Previous kernel needs teardown"); assert_eq( array_length(previous_public_inputs.end.public_call_stack), 0, "Public call stack must be empty when executing the tail circuit" ); @@ -44,7 +44,7 @@ impl PublicKernelTailCircuitPrivateInputs { let requests = self.previous_kernel.public_inputs.validation_requests.nullifier_read_requests; - let pending_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] = array_concat(end_non_revertible.new_nullifiers, end.new_nullifiers); + let pending_nullifiers = array_merge(end_non_revertible.new_nullifiers, end.new_nullifiers); let hints = self.nullifier_read_request_hints; @@ -82,7 +82,7 @@ impl PublicKernelTailCircuitPrivateInputs { let hints = self.nullifier_non_existent_read_request_hints; - let pending_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] = array_concat(end_non_revertible.new_nullifiers, end.new_nullifiers); + let pending_nullifiers = array_merge(end_non_revertible.new_nullifiers, end.new_nullifiers); assert_sorted_array( pending_nullifiers, hints.sorted_pending_values, @@ -100,7 +100,7 @@ impl PublicKernelTailCircuitPrivateInputs { ); } - pub fn public_kernel_tail(self) -> PublicKernelCircuitPublicInputs { + pub fn public_kernel_tail(self) -> KernelCircuitPublicInputs { let mut public_inputs: PublicKernelCircuitPublicInputsBuilder = unsafe::zeroed(); self.validate_inputs(); @@ -113,7 +113,7 @@ impl PublicKernelTailCircuitPrivateInputs { self.validate_nullifier_non_existent_read_requests(&mut public_inputs); - public_inputs.to_inner() + public_inputs.finish_tail() } } @@ -128,7 +128,7 @@ mod tests { }; use dep::types::{ abis::{ - kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, kernel_data::PublicKernelData, nullifier_leaf_preimage::NullifierLeafPreimage }, constants::{ @@ -136,8 +136,8 @@ mod tests { NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT }, hash::silo_nullifier, - tests::{kernel_data_builder::PreviousKernelDataBuilder, merkle_tree_utils::NonEmptyMerkleTree}, - utils::arrays::array_concat + tests::{fixture_builder::FixtureBuilder, merkle_tree_utils::NonEmptyMerkleTree}, + utils::arrays::array_merge }; fn build_nullifier_tree() -> NonEmptyMerkleTree { @@ -153,18 +153,21 @@ mod tests { } struct PublicKernelTailCircuitPrivateInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, + previous_revertible: FixtureBuilder, nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder, nullifier_non_existent_read_request_hints_builder: NullifierNonExistentReadRequestHintsBuilder, } impl PublicKernelTailCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(true); - let mut nullifier_non_existent_read_request_hints_builder = NullifierNonExistentReadRequestHintsBuilder::new(); + let previous_kernel = FixtureBuilder::new(); + let previous_revertible = FixtureBuilder::new(); + let nullifier_non_existent_read_request_hints_builder = NullifierNonExistentReadRequestHintsBuilder::new(); let mut builder = PublicKernelTailCircuitPrivateInputsBuilder { previous_kernel, + previous_revertible, nullifier_read_request_hints_builder: NullifierReadRequestHintsBuilder::new(MAX_NULLIFIER_READ_REQUESTS_PER_TX), nullifier_non_existent_read_request_hints_builder }; @@ -181,40 +184,43 @@ mod tests { pub fn add_nullifier(&mut self, unsiloed_nullifier: Field) { self.previous_kernel.add_nullifier(unsiloed_nullifier); + self.sync_counters(); self.set_nullifiers_for_non_existent_read_request_hints(); } - pub fn append_nullifiers(&mut self, num_nullifiers: u64) { - self.previous_kernel.append_new_nullifiers_from_public(num_nullifiers); + pub fn append_nullifiers_revertible(&mut self, num_nullifiers: u64) { + self.previous_revertible.append_new_nullifiers(num_nullifiers); + self.sync_counters(); self.set_nullifiers_for_non_existent_read_request_hints(); } pub fn append_nullifiers_non_revertible(&mut self, num_nullifiers: u64) { - self.previous_kernel.append_new_nullifiers_non_revertible_from_public(num_nullifiers); + self.previous_kernel.append_new_nullifiers(num_nullifiers); + self.sync_counters(); self.set_nullifiers_for_non_existent_read_request_hints(); } fn set_nullifiers_for_non_existent_read_request_hints(&mut self) { - let previous_kernel_public_inputs = self.previous_kernel.to_public_kernel_data().public_inputs; - let nullifiers = array_concat( - previous_kernel_public_inputs.end_non_revertible.new_nullifiers, - previous_kernel_public_inputs.end.new_nullifiers + let nullifiers = array_merge( + self.previous_kernel.new_nullifiers.storage, + self.previous_revertible.new_nullifiers.storage ); self.nullifier_non_existent_read_request_hints_builder.set_nullifiers(nullifiers); } - pub fn add_nullifier_pending_read(&mut self, nullifier_index: u64) { + pub fn add_pending_revertible_nullifier_read_request(&mut self, nullifier_index: u64) { let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + self.sync_counters(); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); - let pending_value_index = nullifier_index + self.previous_kernel.end_non_revertible.new_nullifiers.len(); + let pending_value_index = nullifier_index + self.previous_kernel.new_nullifiers.len(); let hint = PendingReadHint { read_request_index, pending_value_index }; self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); self.nullifier_read_request_hints_builder.read_request_statuses[read_request_index] = ReadRequestStatus { state: ReadRequestState.PENDING, hint_index }; } - pub fn add_non_revertible_nullifier_pending_read(&mut self, nullifier_index_offset_one: u64) { - let nullifier_index = nullifier_index_offset_one + 1; // + 1 is for the first nullifier - let read_request_index = self.previous_kernel.add_read_request_for_pending_non_revertible_nullifier(nullifier_index); + pub fn add_pending_non_revertible_nullifier_read_request(&mut self, nullifier_index: u64) { + let read_request_index = self.previous_kernel.add_read_request_for_pending_nullifier(nullifier_index); + self.sync_counters(); let hint_index = self.nullifier_read_request_hints_builder.pending_read_hints.len(); let hint = PendingReadHint { read_request_index, pending_value_index: nullifier_index }; self.nullifier_read_request_hints_builder.pending_read_hints.push(hint); @@ -223,6 +229,7 @@ mod tests { pub fn read_non_existent_nullifier(&mut self, unsiloed_nullifier: Field) { self.previous_kernel.add_non_existent_read_request_for_nullifier(unsiloed_nullifier); + self.sync_counters(); let siloed_nullifier = silo_nullifier( self.previous_kernel.storage_contract_address, unsiloed_nullifier @@ -230,8 +237,19 @@ mod tests { self.nullifier_non_existent_read_request_hints_builder.add_value_read(siloed_nullifier); } - pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { - let previous_kernel = self.previous_kernel.to_public_kernel_data(); + fn sync_counters(&mut self) { + let counter_non_revertible = self.previous_kernel.counter; + let counter_revertible = self.previous_revertible.counter; + if counter_non_revertible > counter_revertible { + self.previous_revertible.counter = counter_non_revertible; + } else { + self.previous_kernel.counter = counter_revertible; + } + } + + pub fn execute(&mut self) -> KernelCircuitPublicInputs { + let mut previous_kernel = self.previous_kernel.to_public_kernel_data(false); + previous_kernel.public_inputs.end = self.previous_revertible.to_public_accumulated_data(); let kernel = PublicKernelTailCircuitPrivateInputs { previous_kernel, @@ -262,8 +280,8 @@ mod tests { unconstrained fn one_pending_nullifier_read_request() { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); + builder.append_nullifiers_revertible(3); + builder.add_pending_revertible_nullifier_read_request(1); builder.succeeded(); } @@ -271,9 +289,9 @@ mod tests { unconstrained fn two_pending_nullifier_read_requests() { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); - builder.add_nullifier_pending_read(0); + builder.append_nullifiers_revertible(3); + builder.add_pending_revertible_nullifier_read_request(1); + builder.add_pending_revertible_nullifier_read_request(0); builder.succeeded(); } @@ -283,7 +301,7 @@ mod tests { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); builder.append_nullifiers_non_revertible(3); - builder.add_non_revertible_nullifier_pending_read(1); + builder.add_pending_non_revertible_nullifier_read_request(1); builder.succeeded(); } @@ -291,8 +309,8 @@ mod tests { unconstrained fn pending_nullifier_read_request_wrong_hint_fails() { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); + builder.append_nullifiers_revertible(3); + builder.add_pending_revertible_nullifier_read_request(1); let mut hint = builder.nullifier_read_request_hints_builder.pending_read_hints.pop(); hint.pending_value_index -= 1; builder.nullifier_read_request_hints_builder.pending_read_hints.push(hint); @@ -304,12 +322,12 @@ mod tests { unconstrained fn pending_nullifier_read_request_reads_before_value_fails() { let mut builder = PublicKernelTailCircuitPrivateInputsBuilder::new(); - builder.append_nullifiers(3); - builder.add_nullifier_pending_read(1); - let nullifier_being_read = builder.previous_kernel.end.new_nullifiers.get(1); - let mut read_request = builder.previous_kernel.validation_requests.nullifier_read_requests.pop(); + builder.append_nullifiers_revertible(3); + builder.add_pending_revertible_nullifier_read_request(1); + let nullifier_being_read = builder.previous_revertible.new_nullifiers.get(1); + let mut read_request = builder.previous_kernel.nullifier_read_requests.pop(); read_request.counter = nullifier_being_read.counter - 1; - builder.previous_kernel.validation_requests.nullifier_read_requests.push(read_request); + builder.previous_kernel.nullifier_read_requests.push(read_request); builder.failed(); } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr index 85409d64a6c..4624844617c 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-lib/src/public_kernel_teardown.nr @@ -1,9 +1,6 @@ use crate::common; use dep::types::abis::{ - kernel_circuit_public_inputs::{ - PrivateKernelTailCircuitPublicInputs, PublicKernelCircuitPublicInputs, - PublicKernelCircuitPublicInputsBuilder -}, + kernel_circuit_public_inputs::{PublicKernelCircuitPublicInputs, PublicKernelCircuitPublicInputsBuilder}, kernel_data::PublicKernelData, public_call_data::PublicCallData }; use dep::std::unsafe; @@ -15,11 +12,14 @@ struct PublicKernelTeardownCircuitPrivateInputs { impl PublicKernelTeardownCircuitPrivateInputs { fn validate_inputs(self) { - let needs_setup = self.previous_kernel.public_inputs.needs_setup; - assert(needs_setup == false, "Cannot run teardown circuit before setup circuit"); - let needs_app_logic = self.previous_kernel.public_inputs.needs_app_logic; + // Currently the nested calls will be pushed to the public call stack and need_setup will return true. + // This should not be the case when nested calls are handled in avm. + // But we should also consider merging this and the setup circuit and have one circuit that deals with non-revertibles. + // let needs_setup = self.previous_kernel.public_inputs.needs_setup(); + // assert(needs_setup == false, "Cannot run teardown circuit before setup circuit"); + let needs_app_logic = self.previous_kernel.public_inputs.needs_app_logic(); assert(needs_app_logic == false, "Cannot run teardown circuit before app logic circuit"); - let needs_teardown = self.previous_kernel.public_inputs.needs_teardown; + let needs_teardown = self.previous_kernel.public_inputs.needs_teardown(); assert(needs_teardown == true, "Cannot run unnecessary teardown circuit"); } @@ -47,7 +47,7 @@ impl PublicKernelTeardownCircuitPrivateInputs { common::update_public_end_non_revertible_values(self.public_call, &mut public_inputs); - if public_inputs.end_non_revertible.revert_code == 0 { + if public_inputs.revert_code == 0 { common::accumulate_unencrypted_logs( self.public_call, self.previous_kernel.public_inputs.end.unencrypted_logs_hash, @@ -56,13 +56,7 @@ impl PublicKernelTeardownCircuitPrivateInputs { ); } - let mut output = public_inputs.to_inner(); - - // If we enqueued multiple public functions as part of executing the teardown circuit, - // continue to treat them as part of teardown. - output.needs_setup = false; - - output + public_inputs.finish() } } @@ -82,7 +76,7 @@ mod tests { }, address::{AztecAddress, EthAddress}, contract_class_id::ContractClassId, contrakt::storage_read::StorageRead, hash::compute_logs_hash, - tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, + tests::{fixture_builder::FixtureBuilder, public_call_data_builder::PublicCallDataBuilder}, utils::{arrays::{array_eq, array_length}} }; use dep::types::constants::{ @@ -91,16 +85,18 @@ mod tests { }; struct PublicKernelTeardownCircuitPrivateInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, + previous_kernel: FixtureBuilder, + previous_revertible: FixtureBuilder, public_call: PublicCallDataBuilder, } impl PublicKernelTeardownCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(true); + let previous_kernel = FixtureBuilder::new(); + let previous_revertible = FixtureBuilder::new(); let public_call = PublicCallDataBuilder::new(); - PublicKernelTeardownCircuitPrivateInputsBuilder { previous_kernel, public_call } + PublicKernelTeardownCircuitPrivateInputsBuilder { previous_kernel, previous_revertible, public_call } } pub fn is_delegate_call(&mut self) -> Self { @@ -125,8 +121,9 @@ mod tests { // Adjust the call stack item hash for the current call in the previous iteration. let hash = public_call.call_stack_item.hash(); let is_delegate_call = public_call.call_stack_item.public_inputs.call_context.is_delegate_call; - self.previous_kernel.push_public_call_request_non_revertible(hash, is_delegate_call); - let previous_kernel = self.previous_kernel.to_public_kernel_data(); + self.previous_kernel.push_public_call_request(hash, is_delegate_call); + let mut previous_kernel = self.previous_kernel.to_public_kernel_data(false); + previous_kernel.public_inputs.end = self.previous_revertible.to_public_accumulated_data(); let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; @@ -181,8 +178,8 @@ mod tests { let hash = public_call.call_stack_item.hash(); // Tweak the call stack item hash. - builder.previous_kernel.push_public_call_request_non_revertible(hash + 1, false); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + builder.previous_kernel.push_public_call_request(hash + 1, false); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; @@ -223,8 +220,8 @@ mod tests { let hash = public_call.call_stack_item.hash(); // Caller context is empty for regular calls. let is_delegate_call = false; - builder.previous_kernel.push_public_call_request_non_revertible(hash, is_delegate_call); - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + builder.previous_kernel.push_public_call_request(hash, is_delegate_call); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; @@ -322,7 +319,7 @@ mod tests { let public_call = builder.public_call.finish(); // Don't push a call for teardown - let previous_kernel = builder.previous_kernel.to_public_kernel_data(); + let previous_kernel = builder.previous_kernel.to_public_kernel_data(false); let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; @@ -352,8 +349,8 @@ mod tests { let prev_encrypted_log_preimages_length = 13; let prev_unencrypted_logs_hash = 956; let prev_unencrypted_log_preimages_length = 24; - builder.previous_kernel.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); - builder.previous_kernel.set_unencrypted_logs( + builder.previous_revertible.set_encrypted_logs(prev_encrypted_logs_hash, prev_encrypted_log_preimages_length); + builder.previous_revertible.set_unencrypted_logs( prev_unencrypted_logs_hash, prev_unencrypted_log_preimages_length ); diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr index e225c2d34a1..b82c9aa6362 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTailCircuitPrivateInputs; -use dep::types::PublicKernelCircuitPublicInputs; +use dep::types::KernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +unconstrained fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { input.public_kernel_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr index 19b9f802f48..a294f728943 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTailCircuitPrivateInputs; -use dep::types::PublicKernelCircuitPublicInputs; +use dep::types::KernelCircuitPublicInputs; -fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { input.public_kernel_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr index 07a22b9eb44..a156e40f1a6 100644 --- a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/lib.nr @@ -1,10 +1,12 @@ use non_existent_read_request_reset::reset_non_existent_read_requests; use nullifier_non_existent_read_request_reset::NullifierNonExistentReadRequestHints; use nullifier_read_request_reset::NullifierReadRequestHints; +use private_validation_request_processor::PrivateValidationRequestProcessor; use read_request_reset::reset_read_requests; mod non_existent_read_request_reset; mod nullifier_non_existent_read_request_reset; mod nullifier_read_request_reset; +mod private_validation_request_processor; mod read_request_reset; mod tests; diff --git a/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr new file mode 100644 index 00000000000..9f60134dd45 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/reset-kernel-lib/src/private_validation_request_processor.nr @@ -0,0 +1,77 @@ +use crate::{nullifier_read_request_reset::NullifierReadRequestHints, read_request_reset::reset_read_requests}; +use dep::types::{ + abis::{side_effect::{SideEffect, SideEffectLinkedToNoteHash}, validation_requests::ValidationRequests}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX +}, + grumpkin_private_key::GrumpkinPrivateKey, keys::compute_siloed_nullifier_secret_key, + traits::is_empty +}; + +struct PrivateValidationRequestProcessor { + validation_requests: ValidationRequests, + note_hash_read_request_hints: [u64; MAX_NOTE_HASH_READ_REQUESTS_PER_TX], + pending_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + nullifier_read_request_hints: NullifierReadRequestHints, + pending_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + master_nullifier_secret_keys: [GrumpkinPrivateKey; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], + nullifier_tree_root: Field +} + +impl PrivateValidationRequestProcessor { + pub fn validate(self) { + self.validate_note_hash_read_requests(); + self.validate_nullifier_read_requests(); + self.validate_nullifier_keys(); + } + + fn validate_note_hash_read_requests(self) { + let read_requests = self.validation_requests.note_hash_read_requests; + for i in 0..read_requests.len() { + let read_request = read_requests[i]; + if (read_request.value != 0) { + let index = self.note_hash_read_request_hints[i]; + let note_hash = self.pending_note_hashes[index]; + assert_eq(read_request.value, note_hash.value, "Hinted note hash does not match read request"); + assert( + read_request.counter > note_hash.counter, "Read request counter must be greater than note hash counter" + ); + } + } + } + + fn validate_nullifier_read_requests(self) { + let remaining_requests = reset_read_requests( + self.validation_requests.nullifier_read_requests, + self.pending_nullifiers, + self.nullifier_read_request_hints.read_request_statuses, + self.nullifier_read_request_hints.pending_read_hints, + self.nullifier_read_request_hints.settled_read_hints, + self.nullifier_tree_root + ); + // When we have a separate reset circuit, we can allow unverified requests and process them later after the + // corresponding values are added to public inputs in nested executions. + // But right now, all the request must be cleared in one go. + assert(remaining_requests.len() == 0, "All nullifier read requests must be verified"); + } + + fn validate_nullifier_keys(self) { + let requests = self.validation_requests.nullifier_key_validation_requests; + for i in 0..MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX { + let request = requests[i]; + if !is_empty(request) { + let master_secret_key = self.master_nullifier_secret_keys[i]; + let computed_public_key = master_secret_key.derive_public_key(); + assert( + computed_public_key.eq(request.public_key), "Cannot derive nullifier public key from the master key." + ); + + let computed_secret_key = compute_siloed_nullifier_secret_key(master_secret_key, request.contract_address); + assert( + computed_secret_key.eq(request.secret_key), "Cannot derive siloed secret key from the master key." + ); + } + } + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr index a3efd75b9ef..60f2bc65163 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -12,7 +12,7 @@ use dep::types::{ append_only_tree_snapshot::AppendOnlyTreeSnapshot, membership_witness::{ArchiveRootMembershipWitness, NullifierMembershipWitness, PublicDataMembershipWitness}, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_update_request::PublicDataUpdateRequest, - public_data_read::PublicDataRead, kernel_data::RollupKernelData, + public_data_read::PublicDataRead, kernel_data::KernelData, side_effect::{SideEffect, SideEffectLinkedToNoteHash}, accumulated_data::CombinedAccumulatedData }, constants::{ @@ -21,10 +21,7 @@ use dep::types::{ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, NUM_ENCRYPTED_LOGS_HASHES_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NULLIFIER_TREE_HEIGHT, PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, - PUBLIC_DATA_SUBTREE_HEIGHT, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX + PUBLIC_DATA_SUBTREE_HEIGHT }, merkle_tree::{ append_only_tree, assert_check_membership, calculate_empty_tree_root, calculate_subtree_root, @@ -37,7 +34,7 @@ use dep::types::{ }; struct BaseRollupInputs { - kernel_data: RollupKernelData, + kernel_data: KernelData, start: PartialStateReference, state_diff_hints: StateDiffHints, @@ -48,8 +45,6 @@ struct BaseRollupInputs { sorted_public_data_writes_indexes: [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], low_public_data_writes_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], - public_data_reads_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], - public_data_reads_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], archive_root_membership_witness: ArchiveRootMembershipWitness, @@ -101,7 +96,10 @@ impl BaseRollupInputs { let end_public_data_tree_snapshot = self.validate_and_process_public_state(); // Calculate the tx effects hash of the transaction - let tx_effects_hash = compute_tx_effects_hash(self.kernel_data.public_inputs.end); + let tx_effects_hash = compute_tx_effects_hash( + self.kernel_data.public_inputs.end, + self.kernel_data.public_inputs.revert_code + ); let out_hash = compute_kernel_out_hash(self.kernel_data.public_inputs.end); // Perform membership checks that the notes provided exist within the historical trees data @@ -396,9 +394,8 @@ mod tests { append_only_tree_snapshot::AppendOnlyTreeSnapshot, membership_witness::{ArchiveRootMembershipWitness, NullifierMembershipWitness, PublicDataMembershipWitness}, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_read::PublicDataRead, - public_data_update_request::PublicDataUpdateRequest, - kernel_data::{PublicKernelData, RollupKernelData}, side_effect::SideEffect, - accumulated_data::CombinedAccumulatedData + public_data_update_request::PublicDataUpdateRequest, kernel_data::KernelData, + side_effect::SideEffect, accumulated_data::CombinedAccumulatedData }, address::{AztecAddress, EthAddress}, constants::{ @@ -413,8 +410,8 @@ mod tests { public_data_tree_leaf::PublicDataTreeLeaf, public_data_tree_leaf_preimage::PublicDataTreeLeafPreimage, tests::{ - kernel_data_builder::PreviousKernelDataBuilder, - merkle_tree_utils::{NonEmptyMerkleTree, compute_zero_hashes}, sort::sort_high_to_low + fixture_builder::FixtureBuilder, merkle_tree_utils::{NonEmptyMerkleTree, compute_zero_hashes}, + sort::sort_high_to_low }, utils::{field::{full_field_less_than, field_from_bytes_32_trunc, field_from_bytes}, uint256::U256} }; @@ -430,18 +427,16 @@ mod tests { fn update_public_data_tree( public_data_tree: &mut NonEmptyMerkleTree, - kernel_data: &mut RollupKernelData, + kernel_data: &mut KernelData, snapshot: AppendOnlyTreeSnapshot, public_data_writes: BoundedVec<(u64, PublicDataTreeLeaf), 2>, mut pre_existing_public_data: [PublicDataTreeLeafPreimage; EXISTING_LEAVES] - ) -> ([Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX], [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { + ) -> ([Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH], [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], [PublicDataTreeLeafPreimage; EXISTING_LEAVES]) { let mut subtree_path: [Field; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH] = dep::std::unsafe::zeroed(); let mut sorted_public_data_writes: [PublicDataTreeLeaf; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); let mut sorted_public_data_writes_indexes: [u64; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); let mut low_public_data_writes_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); let mut low_public_data_writes_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); - let mut public_data_reads_preimages: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_READS_PER_TX] = dep::std::unsafe::zeroed(); - let mut public_data_reads_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX] = dep::std::unsafe::zeroed(); let mut new_subtree: [PublicDataTreeLeafPreimage; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX] = dep::std::unsafe::zeroed(); for i in 0..MAX_PUBLIC_DATA_WRITES_PER_TEST { @@ -504,12 +499,12 @@ mod tests { subtree_path = BaseRollupInputsBuilder::extract_subtree_sibling_path(public_data_tree.get_sibling_path(snapshot.next_available_leaf_index as u64), [0; PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH]); ( - subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, public_data_reads_preimages, public_data_reads_witnesses, pre_existing_public_data + subtree_path, sorted_public_data_writes, sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, pre_existing_public_data ) } struct BaseRollupInputsBuilder { - kernel_data: PreviousKernelDataBuilder, + kernel_data: FixtureBuilder, pre_existing_notes: [Field; MAX_NEW_NOTE_HASHES_PER_TX], pre_existing_nullifiers: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], pre_existing_contracts: [Field; 2], @@ -528,13 +523,10 @@ mod tests { impl BaseRollupInputsBuilder { fn new() -> Self { let mut inputs: BaseRollupInputsBuilder = dep::std::unsafe::zeroed(); + inputs.kernel_data = FixtureBuilder::new(); inputs.constants.global_variables.chain_id = 1; inputs.constants.global_variables.version = 0; - let mut builder = PreviousKernelDataBuilder::new(true); - let _nullifier = builder.end_non_revertible.new_nullifiers.pop(); - inputs.kernel_data = builder.is_public(); - inputs.pre_existing_blocks[0] = inputs.kernel_data.historical_header.hash(); inputs @@ -554,7 +546,7 @@ mod tests { fn update_nullifier_tree_with_new_leaves( mut self, nullifier_tree: &mut NonEmptyMerkleTree, - kernel_data: &mut RollupKernelData, + kernel_data: &mut KernelData, start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot ) -> ([NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX], [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_TX], [Field; MAX_NEW_NULLIFIERS_PER_TX], [u64; MAX_NEW_NULLIFIERS_PER_TX]) { let mut nullifier_predecessor_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX] = dep::std::unsafe::zeroed(); @@ -611,7 +603,7 @@ mod tests { } fn build_inputs(mut self) -> BaseRollupInputs { - let mut kernel_data = self.kernel_data.to_rollup_kernel_data(); + let mut kernel_data = self.kernel_data.to_kernel_data(); let start_note_hash_tree = NonEmptyMerkleTree::new( self.pre_existing_notes, @@ -684,8 +676,6 @@ mod tests { sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, - public_data_reads_preimages, - public_data_reads_witnesses, _new_subtree ) = update_public_data_tree( &mut start_public_data_tree, @@ -719,8 +709,6 @@ mod tests { sorted_public_data_writes_indexes, low_public_data_writes_preimages, low_public_data_writes_witnesses, - public_data_reads_preimages, - public_data_reads_witnesses, archive_root_membership_witness: ArchiveRootMembershipWitness { leaf_index: 0, sibling_path: start_archive.get_sibling_path(0) }, constants: self.constants } @@ -744,11 +732,11 @@ mod tests { let mut builder = BaseRollupInputsBuilder::new(); let new_note_hashes = [27, 28, 29, 30, 31, 32]; - let mut new_note_hashes_vec = builder.kernel_data.end.new_note_hashes; + let mut new_note_hashes_vec = builder.kernel_data.new_note_hashes; for i in 0..new_note_hashes.len() { new_note_hashes_vec.push(SideEffect { value: new_note_hashes[i], counter: 0 }); } - builder.kernel_data.end.new_note_hashes = new_note_hashes_vec; + builder.kernel_data.new_note_hashes = new_note_hashes_vec; let mut expected_commitments_tree = NonEmptyMerkleTree::new( [0; MAX_NEW_NOTE_HASHES_PER_TX * 2], [0; NOTE_HASH_TREE_HEIGHT], @@ -1039,21 +1027,6 @@ mod tests { assert_eq(outputs.height_in_block_tree, 0); } - #[test] - unconstrained fn single_public_state_read() { - let mut builder = BaseRollupInputsBuilder::new(); - - builder.pre_existing_public_data[0] = PublicDataTreeLeafPreimage { - slot: 27, - value: 28, - next_slot: 0, - next_index: 0, - }; - builder.public_data_reads.push(0); - - builder.succeeds(); - } - #[test] unconstrained fn single_public_state_write() { let mut builder = BaseRollupInputsBuilder::new(); diff --git a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr index 04f172053ab..7b79a319548 100644 --- a/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr +++ b/noir-projects/noir-protocol-circuits/crates/rollup-lib/src/components.nr @@ -128,7 +128,7 @@ global TX_EFFECTS_HASH_INPUT_FIELDS = 197; // Computes the tx effects hash for a base rollup (a single transaction) // TODO(Alvaro): This is too slow for brillig without the array optimization -pub fn compute_tx_effects_hash(combined: CombinedAccumulatedData) -> Field { +pub fn compute_tx_effects_hash(combined: CombinedAccumulatedData, revert_code: u8) -> Field { // Compute tx effect hash // Consist of // MAX_NEW_NOTE_HASHES_PER_TX fields for note hashes @@ -140,7 +140,6 @@ pub fn compute_tx_effects_hash(combined: CombinedAccumulatedData) -> Field { // 1 unencrypted logs hash --> 1 sha256 hash -> 31 bytes -> 1 fields | Beware when populating bytes that we fill (prepend) to 32! let mut txs_effects_hash_input = [0; TX_EFFECTS_HASH_INPUT_FIELDS]; - let revert_code = combined.revert_code; let new_note_hashes = combined.new_note_hashes; let new_nullifiers = combined.new_nullifiers; let new_l2_to_l1_msgs = combined.new_l2_to_l1_msgs; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data.nr index fc606fc5abd..335ee3d7a23 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data.nr @@ -1,19 +1,15 @@ -mod accumulated_non_revertible_data_builder; -mod accumulated_revertible_data_builder; mod combined_accumulated_data; mod combined_accumulated_data_builder; -mod private_accumulated_non_revertible_data; -mod private_accumulated_revertible_data; -mod public_accumulated_non_revertible_data; -mod public_accumulated_revertible_data; +mod private_accumulated_data; +mod private_accumulated_data_builder; +mod public_accumulated_data; +mod public_accumulated_data_builder; use crate::abis::accumulated_data::{ combined_accumulated_data::CombinedAccumulatedData, - private_accumulated_revertible_data::PrivateAccumulatedRevertibleData, - private_accumulated_non_revertible_data::PrivateAccumulatedNonRevertibleData, combined_accumulated_data_builder::CombinedAccumulatedDataBuilder, - public_accumulated_non_revertible_data::PublicAccumulatedNonRevertibleData, - public_accumulated_revertible_data::PublicAccumulatedRevertibleData, - accumulated_non_revertible_data_builder::AccumulatedNonRevertibleDataBuilder, - accumulated_revertible_data_builder::AccumulatedRevertibleDataBuilder + private_accumulated_data::PrivateAccumulatedData, + private_accumulated_data_builder::PrivateAccumulatedDataBuilder, + public_accumulated_data::PublicAccumulatedData, + public_accumulated_data_builder::PublicAccumulatedDataBuilder }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr deleted file mode 100644 index ad363eff5f1..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_non_revertible_data_builder.nr +++ /dev/null @@ -1,45 +0,0 @@ -use crate::{ - abis::{ - accumulated_data::{ - private_accumulated_non_revertible_data::PrivateAccumulatedNonRevertibleData, - public_accumulated_non_revertible_data::PublicAccumulatedNonRevertibleData -}, - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} -} -}; -use crate::constants::{ - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX -}; - -struct AccumulatedNonRevertibleDataBuilder { - revert_code: u8, - - new_note_hashes: BoundedVec, - new_nullifiers: BoundedVec, - public_call_stack: BoundedVec, - - public_data_update_requests: BoundedVec, -} - -impl AccumulatedNonRevertibleDataBuilder { - pub fn to_private(self) -> PrivateAccumulatedNonRevertibleData { - PrivateAccumulatedNonRevertibleData { - revert_code: self.revert_code, - new_note_hashes: self.new_note_hashes.storage, - new_nullifiers: self.new_nullifiers.storage, - public_call_stack: self.public_call_stack.storage - } - } - pub fn to_public(self) -> PublicAccumulatedNonRevertibleData { - PublicAccumulatedNonRevertibleData { - revert_code: self.revert_code, - new_note_hashes: self.new_note_hashes.storage, - new_nullifiers: self.new_nullifiers.storage, - public_call_stack: self.public_call_stack.storage, - public_data_update_requests: self.public_data_update_requests.storage - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr deleted file mode 100644 index 232ebbc81bc..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/accumulated_revertible_data_builder.nr +++ /dev/null @@ -1,65 +0,0 @@ -use crate::{ - abis::{ - accumulated_data::{ - private_accumulated_revertible_data::PrivateAccumulatedRevertibleData, - public_accumulated_revertible_data::PublicAccumulatedRevertibleData -}, - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} -} -}; -use crate::constants::{ - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX -}; - -struct AccumulatedRevertibleDataBuilder { - new_note_hashes: BoundedVec, - new_nullifiers: BoundedVec, - - private_call_stack: BoundedVec, - public_call_stack: BoundedVec, - new_l2_to_l1_msgs: BoundedVec, - - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, - - // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the - // variable-length data. - encrypted_log_preimages_length: Field, - unencrypted_log_preimages_length: Field, - - public_data_update_requests: BoundedVec, -} - -impl AccumulatedRevertibleDataBuilder { - pub fn to_private(self) -> PrivateAccumulatedRevertibleData { - PrivateAccumulatedRevertibleData { - new_note_hashes: self.new_note_hashes.storage, - new_nullifiers: self.new_nullifiers.storage, - private_call_stack: self.private_call_stack.storage, - public_call_stack: self.public_call_stack.storage, - new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, - encrypted_log_preimages_length: self.encrypted_log_preimages_length, - unencrypted_log_preimages_length: self.unencrypted_log_preimages_length - } - } - - pub fn to_public(self) -> PublicAccumulatedRevertibleData { - PublicAccumulatedRevertibleData { - new_note_hashes: self.new_note_hashes.storage, - new_nullifiers: self.new_nullifiers.storage, - private_call_stack: self.private_call_stack.storage, - public_call_stack: self.public_call_stack.storage, - new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, - encrypted_log_preimages_length: self.encrypted_log_preimages_length, - unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, - public_data_update_requests: self.public_data_update_requests.storage - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr index 76f7e00531f..97f10103185 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data.nr @@ -1,33 +1,19 @@ use crate::{ abis::{ - accumulated_data::{ - public_accumulated_non_revertible_data::PublicAccumulatedNonRevertibleData, - public_accumulated_revertible_data::PublicAccumulatedRevertibleData -}, - call_request::CallRequest, caller_context::CallerContext, + accumulated_data::public_accumulated_data::PublicAccumulatedData, public_data_update_request::PublicDataUpdateRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} -} -}; -use crate::constants::{ - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX +}, + utils::arrays::array_merge }; -use dep::std::unsafe; -use crate::traits::is_empty; - -use crate::utils::arrays::{array_cp, array_concat, array_to_bounded_vec}; - struct CombinedAccumulatedData { - revert_code: u8, - new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], - - private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], - public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], encrypted_logs_hash: Field, @@ -42,116 +28,19 @@ struct CombinedAccumulatedData { } impl CombinedAccumulatedData { - pub fn needs_app_logic(self) -> bool { - // if we have any enqueued revertible public calls, we need to run the public app logic circuit. - !self.public_call_stack[0].is_empty() - } - - pub fn recombine( - non_revertible: PublicAccumulatedNonRevertibleData, - revertible: PublicAccumulatedRevertibleData - ) -> CombinedAccumulatedData { + pub fn recombine(non_revertible: PublicAccumulatedData, revertible: PublicAccumulatedData) -> Self { CombinedAccumulatedData { - revert_code: non_revertible.revert_code, - new_note_hashes: array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes), - new_nullifiers: array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers), - private_call_stack: revertible.private_call_stack, - public_call_stack: array_concat( - non_revertible.public_call_stack, - revertible.public_call_stack - ), + new_note_hashes: array_merge(non_revertible.new_note_hashes, revertible.new_note_hashes), + new_nullifiers: array_merge(non_revertible.new_nullifiers, revertible.new_nullifiers), new_l2_to_l1_msgs: revertible.new_l2_to_l1_msgs, encrypted_logs_hash: revertible.encrypted_logs_hash, unencrypted_logs_hash: revertible.unencrypted_logs_hash, encrypted_log_preimages_length: revertible.encrypted_log_preimages_length, unencrypted_log_preimages_length: revertible.unencrypted_log_preimages_length, - public_data_update_requests: array_concat( + public_data_update_requests: array_merge( non_revertible.public_data_update_requests, revertible.public_data_update_requests ) } } } - -mod tests { - use crate::abis::{ - accumulated_data::combined_accumulated_data_builder::CombinedAccumulatedDataBuilder, - call_request::CallRequest, caller_context::CallerContext, - public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} - }; - use crate::address::AztecAddress; - use crate::utils::arrays::array_eq; - use dep::std::unsafe; - - #[test] - unconstrained fn splits_revertible_and_non_revertible() { - let mut builder: CombinedAccumulatedDataBuilder = unsafe::zeroed(); - - let non_revertible_commitments = [ - SideEffect { value: 1, counter: 1 }, - SideEffect { value: 2, counter: 3 } - ]; - - let non_revertible_nullifiers = [ - SideEffectLinkedToNoteHash { value: 10, note_hash: 1, counter: 2 }, - SideEffectLinkedToNoteHash { value: 20, note_hash: 2, counter: 4 } - ]; - - let non_revertible_public_stack = [ - CallRequest { - hash: 1, - caller_contract_address: AztecAddress::from_field(1), - caller_context: CallerContext::empty(), - start_side_effect_counter: 5, - end_side_effect_counter: 0 - }, - CallRequest { - hash: 2, - caller_contract_address: AztecAddress::from_field(1), - caller_context: CallerContext::empty(), - start_side_effect_counter: 6, - end_side_effect_counter: 0 - } - ]; - - let revertible_commitments = [ - SideEffect { value: 3, counter: 7 }, - SideEffect { value: 4, counter: 10 } - ]; - - let revertible_nullifiers = [ - SideEffectLinkedToNoteHash { value: 30, note_hash: 3, counter: 8 }, - SideEffectLinkedToNoteHash { value: 40, note_hash: 4, counter: 11 } - ]; - - let revertible_public_call_stack = [ - CallRequest { - hash: 3, - caller_contract_address: AztecAddress::from_field(3), - caller_context: CallerContext::empty(), - start_side_effect_counter: 9, - end_side_effect_counter: 0 - } - ]; - - builder.new_note_hashes.extend_from_array(non_revertible_commitments); - builder.new_note_hashes.extend_from_array(revertible_commitments); - - builder.new_nullifiers.extend_from_array(non_revertible_nullifiers); - builder.new_nullifiers.extend_from_array(revertible_nullifiers); - - builder.public_call_stack.extend_from_array(non_revertible_public_stack); - builder.public_call_stack.extend_from_array(revertible_public_call_stack); - - let (non_revertible, revertible) = builder.split(7); - - assert(array_eq(non_revertible.new_note_hashes, non_revertible_commitments)); - assert(array_eq(non_revertible.new_nullifiers, non_revertible_nullifiers)); - assert(array_eq(non_revertible.public_call_stack, non_revertible_public_stack)); - - assert(array_eq(revertible.new_note_hashes, revertible_commitments)); - assert(array_eq(revertible.new_nullifiers, revertible_nullifiers)); - assert(array_eq(revertible.public_call_stack, revertible_public_call_stack)); - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr index f72d34c9565..375fc530327 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/combined_accumulated_data_builder.nr @@ -1,37 +1,18 @@ use crate::{ abis::{ - accumulated_data::{ - accumulated_non_revertible_data_builder::AccumulatedNonRevertibleDataBuilder, - accumulated_revertible_data_builder::AccumulatedRevertibleDataBuilder, - combined_accumulated_data::CombinedAccumulatedData, - private_accumulated_revertible_data::PrivateAccumulatedRevertibleData, - private_accumulated_non_revertible_data::PrivateAccumulatedNonRevertibleData, - public_accumulated_revertible_data::PublicAccumulatedRevertibleData, - public_accumulated_non_revertible_data::PublicAccumulatedNonRevertibleData -}, - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, + accumulated_data::combined_accumulated_data::CombinedAccumulatedData, + public_data_update_request::PublicDataUpdateRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} } }; use crate::constants::{ - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX }; -use dep::std::unsafe; -use crate::traits::is_empty; - -use crate::utils::arrays::{array_cp, array_concat, array_to_bounded_vec}; - struct CombinedAccumulatedDataBuilder { - revert_code: u8, - new_note_hashes: BoundedVec, new_nullifiers: BoundedVec, - - private_call_stack: BoundedVec, - public_call_stack: BoundedVec, new_l2_to_l1_msgs: BoundedVec, encrypted_logs_hash: Field, @@ -46,42 +27,10 @@ struct CombinedAccumulatedDataBuilder { } impl CombinedAccumulatedDataBuilder { - pub fn recombine( - non_revertible: PublicAccumulatedNonRevertibleData, - revertible: PublicAccumulatedRevertibleData - ) -> CombinedAccumulatedDataBuilder { - CombinedAccumulatedDataBuilder { - revert_code: non_revertible.revert_code, - new_note_hashes: array_to_bounded_vec(array_concat(non_revertible.new_note_hashes, revertible.new_note_hashes)), - new_nullifiers: array_to_bounded_vec(array_concat(non_revertible.new_nullifiers, revertible.new_nullifiers)), - private_call_stack: array_to_bounded_vec(revertible.private_call_stack), - public_call_stack: array_to_bounded_vec( - array_concat( - non_revertible.public_call_stack, - revertible.public_call_stack - ) - ), - new_l2_to_l1_msgs: array_to_bounded_vec(revertible.new_l2_to_l1_msgs), - encrypted_logs_hash: revertible.encrypted_logs_hash, - unencrypted_logs_hash: revertible.unencrypted_logs_hash, - encrypted_log_preimages_length: revertible.encrypted_log_preimages_length, - unencrypted_log_preimages_length: revertible.unencrypted_log_preimages_length, - public_data_update_requests: array_to_bounded_vec( - array_concat( - non_revertible.public_data_update_requests, - revertible.public_data_update_requests - ) - ) - } - } - pub fn finish(self) -> CombinedAccumulatedData { CombinedAccumulatedData { - revert_code: self.revert_code, new_note_hashes: self.new_note_hashes.storage, new_nullifiers: self.new_nullifiers.storage, - private_call_stack: self.private_call_stack.storage, - public_call_stack: self.public_call_stack.storage, new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, encrypted_logs_hash: self.encrypted_logs_hash, unencrypted_logs_hash: self.unencrypted_logs_hash, @@ -90,84 +39,4 @@ impl CombinedAccumulatedDataBuilder { public_data_update_requests: self.public_data_update_requests.storage } } - - pub fn to_private_accumulated_revertible_data(self) -> PrivateAccumulatedRevertibleData { - PrivateAccumulatedRevertibleData { - new_note_hashes: array_cp(self.new_note_hashes.storage), - new_nullifiers: array_cp(self.new_nullifiers.storage), - private_call_stack: self.private_call_stack.storage, - public_call_stack: array_cp(self.public_call_stack.storage), - new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, - encrypted_log_preimages_length: self.encrypted_log_preimages_length, - unencrypted_log_preimages_length: self.unencrypted_log_preimages_length - } - } - - pub fn to_public_accumulated_revertible_data(self) -> PublicAccumulatedRevertibleData { - PublicAccumulatedRevertibleData { - new_note_hashes: array_cp(self.new_note_hashes.storage), - new_nullifiers: array_cp(self.new_nullifiers.storage), - private_call_stack: self.private_call_stack.storage, - public_call_stack: array_cp(self.public_call_stack.storage), - new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, - encrypted_logs_hash: self.encrypted_logs_hash, - unencrypted_logs_hash: self.unencrypted_logs_hash, - encrypted_log_preimages_length: self.encrypted_log_preimages_length, - unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, - public_data_update_requests: array_cp(self.public_data_update_requests.storage) - } - } - - pub fn split( - self, - min_revertible_side_effect_counter: u32 - ) -> (PrivateAccumulatedNonRevertibleData, PrivateAccumulatedRevertibleData) { - let mut non_revertible_builder: AccumulatedNonRevertibleDataBuilder = unsafe::zeroed(); - let mut revertible_builder: AccumulatedRevertibleDataBuilder = unsafe::zeroed(); - - for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - let commitment = self.new_note_hashes.storage[i]; - // TODO(fees) we shouldn't need to check is_empty here, - // but we do because new_note_hashes is bounded to MAX_REVERTIBLE_NOTE_HASHES_PER_TX - if !is_empty(commitment) { - if commitment.counter < min_revertible_side_effect_counter { - non_revertible_builder.new_note_hashes.push(commitment); - } else { - revertible_builder.new_note_hashes.push(commitment); - } - } - } - for i in 0..MAX_NEW_NULLIFIERS_PER_TX { - let nullifier = self.new_nullifiers.storage[i]; - if !is_empty(nullifier) { - if nullifier.counter < min_revertible_side_effect_counter { - non_revertible_builder.new_nullifiers.push(nullifier); - } else { - revertible_builder.new_nullifiers.push(nullifier); - } - } - } - - for i in 0..MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX { - let call_stack_item = self.public_call_stack.storage[i]; - if !is_empty(call_stack_item) { - if call_stack_item.start_side_effect_counter < min_revertible_side_effect_counter { - non_revertible_builder.public_call_stack.push(call_stack_item); - } else { - revertible_builder.public_call_stack.push(call_stack_item); - } - } - } - - revertible_builder.private_call_stack = self.private_call_stack; - revertible_builder.new_l2_to_l1_msgs = self.new_l2_to_l1_msgs; - revertible_builder.encrypted_logs_hash = self.encrypted_logs_hash; - revertible_builder.unencrypted_logs_hash = self.unencrypted_logs_hash; - revertible_builder.encrypted_log_preimages_length = self.encrypted_log_preimages_length; - revertible_builder.unencrypted_log_preimages_length= self.unencrypted_log_preimages_length; - - (non_revertible_builder.to_private(), revertible_builder.to_private()) - } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr new file mode 100644 index 00000000000..4c33cb01e7b --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data.nr @@ -0,0 +1,22 @@ +use crate::{abis::{call_request::CallRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; +use crate::constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX +}; + +struct PrivateAccumulatedData { + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], + + encrypted_logs_hash: Field, + unencrypted_logs_hash: Field, + + // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the + // variable-length data. + encrypted_log_preimages_length: Field, + unencrypted_log_preimages_length: Field, + + private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], + public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr new file mode 100644 index 00000000000..0fed9cb468f --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_data_builder.nr @@ -0,0 +1,189 @@ +use crate::{ + abis::{ + accumulated_data::{ + combined_accumulated_data::CombinedAccumulatedData, + private_accumulated_data::PrivateAccumulatedData, public_accumulated_data::PublicAccumulatedData, + public_accumulated_data_builder::PublicAccumulatedDataBuilder +}, + call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX +} +}; +use dep::std::unsafe; + +struct PrivateAccumulatedDataBuilder { + new_note_hashes: BoundedVec, + new_nullifiers: BoundedVec, + new_l2_to_l1_msgs: BoundedVec, + + encrypted_logs_hash: Field, + unencrypted_logs_hash: Field, + + // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the + // variable-length data. + encrypted_log_preimages_length: Field, + unencrypted_log_preimages_length: Field, + + private_call_stack: BoundedVec, + public_call_stack: BoundedVec, +} + +impl PrivateAccumulatedDataBuilder { + pub fn finish(self) -> PrivateAccumulatedData { + PrivateAccumulatedData { + new_note_hashes: self.new_note_hashes.storage, + new_nullifiers: self.new_nullifiers.storage, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + private_call_stack: self.private_call_stack.storage, + public_call_stack: self.public_call_stack.storage + } + } + + pub fn to_combined(self) -> CombinedAccumulatedData { + CombinedAccumulatedData { + new_note_hashes: self.new_note_hashes.storage, + new_nullifiers: self.new_nullifiers.storage, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + public_data_update_requests: unsafe::zeroed() + } + } + + pub fn split_to_public( + self, + min_revertible_side_effect_counter: u32 + ) -> (PublicAccumulatedData, PublicAccumulatedData) { + let mut non_revertible_builder: PublicAccumulatedDataBuilder = unsafe::zeroed(); + let mut revertible_builder: PublicAccumulatedDataBuilder = unsafe::zeroed(); + + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + let note_hash = self.new_note_hashes.storage[i]; + if note_hash.counter < min_revertible_side_effect_counter { + non_revertible_builder.new_note_hashes.push(note_hash); + } else { + revertible_builder.new_note_hashes.push(note_hash); + } + } + for i in 0..MAX_NEW_NULLIFIERS_PER_TX { + let nullifier = self.new_nullifiers.storage[i]; + if nullifier.counter < min_revertible_side_effect_counter { + non_revertible_builder.new_nullifiers.push(nullifier); + } else { + revertible_builder.new_nullifiers.push(nullifier); + } + } + + for i in 0..MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX { + let call_stack_item = self.public_call_stack.storage[i]; + if call_stack_item.start_side_effect_counter < min_revertible_side_effect_counter { + non_revertible_builder.public_call_stack.push(call_stack_item); + } else { + revertible_builder.public_call_stack.push(call_stack_item); + } + } + + revertible_builder.new_l2_to_l1_msgs = self.new_l2_to_l1_msgs; + revertible_builder.encrypted_logs_hash = self.encrypted_logs_hash; + revertible_builder.unencrypted_logs_hash = self.unencrypted_logs_hash; + revertible_builder.encrypted_log_preimages_length = self.encrypted_log_preimages_length; + revertible_builder.unencrypted_log_preimages_length= self.unencrypted_log_preimages_length; + + (non_revertible_builder.finish(), revertible_builder.finish()) + } +} + +mod tests { + use crate::{ + abis::{ + accumulated_data::private_accumulated_data_builder::PrivateAccumulatedDataBuilder, + call_request::CallRequest, caller_context::CallerContext, + public_data_update_request::PublicDataUpdateRequest, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} + }, + address::AztecAddress, utils::arrays::array_eq + }; + use dep::std::unsafe; + + #[test] + unconstrained fn splits_revertible_and_non_revertible() { + let mut builder: PrivateAccumulatedDataBuilder = unsafe::zeroed(); + + let non_revertible_commitments = [ + SideEffect { value: 1, counter: 1 }, + SideEffect { value: 2, counter: 3 } + ]; + + let non_revertible_nullifiers = [ + SideEffectLinkedToNoteHash { value: 10, note_hash: 1, counter: 2 }, + SideEffectLinkedToNoteHash { value: 20, note_hash: 2, counter: 4 } + ]; + + let non_revertible_public_stack = [ + CallRequest { + hash: 1, + caller_contract_address: AztecAddress::from_field(1), + caller_context: CallerContext::empty(), + start_side_effect_counter: 5, + end_side_effect_counter: 0 + }, + CallRequest { + hash: 2, + caller_contract_address: AztecAddress::from_field(1), + caller_context: CallerContext::empty(), + start_side_effect_counter: 6, + end_side_effect_counter: 0 + } + ]; + + let revertible_commitments = [ + SideEffect { value: 3, counter: 7 }, + SideEffect { value: 4, counter: 10 } + ]; + + let revertible_nullifiers = [ + SideEffectLinkedToNoteHash { value: 30, note_hash: 3, counter: 8 }, + SideEffectLinkedToNoteHash { value: 40, note_hash: 4, counter: 11 } + ]; + + let revertible_public_call_stack = [ + CallRequest { + hash: 3, + caller_contract_address: AztecAddress::from_field(3), + caller_context: CallerContext::empty(), + start_side_effect_counter: 9, + end_side_effect_counter: 0 + } + ]; + + builder.new_note_hashes.extend_from_array(non_revertible_commitments); + builder.new_note_hashes.extend_from_array(revertible_commitments); + + builder.new_nullifiers.extend_from_array(non_revertible_nullifiers); + builder.new_nullifiers.extend_from_array(revertible_nullifiers); + + builder.public_call_stack.extend_from_array(non_revertible_public_stack); + builder.public_call_stack.extend_from_array(revertible_public_call_stack); + + let (non_revertible, revertible) = builder.split_to_public(7); + + assert(array_eq(non_revertible.new_note_hashes, non_revertible_commitments)); + assert(array_eq(non_revertible.new_nullifiers, non_revertible_nullifiers)); + assert(array_eq(non_revertible.public_call_stack, non_revertible_public_stack)); + + assert(array_eq(revertible.new_note_hashes, revertible_commitments)); + assert(array_eq(revertible.new_nullifiers, revertible_nullifiers)); + assert(array_eq(revertible.public_call_stack, revertible_public_call_stack)); + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr deleted file mode 100644 index 57ea42b6faa..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_non_revertible_data.nr +++ /dev/null @@ -1,27 +0,0 @@ -use crate::{abis::{call_request::CallRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; -use crate::constants::{ - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX -}; - -struct PrivateAccumulatedNonRevertibleData { - revert_code: u8, - new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], - public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], -} - -impl PrivateAccumulatedNonRevertibleData { - pub fn needs_setup(self) -> bool { - // By definition, the final non-revertible enqueued call is for teardown. - // since this is a stack, the teardown call would be the 0th element. - // So if we have more than one element, we need setup. - !self.public_call_stack[1].is_empty() - } - - pub fn needs_teardown(self) -> bool { - // By definition, the final non-revertible enqueued call is for teardown. - // since this is a stack, the teardown call would be the 0th element. - !self.public_call_stack[0].is_empty() - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr deleted file mode 100644 index 9144bd52a22..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/private_accumulated_revertible_data.nr +++ /dev/null @@ -1,30 +0,0 @@ -use crate::{abis::{call_request::CallRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash}}}; -use crate::constants::{ - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NEW_L2_TO_L1_MSGS_PER_TX -}; - -struct PrivateAccumulatedRevertibleData { - new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], - - private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], - public_call_stack: [CallRequest; MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], - new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], - - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, - - // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the - // variable-length data. - encrypted_log_preimages_length: Field, - unencrypted_log_preimages_length: Field, -} - -impl PrivateAccumulatedRevertibleData { - pub fn needs_app_logic(self) -> bool { - // if we have any enqueued revertible public calls, we need to run the public app logic circuit. - !self.public_call_stack[0].is_empty() - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr new file mode 100644 index 00000000000..89b520392fb --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data.nr @@ -0,0 +1,28 @@ +use crate::{ + abis::{ + call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX +} +}; + +struct PublicAccumulatedData { + new_note_hashes: [SideEffect; MAX_NEW_NOTE_HASHES_PER_TX], + new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], + + encrypted_logs_hash: Field, + unencrypted_logs_hash: Field, + + // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the + // variable-length data. + encrypted_log_preimages_length: Field, + unencrypted_log_preimages_length: Field, + + public_data_update_requests: [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + + public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX], +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr new file mode 100644 index 00000000000..0740f852f32 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_data_builder.nr @@ -0,0 +1,45 @@ +use crate::{ + abis::{ + accumulated_data::public_accumulated_data::PublicAccumulatedData, call_request::CallRequest, + public_data_update_request::PublicDataUpdateRequest, + side_effect::{SideEffect, SideEffectLinkedToNoteHash} +}, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX +} +}; + +struct PublicAccumulatedDataBuilder { + new_note_hashes: BoundedVec, + new_nullifiers: BoundedVec, + new_l2_to_l1_msgs: BoundedVec, + + encrypted_logs_hash: Field, + unencrypted_logs_hash: Field, + + // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the + // variable-length data. + encrypted_log_preimages_length: Field, + unencrypted_log_preimages_length: Field, + + public_data_update_requests: BoundedVec, + + public_call_stack: BoundedVec, +} + +impl PublicAccumulatedDataBuilder { + pub fn finish(self) -> PublicAccumulatedData { + PublicAccumulatedData { + new_note_hashes: self.new_note_hashes.storage, + new_nullifiers: self.new_nullifiers.storage, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + public_data_update_requests: self.public_data_update_requests.storage, + public_call_stack: self.public_call_stack.storage + } + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr deleted file mode 100644 index 265466c9959..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_non_revertible_data.nr +++ /dev/null @@ -1,39 +0,0 @@ -use crate::{ - abis::{ - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} -} -}; -use crate::constants::{ - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX -}; - -use dep::std::unsafe; -use crate::traits::is_empty; - -use crate::utils::arrays::{array_cp, array_concat, array_to_bounded_vec}; - -struct PublicAccumulatedNonRevertibleData { - revert_code: u8, - new_note_hashes: [SideEffect; MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX], - public_call_stack: [CallRequest; MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], - public_data_update_requests: [PublicDataUpdateRequest; MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], -} - -impl PublicAccumulatedNonRevertibleData { - pub fn needs_setup(self) -> bool { - // By definition, the final non-revertible enqueued call is for teardown. - // since this is a stack, the teardown call would be the 0th element. - // So if we have more than one element, we need setup. - !self.public_call_stack[1].is_empty() - } - - pub fn needs_teardown(self) -> bool { - // By definition, the final non-revertible enqueued call is for teardown. - // since this is a stack, the teardown call would be the 0th element. - !self.public_call_stack[0].is_empty() - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr deleted file mode 100644 index fc3660b0ae1..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/accumulated_data/public_accumulated_revertible_data.nr +++ /dev/null @@ -1,37 +0,0 @@ -use crate::{ - abis::{ - call_request::CallRequest, public_data_update_request::PublicDataUpdateRequest, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} -} -}; -use crate::constants::{ - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX -}; - -struct PublicAccumulatedRevertibleData { - new_note_hashes: [SideEffect; MAX_REVERTIBLE_NOTE_HASHES_PER_TX], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_REVERTIBLE_NULLIFIERS_PER_TX], - - private_call_stack: [CallRequest; MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX], - public_call_stack: [CallRequest; MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX], - new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_TX], - - encrypted_logs_hash: Field, - unencrypted_logs_hash: Field, - - // Here so that the gas cost of this request can be measured by circuits, without actually needing to feed in the - // variable-length data. - encrypted_log_preimages_length: Field, - unencrypted_log_preimages_length: Field, - - public_data_update_requests: [PublicDataUpdateRequest; MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], -} - -impl PublicAccumulatedRevertibleData { - pub fn needs_app_logic(self) -> bool { - // if we have any enqueued revertible public calls, we need to run the public app logic circuit. - !self.public_call_stack[0].is_empty() - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr index 4ea6274011e..3d17e14fec4 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs.nr @@ -1,17 +1,13 @@ +mod kernel_circuit_public_inputs; +mod private_kernel_circuit_public_inputs; mod private_kernel_circuit_public_inputs_builder; -mod private_kernel_inner_circuit_public_inputs; -mod private_kernel_tail_circuit_public_inputs; mod public_kernel_circuit_public_inputs; mod public_kernel_circuit_public_inputs_builder; -mod rollup_kernel_circuit_public_inputs; -mod rollup_kernel_circuit_public_inputs_builder; use crate::abis::kernel_circuit_public_inputs::{ + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + private_kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, private_kernel_circuit_public_inputs_builder::PrivateKernelCircuitPublicInputsBuilder, - private_kernel_inner_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, - private_kernel_tail_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, - public_kernel_circuit_public_inputs_builder::PublicKernelCircuitPublicInputsBuilder, - rollup_kernel_circuit_public_inputs::RollupKernelCircuitPublicInputs, - rollup_kernel_circuit_public_inputs_builder::RollupKernelCircuitPublicInputsBuilder + public_kernel_circuit_public_inputs_builder::PublicKernelCircuitPublicInputsBuilder }; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr similarity index 87% rename from noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs.nr rename to noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr index 9d1c748d2da..b15b68d2365 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/kernel_circuit_public_inputs.nr @@ -2,12 +2,12 @@ use crate::abis::{ accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, validation_requests::RollupValidationRequests }; - use crate::mocked::AggregationObject; -struct RollupKernelCircuitPublicInputs { +struct KernelCircuitPublicInputs { aggregation_object: AggregationObject, + rollup_validation_requests: RollupValidationRequests, end: CombinedAccumulatedData, constants: CombinedConstantData, - rollup_validation_requests: RollupValidationRequests, + revert_code: u8, } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_inner_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr similarity index 55% rename from noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_inner_circuit_public_inputs.nr rename to noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr index e7adafbd5e3..6a30e724a3c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_inner_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs.nr @@ -1,14 +1,13 @@ use crate::abis::{ - accumulated_data::CombinedAccumulatedData, combined_constant_data::CombinedConstantData, + accumulated_data::PrivateAccumulatedData, combined_constant_data::CombinedConstantData, validation_requests::ValidationRequests }; use crate::mocked::AggregationObject; -struct PrivateKernelInnerCircuitPublicInputs { +struct PrivateKernelCircuitPublicInputs { aggregation_object: AggregationObject, min_revertible_side_effect_counter: u32, validation_requests: ValidationRequests, - end: CombinedAccumulatedData, + end: PrivateAccumulatedData, constants: CombinedConstantData, - is_private: bool, // TODO can we remove this? } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr index 927f5b5b37f..194cd7df510 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_circuit_public_inputs_builder.nr @@ -1,46 +1,54 @@ use crate::abis::{ - accumulated_data::CombinedAccumulatedDataBuilder, combined_constant_data::CombinedConstantData, + accumulated_data::PrivateAccumulatedDataBuilder, combined_constant_data::CombinedConstantData, kernel_circuit_public_inputs::{ - private_kernel_inner_circuit_public_inputs::PrivateKernelInnerCircuitPublicInputs, - private_kernel_tail_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + private_kernel_circuit_public_inputs::PrivateKernelCircuitPublicInputs, + public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs }, validation_requests::validation_requests_builder::ValidationRequestsBuilder }; - use crate::mocked::AggregationObject; +use dep::std::unsafe; struct PrivateKernelCircuitPublicInputsBuilder { aggregation_object: AggregationObject, min_revertible_side_effect_counter: u32, validation_requests: ValidationRequestsBuilder, - end: CombinedAccumulatedDataBuilder, + end: PrivateAccumulatedDataBuilder, constants: CombinedConstantData, - is_private: bool, } impl PrivateKernelCircuitPublicInputsBuilder { - pub fn to_inner(self) -> PrivateKernelInnerCircuitPublicInputs { - PrivateKernelInnerCircuitPublicInputs { + pub fn finish(self) -> PrivateKernelCircuitPublicInputs { + PrivateKernelCircuitPublicInputs { aggregation_object: self.aggregation_object, min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, validation_requests: self.validation_requests.finish(), end: self.end.finish(), + constants: self.constants + } + } + + pub fn finish_tail(self) -> KernelCircuitPublicInputs { + KernelCircuitPublicInputs { + aggregation_object: self.aggregation_object, + rollup_validation_requests: self.validation_requests.to_rollup(), + end: self.end.to_combined(), constants: self.constants, - is_private: self.is_private + revert_code: 0 } } - pub fn to_tail(self) -> PrivateKernelTailCircuitPublicInputs { - let (end_non_revertible, end) = self.end.split(self.min_revertible_side_effect_counter); - PrivateKernelTailCircuitPublicInputs { + pub fn finish_to_public(self, min_revertible_side_effect_counter: u32) -> PublicKernelCircuitPublicInputs { + let (end_non_revertible, end) = self.end.split_to_public(min_revertible_side_effect_counter); + + PublicKernelCircuitPublicInputs { aggregation_object: self.aggregation_object, + validation_requests: self.validation_requests.finish(), end_non_revertible, end, constants: self.constants, - rollup_validation_requests: self.validation_requests.to_rollup(), - needs_setup: end_non_revertible.needs_setup(), - needs_app_logic: end.needs_app_logic(), - needs_teardown: end_non_revertible.needs_teardown() + revert_code: 0 } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_tail_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_tail_circuit_public_inputs.nr deleted file mode 100644 index 9edcb52afb2..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/private_kernel_tail_circuit_public_inputs.nr +++ /dev/null @@ -1,17 +0,0 @@ -use crate::abis::{ - accumulated_data::{PrivateAccumulatedNonRevertibleData, PrivateAccumulatedRevertibleData}, - combined_constant_data::CombinedConstantData, validation_requests::RollupValidationRequests -}; - -use crate::mocked::AggregationObject; - -struct PrivateKernelTailCircuitPublicInputs { - aggregation_object: AggregationObject, - rollup_validation_requests: RollupValidationRequests, - end_non_revertible: PrivateAccumulatedNonRevertibleData, - end: PrivateAccumulatedRevertibleData, - constants: CombinedConstantData, - needs_setup: bool, - needs_app_logic: bool, - needs_teardown: bool, -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr index 31ccb566cfa..2441851f617 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs.nr @@ -1,6 +1,5 @@ use crate::abis::{ - accumulated_data::{PublicAccumulatedNonRevertibleData, PublicAccumulatedRevertibleData}, - combined_constant_data::CombinedConstantData, + accumulated_data::PublicAccumulatedData, combined_constant_data::CombinedConstantData, validation_requests::{RollupValidationRequests, ValidationRequests} }; use crate::mocked::AggregationObject; @@ -8,11 +7,28 @@ use crate::mocked::AggregationObject; struct PublicKernelCircuitPublicInputs { aggregation_object: AggregationObject, validation_requests: ValidationRequests, - rollup_validation_requests: RollupValidationRequests, - end_non_revertible: PublicAccumulatedNonRevertibleData, - end: PublicAccumulatedRevertibleData, + end_non_revertible: PublicAccumulatedData, + end: PublicAccumulatedData, constants: CombinedConstantData, - needs_setup: bool, - needs_app_logic: bool, - needs_teardown: bool, + revert_code: u8, +} + +impl PublicKernelCircuitPublicInputs { + pub fn needs_setup(self) -> bool { + // By definition, the final non-revertible enqueued call is for teardown. + // since this is a stack, the teardown call would be the 0th element. + // So if we have more than one element, we need setup. + !self.end_non_revertible.public_call_stack[1].is_empty() + } + + pub fn needs_app_logic(self) -> bool { + // if we have any enqueued revertible public calls, we need to run the public app logic circuit. + !self.end.public_call_stack[0].is_empty() + } + + pub fn needs_teardown(self) -> bool { + // By definition, the final non-revertible enqueued call is for teardown. + // since this is a stack, the teardown call would be the 0th element. + !self.end_non_revertible.public_call_stack[0].is_empty() + } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr index 96d8a0d7a75..70da6d47a1c 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/public_kernel_circuit_public_inputs_builder.nr @@ -1,37 +1,46 @@ use crate::abis::{ - accumulated_data::{AccumulatedNonRevertibleDataBuilder, AccumulatedRevertibleDataBuilder}, + accumulated_data::{CombinedAccumulatedData, PublicAccumulatedDataBuilder}, combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + kernel_circuit_public_inputs::{ + kernel_circuit_public_inputs::KernelCircuitPublicInputs, + public_kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs +}, validation_requests::ValidationRequestsBuilder }; - use crate::mocked::AggregationObject; struct PublicKernelCircuitPublicInputsBuilder { aggregation_object: AggregationObject, validation_requests: ValidationRequestsBuilder, - end_non_revertible: AccumulatedNonRevertibleDataBuilder, - end: AccumulatedRevertibleDataBuilder, + end_non_revertible: PublicAccumulatedDataBuilder, + end: PublicAccumulatedDataBuilder, constants: CombinedConstantData, + revert_code: u8, } impl PublicKernelCircuitPublicInputsBuilder { - pub fn to_inner(self) -> PublicKernelCircuitPublicInputs { - let end_non_revertible = self.end_non_revertible.to_public(); - let end = self.end.to_public(); + pub fn finish(self) -> PublicKernelCircuitPublicInputs { PublicKernelCircuitPublicInputs { aggregation_object: self.aggregation_object, // Note that we're including both the validation_requests AND the rollup_validation requests, because this // struct is used as an input for both the public kernel and base rollup circuits. In the near future the // base rollup will only receive rollup_validation_requests, and the public kernel only validation_requests. validation_requests: self.validation_requests.finish(), + end_non_revertible: self.end_non_revertible.finish(), + end: self.end.finish(), + constants: self.constants, + revert_code: self.revert_code + } + } + + pub fn finish_tail(self) -> KernelCircuitPublicInputs { + KernelCircuitPublicInputs { + aggregation_object: self.aggregation_object, rollup_validation_requests: self.validation_requests.to_rollup(), - end_non_revertible, - end, + // TODO: Sort by counters. + end: CombinedAccumulatedData::recombine(self.end_non_revertible.finish(), self.end.finish()), constants: self.constants, - needs_setup: end_non_revertible.needs_setup(), - needs_app_logic: end.needs_app_logic(), - needs_teardown: end_non_revertible.needs_teardown() + revert_code: self.revert_code } } } diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs_builder.nr deleted file mode 100644 index ed8ca7f6990..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_circuit_public_inputs/rollup_kernel_circuit_public_inputs_builder.nr +++ /dev/null @@ -1,25 +0,0 @@ -use crate::abis::{ - accumulated_data::CombinedAccumulatedDataBuilder, combined_constant_data::CombinedConstantData, - kernel_circuit_public_inputs::rollup_kernel_circuit_public_inputs::RollupKernelCircuitPublicInputs, - validation_requests::RollupValidationRequests -}; - -use crate::mocked::AggregationObject; - -struct RollupKernelCircuitPublicInputsBuilder { - aggregation_object: AggregationObject, - end: CombinedAccumulatedDataBuilder, - constants: CombinedConstantData, - rollup_validation_requests: RollupValidationRequests, -} - -impl RollupKernelCircuitPublicInputsBuilder { - pub fn finish(self) -> RollupKernelCircuitPublicInputs { - RollupKernelCircuitPublicInputs { - aggregation_object: self.aggregation_object, - end: self.end.finish(), - constants: self.constants, - rollup_validation_requests: self.rollup_validation_requests - } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr index 832a728cb34..f0dd35e98b1 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/abis/kernel_data.nr @@ -1,14 +1,11 @@ use crate::mocked::{Proof, VerificationKey}; use crate::constants::VK_TREE_HEIGHT; -use crate::abis::kernel_circuit_public_inputs::{ - PrivateKernelInnerCircuitPublicInputs, PublicKernelCircuitPublicInputs, - RollupKernelCircuitPublicInputs -}; +use crate::abis::kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs, KernelCircuitPublicInputs}; -struct PrivateKernelInnerData { +struct PrivateKernelData { // TODO(David): Left a note asking if we need this due to it // already being in the proof. - public_inputs : PrivateKernelInnerCircuitPublicInputs, + public_inputs: PrivateKernelCircuitPublicInputs, // TODO(David): Mentions the dichotomy between a proof created for the // circuit, which is a sequence of field elements, versus a proof @@ -17,28 +14,28 @@ struct PrivateKernelInnerData { // It makes verification cheaper, though I have not tested how much cheaper. // Removing it would also reduce complexity on the Noir side, as we have // special methods to convert "inner proofs" into sequence of field elements. - proof : Proof, + proof: Proof, - vk : VerificationKey, + vk: VerificationKey, // TODO(Mike): left a note saying : this index and path are meant to be those of a leaf within the tree of _kernel circuit_ vks; not the tree // of functions within the contract tree. - vk_index : u32, - vk_path : [Field; VK_TREE_HEIGHT], + vk_index: u32, + vk_path: [Field; VK_TREE_HEIGHT], } struct PublicKernelData { - public_inputs : PublicKernelCircuitPublicInputs, - proof : Proof, - vk : VerificationKey, - vk_index : u32, - vk_path : [Field; VK_TREE_HEIGHT], + public_inputs: PublicKernelCircuitPublicInputs, + proof: Proof, + vk: VerificationKey, + vk_index: u32, + vk_path: [Field; VK_TREE_HEIGHT], } -struct RollupKernelData { - public_inputs : RollupKernelCircuitPublicInputs, - proof : Proof, - vk : VerificationKey, - vk_index : u32, - vk_path : [Field; VK_TREE_HEIGHT], +struct KernelData { + public_inputs: KernelCircuitPublicInputs, + proof: Proof, + vk: VerificationKey, + vk_index: u32, + vk_path: [Field; VK_TREE_HEIGHT], } 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 2fec9bce466..04932d9ecf3 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -37,25 +37,11 @@ global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: u64 = 1; // "PER TRANSACTION" CONSTANTS global MAX_NEW_NOTE_HASHES_PER_TX: u64 = 64; -global MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX: u64 = 8; -global MAX_REVERTIBLE_NOTE_HASHES_PER_TX: u64 = 56; - global MAX_NEW_NULLIFIERS_PER_TX: u64 = 64; -global MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX: u64 = 8; -global MAX_REVERTIBLE_NULLIFIERS_PER_TX: u64 = 56; - global MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: u64 = 8; - global MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: u64 = 8; -global MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX: u64 = 3; -global MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX: u64 = 5; - global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u64 = 32; -global MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u64 = 16; -global MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: u64 = 16; - global MAX_PUBLIC_DATA_READS_PER_TX: u64 = 32; - global MAX_NEW_L2_TO_L1_MSGS_PER_TX: u64 = 2; global MAX_NOTE_HASH_READ_REQUESTS_PER_TX: u64 = 128; global MAX_NULLIFIER_READ_REQUESTS_PER_TX: u64 = 8; // Change it to a larger value when there's a seperate reset circuit. diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/keys.nr b/noir-projects/noir-protocol-circuits/crates/types/src/keys.nr new file mode 100644 index 00000000000..0e93ffe7841 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/keys.nr @@ -0,0 +1,26 @@ +use crate::{address::AztecAddress, grumpkin_private_key::GrumpkinPrivateKey, hash::pedersen_hash}; + +fn field_to_grumpkin_private_key(val: Field) -> GrumpkinPrivateKey { + let bytes = val.to_be_bytes(32); + let mut v = 1; + let mut high = 0; + let mut low = 0; + + for i in 0..16 { + high = high + (bytes[15 - i] as Field) * v; + low = low + (bytes[16 + 15 - i] as Field) * v; + v = v * 256; + } + + GrumpkinPrivateKey { high, low } +} + +pub fn compute_siloed_nullifier_secret_key(secret_key: GrumpkinPrivateKey, contract_address: AztecAddress) -> GrumpkinPrivateKey { + // TODO: Temporary hack. Should replace it with a secure way to derive the secret key. + // Match the way keys are derived in circuits.js/src/keys/index.ts + let hash = pedersen_hash( + [secret_key.high, secret_key.low, contract_address.to_field()], + 0 + ); + field_to_grumpkin_private_key(hash) +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr index dd16fb45338..f9c986ba0de 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/lib.nr @@ -12,6 +12,7 @@ mod constants; mod contract_class_id; mod merkle_tree; mod contract_instance; +mod keys; mod messaging; mod mocked; @@ -29,7 +30,4 @@ mod partial_state_reference; mod public_data_tree_leaf; mod public_data_tree_leaf_preimage; -use abis::kernel_circuit_public_inputs::{ - PrivateKernelInnerCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, - PublicKernelCircuitPublicInputs, RollupKernelCircuitPublicInputs -}; +use abis::kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr index 77f7f32bc6d..0defe42f5bd 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests.nr @@ -1,6 +1,6 @@ mod testing_harness; +mod fixture_builder; mod fixtures; -mod kernel_data_builder; mod merkle_tree_utils; mod private_call_data_builder; mod private_circuit_public_inputs_builder; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr new file mode 100644 index 00000000000..4fa846432b5 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/crates/types/src/tests/fixture_builder.nr @@ -0,0 +1,380 @@ +use crate::{ + abis::{ + call_context::CallContext, call_request::{CallerContext, CallRequest}, + accumulated_data::{ + CombinedAccumulatedData, CombinedAccumulatedDataBuilder, PrivateAccumulatedData, + PrivateAccumulatedDataBuilder, PublicAccumulatedData, PublicAccumulatedDataBuilder +}, + combined_constant_data::CombinedConstantData, + kernel_circuit_public_inputs::{KernelCircuitPublicInputs, PrivateKernelCircuitPublicInputs, PublicKernelCircuitPublicInputs}, + kernel_data::{PrivateKernelData, PublicKernelData, KernelData}, max_block_number::MaxBlockNumber, + nullifier_key_validation_request::NullifierKeyValidationRequestContext, + public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, + read_request::ReadRequestContext, side_effect::{SideEffect, SideEffectLinkedToNoteHash}, + validation_requests::{ValidationRequests, ValidationRequestsBuilder} +}, + address::AztecAddress, + constants::{ + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_READ_REQUESTS_PER_TX, + MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, + VK_TREE_HEIGHT +}, + hash::silo_nullifier, header::Header, mocked::{AggregationObject, Proof, VerificationKey}, + tests::fixtures, transaction::tx_context::TxContext +}; +use dep::std::unsafe; + +struct FixtureBuilder { + contract_address: AztecAddress, + storage_contract_address: AztecAddress, + + // Constant data. + historical_header: Header, + tx_context: TxContext, + + // Accumulated data. + new_note_hashes: BoundedVec, + new_nullifiers: BoundedVec, + new_l2_to_l1_msgs: BoundedVec, + encrypted_logs_hash: Field, + unencrypted_logs_hash: Field, + encrypted_log_preimages_length: Field, + unencrypted_log_preimages_length: Field, + public_data_update_requests: BoundedVec, + private_call_stack: BoundedVec, + public_call_stack: BoundedVec, + + // Validation requests. + max_block_number: MaxBlockNumber, + note_hash_read_requests: BoundedVec, + nullifier_read_requests: BoundedVec, + nullifier_non_existent_read_requests: BoundedVec, + nullifier_key_validation_requests: BoundedVec, + public_data_reads: BoundedVec, + + // Proof. + proof: Proof, + vk: VerificationKey, + vk_index: u32, + vk_path: [Field; VK_TREE_HEIGHT], + revert_code: u8, + + // Counters. + min_revertible_side_effect_counter: u32, + counter: u32, +} + +impl FixtureBuilder { + pub fn new() -> Self { + let tx_context = TxContext { is_fee_payment_tx: false, is_rebate_payment_tx: false, chain_id: 1, version: 0 }; + + FixtureBuilder { + contract_address: fixtures::contracts::parent_contract.address, + storage_contract_address: fixtures::contracts::parent_contract.address, + historical_header: fixtures::HEADER, + tx_context, + new_note_hashes: BoundedVec::new(), + new_nullifiers: BoundedVec::new(), + new_l2_to_l1_msgs: BoundedVec::new(), + encrypted_logs_hash: 0, + unencrypted_logs_hash: 0, + encrypted_log_preimages_length: 0, + unencrypted_log_preimages_length: 0, + public_data_update_requests: BoundedVec::new(), + private_call_stack: BoundedVec::new(), + public_call_stack: BoundedVec::new(), + max_block_number: MaxBlockNumber::default(), + note_hash_read_requests: BoundedVec::new(), + nullifier_read_requests: BoundedVec::new(), + nullifier_non_existent_read_requests: BoundedVec::new(), + nullifier_key_validation_requests: BoundedVec::new(), + public_data_reads: BoundedVec::new(), + proof: Proof {}, + vk: VerificationKey {}, + vk_index: 0, + vk_path: [0; VK_TREE_HEIGHT], + revert_code: 0, + min_revertible_side_effect_counter: 0, + counter: 0 + } + } + + pub fn to_constant_data(self) -> CombinedConstantData { + CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context } + } + + pub fn to_private_accumulated_data(self) -> PrivateAccumulatedData { + let public_inputs = PrivateAccumulatedDataBuilder { + new_note_hashes: self.new_note_hashes, + new_nullifiers: self.new_nullifiers, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + private_call_stack: self.private_call_stack, + public_call_stack: self.public_call_stack + }; + public_inputs.finish() + } + + pub fn to_public_accumulated_data(self) -> PublicAccumulatedData { + let public_inputs = PublicAccumulatedDataBuilder { + new_note_hashes: self.new_note_hashes, + new_nullifiers: self.new_nullifiers, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + public_data_update_requests: self.public_data_update_requests, + public_call_stack: self.public_call_stack + }; + public_inputs.finish() + } + + pub fn to_combined_accumulated_data(self) -> CombinedAccumulatedData { + let public_inputs = CombinedAccumulatedDataBuilder { + new_note_hashes: self.new_note_hashes, + new_nullifiers: self.new_nullifiers, + new_l2_to_l1_msgs: self.new_l2_to_l1_msgs, + encrypted_logs_hash: self.encrypted_logs_hash, + unencrypted_logs_hash: self.unencrypted_logs_hash, + encrypted_log_preimages_length: self.encrypted_log_preimages_length, + unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, + public_data_update_requests: self.public_data_update_requests + }; + public_inputs.finish() + } + + pub fn to_validation_requests(self) -> ValidationRequests { + let validation_requests = ValidationRequestsBuilder { + max_block_number: self.max_block_number, + note_hash_read_requests: self.note_hash_read_requests, + nullifier_read_requests: self.nullifier_read_requests, + nullifier_non_existent_read_requests: self.nullifier_non_existent_read_requests, + nullifier_key_validation_requests: self.nullifier_key_validation_requests, + public_data_reads: self.public_data_reads + }; + validation_requests.finish() + } + + pub fn to_private_circuit_public_inputs(self) -> PrivateKernelCircuitPublicInputs { + let end = self.to_private_accumulated_data(); + let validation_requests = self.to_validation_requests(); + let constants = self.to_constant_data(); + + PrivateKernelCircuitPublicInputs { + aggregation_object: AggregationObject {}, + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, + end, + validation_requests, + constants + } + } + + pub fn to_private_kernel_data(self) -> PrivateKernelData { + let public_inputs = self.to_private_circuit_public_inputs(); + PrivateKernelData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } + } + + pub fn to_public_kernel_circuit_public_inputs(self, revertible: bool) -> PublicKernelCircuitPublicInputs { + let accumulated_data = self.to_public_accumulated_data(); + let end_non_revertible = if revertible { + unsafe::zeroed() + } else { + accumulated_data + }; + let end = if revertible { + accumulated_data + } else { + unsafe::zeroed() + }; + let validation_requests = self.to_validation_requests(); + let constants = self.to_constant_data(); + + PublicKernelCircuitPublicInputs { + aggregation_object: AggregationObject {}, + end_non_revertible, + end, + validation_requests, + constants, + revert_code: self.revert_code + } + } + + pub fn to_public_kernel_data(self, revertible: bool) -> PublicKernelData { + let public_inputs = self.to_public_kernel_circuit_public_inputs(revertible); + PublicKernelData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } + } + + pub fn to_kernel_circuit_public_inputs(self) -> KernelCircuitPublicInputs { + let rollup_validation_requests = self.to_validation_requests().for_rollup; + let end = self.to_combined_accumulated_data(); + let constants = self.to_constant_data(); + + KernelCircuitPublicInputs { + aggregation_object: AggregationObject {}, + rollup_validation_requests, + end, + constants, + revert_code: self.revert_code + } + } + + pub fn to_kernel_data(self) -> KernelData { + let public_inputs = self.to_kernel_circuit_public_inputs(); + KernelData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } + } + + pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u64) { + let mocked_value_offset = self.new_note_hashes.len() + 1; + for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { + if i < num_new_note_hashes { + // The default value is its index + 1. + self.new_note_hashes.push( + SideEffect { value: (i + mocked_value_offset) as Field, counter: self.next_counter() } + ); + } + } + } + + pub fn add_nullifier(&mut self, unsiloed_nullifier: Field) { + let value = silo_nullifier(self.storage_contract_address, unsiloed_nullifier); + self.new_nullifiers.push(SideEffectLinkedToNoteHash { value, note_hash: 0, counter: self.next_counter() }); + } + + pub fn append_new_nullifiers(&mut self, num_extra_nullifier: u64) { + let index_offset = self.new_nullifiers.len(); + for i in 0..MAX_NEW_NULLIFIERS_PER_TX { + if i < num_extra_nullifier { + let mock_value = self.get_mock_nullifier_value(index_offset + i); + self.add_nullifier(mock_value); + } + } + } + + pub fn append_public_data_update_requests(&mut self, num_updates: u64) { + let value_offset = self.public_data_update_requests.len(); + for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + if i < num_updates { + let update_request = PublicDataUpdateRequest { + // The default leaf index is its index + 23. + leaf_slot: (value_offset + i + 23) as Field, + // The default value is its index + 678. + new_value: (value_offset + i + 678) as Field + }; + self.public_data_update_requests.push(update_request); + } + } + } + + pub fn append_public_data_read_requests(&mut self, num_reads: u64) { + let value_offset = self.public_data_reads.len(); + for i in 0..MAX_PUBLIC_DATA_READS_PER_TX { + if i < num_reads { + let read_request = PublicDataRead { + // The default leaf index is its index + 34. + leaf_slot: (value_offset + i + 34) as Field, + // The default value is its index + 5566. + value: (value_offset + i + 5566) as Field + }; + self.public_data_reads.push(read_request); + } + } + } + + pub fn add_read_request_for_pending_note_hash(&mut self, note_hash_index: u64) -> u64 { + let new_read_request_index = self.note_hash_read_requests.len(); + let note_hash = self.new_note_hashes.get(note_hash_index); + let read_request = SideEffect { value: note_hash.value, counter: self.next_counter() }; + self.note_hash_read_requests.push(read_request); + new_read_request_index + } + + pub fn add_read_request_for_pending_nullifier(&mut self, nullifier_index: u64) -> u64 { + let read_request_index = self.nullifier_read_requests.len(); + let unsiloed_nullifier = self.get_mock_nullifier_value(nullifier_index); + let read_request = ReadRequestContext { + value: unsiloed_nullifier, + counter: self.next_counter(), + contract_address: self.storage_contract_address + }; + self.nullifier_read_requests.push(read_request); + read_request_index + } + + pub fn add_non_existent_read_request_for_nullifier(&mut self, unsiloed_nullifier: Field) { + let read_request = ReadRequestContext { + value: unsiloed_nullifier, + counter: self.next_counter(), + contract_address: self.storage_contract_address + }; + self.nullifier_non_existent_read_requests.push(read_request); + } + + pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { + self.encrypted_logs_hash = hash; + self.encrypted_log_preimages_length = preimages_length; + } + + pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { + self.unencrypted_logs_hash = hash; + self.unencrypted_log_preimages_length = preimages_length; + } + + pub fn push_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { + let call_stack_item = self.generate_call_request(hash, is_delegate_call); + self.private_call_stack.push(call_stack_item); + } + + pub fn push_public_call_request(&mut self, hash: Field, is_delegate_call: bool) { + let call_stack_item = self.generate_call_request(hash, is_delegate_call); + self.public_call_stack.push(call_stack_item); + } + + pub fn capture_min_revertible_side_effect_counter(&mut self) { + self.min_revertible_side_effect_counter = self.counter; + } + + pub fn set_max_block_number(&mut self, max_block_number: u32) { + self.max_block_number = MaxBlockNumber::new(max_block_number); + } + + fn generate_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { + let mut caller_context = CallerContext::empty(); + if is_delegate_call { + caller_context.msg_sender = fixtures::MSG_SENDER; + caller_context.storage_contract_address = self.contract_address; + } + let start_counter = self.next_counter(); + let end_counter = start_counter + 10; + self.counter = end_counter; + CallRequest { + hash, + caller_contract_address: self.contract_address, + caller_context, + start_side_effect_counter: start_counter, + end_side_effect_counter: end_counter + } + } + + fn get_mock_nullifier_value(_self: Self, nullifier_index: u64) -> Field { + let value_offset = 5678; + value_offset + nullifier_index as Field + } + + fn get_mock_nullifier_value_non_revertible(_self: Self, nullifier_index: u64) -> Field { + let value_offset = 987; + value_offset + nullifier_index as Field + } + + fn next_counter(&mut self) -> u32 { + let counter = self.counter; + self.counter += 1; + counter + } +} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/tests/kernel_data_builder.nr b/noir-projects/noir-protocol-circuits/crates/types/src/tests/kernel_data_builder.nr deleted file mode 100644 index cee46c22a55..00000000000 --- a/noir-projects/noir-protocol-circuits/crates/types/src/tests/kernel_data_builder.nr +++ /dev/null @@ -1,320 +0,0 @@ -use crate::{ - abis::{ - call_context::CallContext, call_request::{CallerContext, CallRequest}, - combined_constant_data::CombinedConstantData, - accumulated_data::{CombinedAccumulatedDataBuilder, AccumulatedNonRevertibleDataBuilder, AccumulatedRevertibleDataBuilder}, - kernel_circuit_public_inputs::{ - PrivateKernelInnerCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, - PublicKernelCircuitPublicInputs, RollupKernelCircuitPublicInputs -}, - kernel_data::{PrivateKernelInnerData, PublicKernelData, RollupKernelData}, - max_block_number::MaxBlockNumber, public_data_read::PublicDataRead, - public_data_update_request::PublicDataUpdateRequest, read_request::ReadRequestContext, - side_effect::{SideEffect, SideEffectLinkedToNoteHash}, - validation_requests::ValidationRequestsBuilder -}, - address::{AztecAddress, EthAddress}, header::Header, hash::silo_nullifier, - mocked::{AggregationObject, Proof, VerificationKey}, - tests::{fixtures, testing_harness::build_tx_context}, transaction::tx_context::TxContext -}; -use crate::constants::{ - MAX_NEW_NOTE_HASHES_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, VK_TREE_HEIGHT -}; -use dep::std::unsafe; - -struct PreviousKernelDataBuilder { - contract_address: AztecAddress, - storage_contract_address: AztecAddress, - portal_contract_address: EthAddress, - validation_requests: ValidationRequestsBuilder, - end: CombinedAccumulatedDataBuilder, - end_non_revertible: AccumulatedNonRevertibleDataBuilder, - historical_header: Header, - tx_context: TxContext, - is_private: bool, - proof: Proof, - vk: VerificationKey, - vk_index: u32, - vk_path: [Field; VK_TREE_HEIGHT], - sideffect_counter: u32, - min_revertible_side_effect_counter: u32, -} - -impl PreviousKernelDataBuilder { - pub fn new(is_for_public: bool) -> Self { - let mut end: CombinedAccumulatedDataBuilder = dep::std::unsafe::zeroed(); - let mut end_non_revertible: AccumulatedNonRevertibleDataBuilder = dep::std::unsafe::zeroed(); - // 0th nullifier must be non-zero. - let tx_nullifier = SideEffectLinkedToNoteHash { value: 321, note_hash: 0, counter: 0 }; - // but the public kernels expect this first nullifier to have been partitioned into - // the non-revertible set - - if is_for_public == true { - end_non_revertible.new_nullifiers.push(tx_nullifier); - } else { - end.new_nullifiers.push(tx_nullifier); - } - - let tx_context = build_tx_context(); - - PreviousKernelDataBuilder { - contract_address: fixtures::contracts::parent_contract.address, - storage_contract_address: fixtures::contracts::parent_contract.address, - portal_contract_address: fixtures::contracts::parent_contract.portal_contract_address, - validation_requests: unsafe::zeroed(), - end, - end_non_revertible, - historical_header: fixtures::HEADER, - tx_context, - is_private: true, - proof: Proof {}, - vk: VerificationKey {}, - vk_index: 0, - vk_path: [0; VK_TREE_HEIGHT], - sideffect_counter: 2, - min_revertible_side_effect_counter: 2 - } - } - - pub fn is_public(&mut self) -> Self { - self.is_private = false; - *self - } - - pub fn set_max_block_number(&mut self, max_block_number: u32) { - self.validation_requests.max_block_number = MaxBlockNumber::new(max_block_number); - } - - pub fn append_public_data_update_requests(&mut self, num_updates: u64) { - let value_offset = self.end.public_data_update_requests.len(); - for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { - if i < num_updates { - let update_request = PublicDataUpdateRequest { - // The default leaf index is its index + 23. - leaf_slot: (value_offset + i + 23) as Field, - // The default value is its index + 678. - new_value: (value_offset + i + 678) as Field - }; - self.end.public_data_update_requests.push(update_request); - } - } - } - - pub fn append_public_data_read_requests(&mut self, num_reads: u64) { - let value_offset = self.validation_requests.public_data_reads.len(); - for i in 0..MAX_PUBLIC_DATA_READS_PER_TX { - if i < num_reads { - let read_request = PublicDataRead { - // The default leaf index is its index + 34. - leaf_slot: (value_offset + i + 34) as Field, - // The default value is its index + 5566. - value: (value_offset + i + 5566) as Field - }; - self.validation_requests.public_data_reads.push(read_request); - } - } - } - - fn next_sideffect_counter(&mut self) -> u32 { - let counter = self.sideffect_counter; - self.sideffect_counter += 1; - counter - } - - pub fn add_read_request_for_transient_commitment(&mut self, commitment_index: u64) -> u64 { - let new_read_request_index = self.validation_requests.note_hash_read_requests.len(); - let commitment = self.end.new_note_hashes.get(commitment_index); - let read_request = SideEffect { value: commitment.value, counter: self.next_sideffect_counter() }; - self.validation_requests.note_hash_read_requests.push(read_request); - new_read_request_index - } - - pub fn append_new_note_hashes(&mut self, num_new_note_hashes: u64) { - let mocked_value_offset = self.end.new_note_hashes.len() + 1; - for i in 0..MAX_NEW_NOTE_HASHES_PER_TX { - if i < num_new_note_hashes { - // The default value is its index + 1. - self.end.new_note_hashes.push( - SideEffect { value: (i + mocked_value_offset) as Field, counter: self.next_sideffect_counter() } - ); - } - } - } - - fn get_mock_nullifier_value(_self: Self, nullifier_index: u64) -> Field { - let value_offset = 5678; - value_offset + nullifier_index as Field - } - - fn get_mock_nullifier_value_non_revertible(_self: Self, nullifier_index: u64) -> Field { - let value_offset = 987; - value_offset + nullifier_index as Field - } - - pub fn add_nullifier(&mut self, unsiloed_nullifier: Field) { - let value = silo_nullifier(self.storage_contract_address, unsiloed_nullifier); - self.end.new_nullifiers.push(SideEffectLinkedToNoteHash { value, note_hash: 0, counter: self.next_sideffect_counter() }); - } - - pub fn add_nullifier_non_revertible(&mut self, unsiloed_nullifier: Field) { - let value = silo_nullifier(self.storage_contract_address, unsiloed_nullifier); - self.end_non_revertible.new_nullifiers.push(SideEffectLinkedToNoteHash { value, note_hash: 0, counter: self.next_sideffect_counter() }); - } - - pub fn append_new_nullifiers_from_private(&mut self, num_extra_nullifier: u64) { - // in private kernel, the nullifiers have not yet been partitioned - // (that is part of the job of the private kernel tail) - // so the tx nullifier is in `end` - let index_offset = self.end.new_nullifiers.len(); - for i in 0..MAX_NEW_NULLIFIERS_PER_TX { - if i < num_extra_nullifier { - let mock_value = self.get_mock_nullifier_value(index_offset + i); - self.add_nullifier(mock_value); - } - } - } - - pub fn append_new_nullifiers_from_public(&mut self, num_extra_nullifier: u64) { - let index_offset = self.end.new_nullifiers.len(); - for i in 0..MAX_NEW_NULLIFIERS_PER_TX { - if i < num_extra_nullifier { - let mock_value = self.get_mock_nullifier_value(index_offset + i); - self.add_nullifier(mock_value); - } - } - } - - pub fn append_new_nullifiers_non_revertible_from_public(&mut self, num_extra_nullifier: u64) { - let index_offset = self.end_non_revertible.new_nullifiers.len(); - for i in 0..MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX { - if i < num_extra_nullifier { - let mock_value = self.get_mock_nullifier_value_non_revertible(index_offset + i); - self.add_nullifier_non_revertible(mock_value); - } - } - } - - pub fn add_read_request_for_pending_nullifier(&mut self, nullifier_index: u64) -> u64 { - let read_request_index = self.validation_requests.nullifier_read_requests.len(); - let unsiloed_nullifier = self.get_mock_nullifier_value(nullifier_index); - let read_request = ReadRequestContext { - value: unsiloed_nullifier, - counter: self.next_sideffect_counter(), - contract_address: self.storage_contract_address - }; - self.validation_requests.nullifier_read_requests.push(read_request); - read_request_index - } - - pub fn add_read_request_for_pending_non_revertible_nullifier(&mut self, nullifier_index: u64) -> u64 { - let read_request_index = self.validation_requests.nullifier_read_requests.len(); - let unsiloed_nullifier = self.get_mock_nullifier_value_non_revertible(nullifier_index); - let read_request = ReadRequestContext { - value: unsiloed_nullifier, - counter: self.next_sideffect_counter(), - contract_address: self.storage_contract_address - }; - self.validation_requests.nullifier_read_requests.push(read_request); - read_request_index - } - - pub fn add_non_existent_read_request_for_nullifier(&mut self, unsiloed_nullifier: Field) { - let read_request = ReadRequestContext { - value: unsiloed_nullifier, - counter: self.next_sideffect_counter(), - contract_address: self.storage_contract_address - }; - self.validation_requests.nullifier_non_existent_read_requests.push(read_request); - } - - // snapshot the side effects - // this is useful in the private tail circuit to test side effect splitting - pub fn capture_min_revertible_side_effect_counter(&mut self) { - self.min_revertible_side_effect_counter = self.sideffect_counter; - } - - pub fn set_encrypted_logs(&mut self, hash: Field, preimages_length: Field) { - self.end.encrypted_logs_hash = hash; - self.end.encrypted_log_preimages_length = preimages_length; - } - - pub fn set_unencrypted_logs(&mut self, hash: Field, preimages_length: Field) { - self.end.unencrypted_logs_hash = hash; - self.end.unencrypted_log_preimages_length = preimages_length; - } - - pub fn push_private_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); - self.end.private_call_stack.push(call_stack_item); - } - - pub fn push_public_call_request(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); - self.end.public_call_stack.push(call_stack_item); - } - - pub fn push_public_call_request_non_revertible(&mut self, hash: Field, is_delegate_call: bool) { - let call_stack_item = self.generate_call_request(hash, is_delegate_call); - self.end_non_revertible.public_call_stack.push(call_stack_item); - } - - fn generate_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { - let mut caller_context = CallerContext::empty(); - if is_delegate_call { - caller_context.msg_sender = fixtures::MSG_SENDER; - caller_context.storage_contract_address = self.contract_address; - } - let counter = self.next_sideffect_counter(); - let end_counter = counter + 10; - self.sideffect_counter = end_counter; - CallRequest { - hash, - caller_contract_address: self.contract_address, - caller_context, - start_side_effect_counter: counter, - end_side_effect_counter: end_counter - } - } - - pub fn to_private_kernel_inner_data(self) -> PrivateKernelInnerData { - let public_inputs = PrivateKernelInnerCircuitPublicInputs { - aggregation_object: AggregationObject {}, - min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, - end: self.end.finish(), - validation_requests: self.validation_requests.finish(), - constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, - is_private: self.is_private - }; - PrivateKernelInnerData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } - } - - pub fn to_public_kernel_data(self) -> PublicKernelData { - let end_non_revertible = self.end_non_revertible.to_public(); - let end = self.end.to_public_accumulated_revertible_data(); - let public_inputs = PublicKernelCircuitPublicInputs { - aggregation_object: AggregationObject {}, - end_non_revertible, - end, - validation_requests: self.validation_requests.finish(), - rollup_validation_requests: self.validation_requests.to_rollup(), - constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, - needs_setup: end_non_revertible.needs_setup(), - needs_app_logic: end.needs_app_logic(), - needs_teardown: end_non_revertible.needs_teardown() - }; - - PublicKernelData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } - } - - pub fn to_rollup_kernel_data(self) -> RollupKernelData { - let public_inputs = RollupKernelCircuitPublicInputs { - aggregation_object: AggregationObject {}, - end: self.end.finish(), - constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, - rollup_validation_requests: self.validation_requests.to_rollup() - }; - - RollupKernelData { public_inputs, proof: self.proof, vk: self.vk, vk_index: self.vk_index, vk_path: self.vk_path } - } -} diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr index 73af12d2969..076d1e97a7e 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/utils/arrays.nr @@ -75,25 +75,6 @@ pub fn array_cp(array: [T; N]) -> [T; S] where T: Empty { result } -pub fn array_concat(array1: [T; N], array2: [T; S]) -> [T; M] where T: Empty + Eq { - assert(N + S <= M, "combined array length exceeds length of return array"); - let mut result: [T; M] = [T::empty(); M]; - let mut i = 0; - for elem in array1 { - if !is_empty(elem) { - result[i] = elem; - i += 1; - } - } - for elem in array2 { - if !is_empty(elem) { - result[i] = elem; - i += 1; - } - } - result -} - pub fn array_merge(array1: [T; N], array2: [T; N]) -> [T; N] where T: Empty + Eq { let mut result: [T; N] = [T::empty(); N]; let mut i = 0; diff --git a/yarn-project/circuit-types/src/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index 760128c49ef..60f9e378c2c 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -2,22 +2,23 @@ import { AztecAddress, CallRequest, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + PartialPrivateTailPublicInputsForPublic, + PrivateKernelTailCircuitPublicInputs, Proof, + SideEffectLinkedToNoteHash, computeContractClassId, getContractClassFromArtifact, } from '@aztec/circuits.js'; +import { makePublicCallRequest } from '@aztec/circuits.js/testing'; import { type ContractArtifact, type DecodedReturn } from '@aztec/foundation/abi'; import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto'; import { Fr } from '@aztec/foundation/fields'; -import { type Tuple } from '@aztec/foundation/serialize'; import { type ContractInstanceWithAddress, SerializableContractInstance } from '@aztec/types/contracts'; import { EncryptedL2Log } from './logs/encrypted_l2_log.js'; import { EncryptedFunctionL2Logs, EncryptedTxL2Logs, Note, UnencryptedTxL2Logs } from './logs/index.js'; -import { makePrivateKernelTailCircuitPublicInputs, makePublicCallRequest } from './mocks_to_purge.js'; import { ExtendedNote } from './notes/index.js'; import { SimulatedTx, Tx, TxHash } from './tx/index.js'; @@ -31,31 +32,66 @@ export function makeEmptyLogs(): EncryptedTxL2Logs { export const randomTxHash = (): TxHash => new TxHash(randomBytes(32)); -export const mockTx = (seed = 1, logs = true) => { - const tx = new Tx( - makePrivateKernelTailCircuitPublicInputs(seed), - new Proof(Buffer.alloc(0)), - logs ? EncryptedTxL2Logs.random(8, 3) : EncryptedTxL2Logs.empty(), // 8 priv function invocations creating 3 encrypted logs each - logs ? UnencryptedTxL2Logs.random(11, 2) : UnencryptedTxL2Logs.empty(), // 8 priv + 3 pub function invocations creating 2 unencrypted logs each - times(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makePublicCallRequest), - ); - - tx.data.endNonRevertibleData.publicCallStack = [ - tx.enqueuedPublicFunctionCalls[1].toCallRequest(), - tx.enqueuedPublicFunctionCalls[0].toCallRequest(), - CallRequest.empty(), - ]; - - tx.data.end.publicCallStack = makeTuple( - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - i => tx.enqueuedPublicFunctionCalls[i + 2]?.toCallRequest() ?? CallRequest.empty(), - ).reverse() as Tuple; +export const mockTx = ( + seed = 1, + { + hasLogs = false, + numberOfNonRevertiblePublicCallRequests = MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX / 2, + numberOfRevertiblePublicCallRequests = MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX / 2, + }: { + hasLogs?: boolean; + numberOfNonRevertiblePublicCallRequests?: number; + numberOfRevertiblePublicCallRequests?: number; + } = {}, +) => { + const totalPublicCallRequests = numberOfNonRevertiblePublicCallRequests + numberOfRevertiblePublicCallRequests; + const publicCallRequests = times(totalPublicCallRequests, i => makePublicCallRequest(seed + 0x100 + i)); + + const isForPublic = totalPublicCallRequests > 0; + const data = PrivateKernelTailCircuitPublicInputs.empty(); + const firstNullifier = new SideEffectLinkedToNoteHash(new Fr(seed), new Fr(seed + 1), Fr.ZERO); + + if (isForPublic) { + data.forRollup = undefined; + data.forPublic = PartialPrivateTailPublicInputsForPublic.empty(); + + data.forPublic.endNonRevertibleData.newNullifiers[0] = firstNullifier; + + data.forPublic.endNonRevertibleData.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, i => + i < numberOfNonRevertiblePublicCallRequests ? publicCallRequests[i].toCallRequest() : CallRequest.empty(), + ); + + data.forPublic.end.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, i => + i < numberOfRevertiblePublicCallRequests + ? publicCallRequests[i + numberOfNonRevertiblePublicCallRequests].toCallRequest() + : CallRequest.empty(), + ); + } else { + data.forRollup!.end.newNullifiers[0] = firstNullifier; + } + + const target = isForPublic ? data.forPublic! : data.forRollup!; + + const encryptedLogs = hasLogs ? EncryptedTxL2Logs.random(8, 3) : EncryptedTxL2Logs.empty(); // 8 priv function invocations creating 3 encrypted logs each + const unencryptedLogs = hasLogs ? UnencryptedTxL2Logs.random(11, 2) : UnencryptedTxL2Logs.empty(); // 8 priv function invocations creating 3 encrypted logs each + if (!hasLogs) { + target.end.encryptedLogsHash = Fr.ZERO; + target.end.unencryptedLogsHash = Fr.ZERO; + } else { + target.end.encryptedLogsHash = Fr.fromBuffer(encryptedLogs.hash()); + target.end.unencryptedLogsHash = Fr.fromBuffer(unencryptedLogs.hash()); + } + + const tx = new Tx(data, new Proof(Buffer.alloc(0)), encryptedLogs, unencryptedLogs, publicCallRequests); return tx; }; -export const mockSimulatedTx = (seed = 1, logs = true) => { - const tx = mockTx(seed, logs); +export const mockTxForRollup = (seed = 1, { hasLogs = false }: { hasLogs?: boolean } = {}) => + mockTx(seed, { hasLogs, numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 0 }); + +export const mockSimulatedTx = (seed = 1, hasLogs = true) => { + const tx = mockTx(seed, { hasLogs }); const dec: DecodedReturn = [1n, 2n, 3n, 4n]; return new SimulatedTx(tx, dec, dec); }; diff --git a/yarn-project/circuit-types/src/mocks_to_purge.ts b/yarn-project/circuit-types/src/mocks_to_purge.ts deleted file mode 100644 index 60708226bd3..00000000000 --- a/yarn-project/circuit-types/src/mocks_to_purge.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { - ARGS_LENGTH, - AggregationObject, - AztecAddress, - CallContext, - CallRequest, - CallerContext, - CombinedConstantData, - EthAddress, - Fq, - Fr, - FunctionData, - FunctionSelector, - G1AffineElement, - MAX_NEW_L2_TO_L1_MSGS_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - Point, - PrivateAccumulatedNonRevertibleData, - PrivateAccumulatedRevertibleData, - PrivateKernelTailCircuitPublicInputs, - PublicCallRequest, - RevertCode, - SideEffect, - SideEffectLinkedToNoteHash, - TxContext, -} from '@aztec/circuits.js'; -import { makeRollupValidationRequests } from '@aztec/circuits.js/testing'; -import { makeHalfFullTuple, makeTuple, range } from '@aztec/foundation/array'; - -import { makeHeader } from './l2_block_code_to_purge.js'; - -/** - * Creates arbitrary private kernel tail circuit public inputs. - * @param seed - The seed to use for generating the kernel circuit public inputs. - * @returns Private kernel tail circuit public inputs. - */ -export function makePrivateKernelTailCircuitPublicInputs(seed = 1, full = true): PrivateKernelTailCircuitPublicInputs { - return new PrivateKernelTailCircuitPublicInputs( - makeAggregationObject(seed), - makeRollupValidationRequests(seed), - makeAccumulatedNonRevertibleData(seed + 0x100, full), - makeFinalAccumulatedData(seed + 0x200, full), - makeConstantData(seed + 0x300), - true, - true, - true, - ); -} - -/** - * TODO: Since the max value check is currently disabled this function is pointless. Should it be removed? - * Test only. Easy to identify big endian field serialize. - * @param n - The number. - * @returns The field. - */ -export function fr(n: number): Fr { - return new Fr(BigInt(n)); -} -/** - * Creates arbitrary aggregation object. - * @param seed - The seed to use for generating the aggregation object. - * @returns An aggregation object. - */ -export function makeAggregationObject(seed = 1): AggregationObject { - return new AggregationObject( - new G1AffineElement(new Fq(BigInt(seed)), new Fq(BigInt(seed + 1))), - new G1AffineElement(new Fq(BigInt(seed + 0x100)), new Fq(BigInt(seed + 0x101))), - makeTuple(4, fr, seed + 2), - range(6, seed + 6), - ); -} - -/** - * Creates arbitrary accumulated data for a Tx's non-revertible side effects. - * @param seed - The seed to use for generating the data. - * @returns An instance of AccumulatedNonRevertibleData. - */ -export function makeAccumulatedNonRevertibleData(seed = 1, full = false): PrivateAccumulatedNonRevertibleData { - const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - - return new PrivateAccumulatedNonRevertibleData( - RevertCode.OK, - tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), - tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), - tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), - ); -} - -export function sideEffectFromNumber(n: number): SideEffect { - return new SideEffect(new Fr(BigInt(n)), Fr.zero()); -} - -/** - * Test only. Easy to identify big endian side-effect serialize. - * @param n - The number. - * @returns The SideEffect instance. - */ -export function sideEffectLinkedFromNumber(n: number): SideEffectLinkedToNoteHash { - return new SideEffectLinkedToNoteHash(new Fr(BigInt(n)), Fr.zero(), Fr.zero()); -} - -/** - * Makes arbitrary call stack item. - * @param seed - The seed to use for generating the call stack item. - * @returns A call stack item. - */ -export function makeCallRequest(seed = 1): CallRequest { - return new CallRequest(fr(seed), makeAztecAddress(seed + 0x1), makeCallerContext(seed + 0x2), fr(0), fr(0)); -} - -/** - * Makes arbitrary aztec address. - * @param seed - The seed to use for generating the aztec address. - * @returns An aztec address. - */ -export function makeAztecAddress(seed = 1): AztecAddress { - return AztecAddress.fromField(fr(seed)); -} - -/** - * Makes arbitrary call stack item. - * @param seed - The seed to use for generating the call stack item. - * @returns A call stack item. - */ -export function makeCallerContext(seed = 1): CallerContext { - return new CallerContext(makeAztecAddress(seed), makeAztecAddress(seed + 0x1)); -} - -/** - * Creates arbitrary final accumulated data. - * @param seed - The seed to use for generating the final accumulated data. - * @returns A final accumulated data. - */ -export function makeFinalAccumulatedData(seed = 1, full = false): PrivateAccumulatedRevertibleData { - const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - - return new PrivateAccumulatedRevertibleData( - tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x100), - tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), - tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), - tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), - tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600), - fr(seed + 0x700), // encrypted logs hash - fr(seed + 0x800), // unencrypted logs hash - fr(seed + 0x900), // encrypted_log_preimages_length - fr(seed + 0xa00), // unencrypted_log_preimages_length - ); -} - -/** - * Makes arbitrary eth address. - * @param seed - The seed to use for generating the eth address. - * @returns An eth address. - */ -export function makeEthAddress(seed = 1): EthAddress { - return EthAddress.fromField(fr(seed)); -} - -/** - * Creates arbitrary constant data with the given seed. - * @param seed - The seed to use for generating the constant data. - * @returns A constant data object. - */ -export function makeConstantData(seed = 1): CombinedConstantData { - return new CombinedConstantData(makeHeader(seed, undefined), makeTxContext(seed + 4)); -} - -/** - * Creates an arbitrary tx context with the given seed. - * @param seed - The seed to use for generating the tx context. - * @returns A tx context. - */ -export function makeTxContext(_seed: number): TxContext { - // @todo @LHerskind should probably take value for chainId as it will be verified later. - return new TxContext(false, false, Fr.ZERO, Fr.ZERO); -} - -/** - * Creates an arbitrary point in a curve. - * @param seed - Seed to generate the point values. - * @returns A point. - */ -export function makePoint(seed = 1): Point { - return new Point(fr(seed), fr(seed + 1)); -} - -/** - * Creates a public call request for testing. - * @param seed - The seed. - * @returns Public call request. - */ -export function makePublicCallRequest(seed = 1): PublicCallRequest { - const childCallContext = makeCallContext(seed + 0x2, makeAztecAddress(seed)); - const parentCallContext = CallContext.from({ - msgSender: makeAztecAddress(seed + 0x3), - storageContractAddress: childCallContext.msgSender, - portalContractAddress: makeEthAddress(seed + 2), - functionSelector: makeSelector(seed + 3), - isStaticCall: false, - isDelegateCall: false, - sideEffectCounter: 0, - }); - return new PublicCallRequest( - makeAztecAddress(seed), - new FunctionData(makeSelector(seed + 0x1), false), - childCallContext, - parentCallContext, - makeTuple(ARGS_LENGTH, fr, seed + 0x10), - ); -} - -/** - * Creates arbitrary call context. - * @param seed - The seed to use for generating the call context. - * @param storageContractAddress - The storage contract address set on the call context. - * @returns A call context. - */ -export function makeCallContext(seed = 0, storageContractAddress = makeAztecAddress(seed + 1)): CallContext { - return new CallContext( - makeAztecAddress(seed), - storageContractAddress, - makeEthAddress(seed + 2), - makeSelector(seed + 3), - false, - false, - 0, - ); -} - -/** - * Creates arbitrary selector from the given seed. - * @param seed - The seed to use for generating the selector. - * @returns A selector. - */ -export function makeSelector(seed: number): FunctionSelector { - return new FunctionSelector(seed); -} diff --git a/yarn-project/circuit-types/src/tx/processed_tx.ts b/yarn-project/circuit-types/src/tx/processed_tx.ts index fbc98d67c02..b59642ab3b1 100644 --- a/yarn-project/circuit-types/src/tx/processed_tx.ts +++ b/yarn-project/circuit-types/src/tx/processed_tx.ts @@ -10,13 +10,11 @@ import { import { Fr, type Header, + KernelCircuitPublicInputs, type Proof, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, - PublicKernelCircuitPublicInputs, + type PublicKernelCircuitPublicInputs, type SideEffect, type SideEffectLinkedToNoteHash, - ValidationRequests, makeEmptyProof, } from '@aztec/circuits.js'; @@ -26,9 +24,9 @@ import { */ export type ProcessedTx = Pick & { /** - * Output of the public kernel circuit for this tx. + * Output of the private tail or public tail kernel circuit for this tx. */ - data: PublicKernelCircuitPublicInputs; + data: KernelCircuitPublicInputs; /** * Hash of the transaction. */ @@ -53,7 +51,7 @@ export type RevertedTx = ProcessedTx & { }; export function isRevertedTx(tx: ProcessedTx): tx is RevertedTx { - return !tx.data.endNonRevertibleData.revertCode.isOK(); + return !tx.data.revertCode.isOK(); } export function partitionReverts(txs: ProcessedTx[]): { reverted: RevertedTx[]; nonReverted: ProcessedTx[] } { @@ -84,52 +82,6 @@ export type FailedTx = { error: Error; }; -/** - * - * @param tx - the TX being procesed - * @param publicKernelPublicInput - the output of the public kernel circuit, unless we just came from private - * @param publicKernelProof - the proof of the public kernel circuit, unless we just came from private - * @returns PublicKernelCircuitPublicInputs, either passed through from the input or converted from the output of the TX, - * and Proof, either passed through from the input or the proof of the TX - */ -export function getPreviousOutputAndProof( - tx: Tx, - publicKernelPublicInput?: PublicKernelCircuitPublicInputs, - publicKernelProof?: Proof, -): { - /** - * the output of the public kernel circuit for this phase - */ - publicKernelPublicInput: PublicKernelCircuitPublicInputs; - /** - * the proof of the public kernel circuit for this phase - */ - previousProof: Proof; -} { - if (publicKernelPublicInput && publicKernelProof) { - return { - publicKernelPublicInput, - previousProof: publicKernelProof, - }; - } else { - const publicKernelPublicInput = new PublicKernelCircuitPublicInputs( - tx.data.aggregationObject, - tx.data.rollupValidationRequests, - ValidationRequests.empty(), - PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData), - PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end), - tx.data.constants, - tx.data.needsSetup, - tx.data.needsAppLogic, - tx.data.needsTeardown, - ); - return { - publicKernelPublicInput, - previousProof: publicKernelProof || tx.proof, - }; - } -} - /** * Makes a processed tx out of source tx. * @param tx - Source tx. @@ -138,15 +90,14 @@ export function getPreviousOutputAndProof( */ export function makeProcessedTx( tx: Tx, - kernelOutput?: PublicKernelCircuitPublicInputs, - proof?: Proof, + kernelOutput: KernelCircuitPublicInputs, + proof: Proof, revertReason?: SimulationError, ): ProcessedTx { - const { publicKernelPublicInput, previousProof } = getPreviousOutputAndProof(tx, kernelOutput, proof); return { hash: tx.getTxHash(), - data: publicKernelPublicInput, - proof: previousProof, + data: kernelOutput, + proof, encryptedLogs: revertReason ? EncryptedTxL2Logs.empty() : tx.encryptedLogs, unencryptedLogs: revertReason ? UnencryptedTxL2Logs.empty() : tx.unencryptedLogs, isEmpty: false, @@ -159,7 +110,7 @@ export function makeProcessedTx( * @returns A processed empty tx. */ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): ProcessedTx { - const emptyKernelOutput = PublicKernelCircuitPublicInputs.empty(); + const emptyKernelOutput = KernelCircuitPublicInputs.empty(); emptyKernelOutput.constants.historicalHeader = header; emptyKernelOutput.constants.txContext.chainId = chainId; emptyKernelOutput.constants.txContext.version = version; @@ -179,11 +130,11 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): export function toTxEffect(tx: ProcessedTx): TxEffect { return new TxEffect( - tx.data.combinedData.revertCode, - tx.data.combinedData.newNoteHashes.map((c: SideEffect) => c.value).filter(h => !h.isZero()), - tx.data.combinedData.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value).filter(h => !h.isZero()), - tx.data.combinedData.newL2ToL1Msgs.filter(h => !h.isZero()), - tx.data.combinedData.publicDataUpdateRequests + tx.data.revertCode, + tx.data.end.newNoteHashes.map((c: SideEffect) => c.value).filter(h => !h.isZero()), + tx.data.end.newNullifiers.map((n: SideEffectLinkedToNoteHash) => n.value).filter(h => !h.isZero()), + tx.data.end.newL2ToL1Msgs.filter(h => !h.isZero()), + tx.data.end.publicDataUpdateRequests .map(t => new PublicDataWrite(t.leafSlot, t.newValue)) .filter(h => !h.isEmpty()), tx.encryptedLogs || EncryptedTxL2Logs.empty(), @@ -193,13 +144,13 @@ export function toTxEffect(tx: ProcessedTx): TxEffect { function validateProcessedTxLogs(tx: ProcessedTx): void { const unencryptedLogs = tx.unencryptedLogs || UnencryptedTxL2Logs.empty(); - const kernelUnencryptedLogsHash = tx.data.combinedData.unencryptedLogsHash; + const kernelUnencryptedLogsHash = tx.data.end.unencryptedLogsHash; const referenceHash = Fr.fromBuffer(unencryptedLogs.hash()); if (!referenceHash.equals(kernelUnencryptedLogsHash)) { throw new Error( `Unencrypted logs hash mismatch. Expected ${referenceHash.toString()}, got ${kernelUnencryptedLogsHash.toString()}. Processed: ${JSON.stringify(unencryptedLogs.toJSON())} - Kernel Length: ${tx.data.combinedData.unencryptedLogPreimagesLength}`, + Kernel Length: ${tx.data.end.unencryptedLogPreimagesLength}`, ); } } diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 181bc5d969b..bfa009872fc 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -3,10 +3,7 @@ import { PrivateKernelTailCircuitPublicInputs, Proof, PublicCallRequest, - SideEffect, - SideEffectLinkedToNoteHash, } from '@aztec/circuits.js'; -import { arrayNonEmptyLength } from '@aztec/foundation/collection'; import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { type GetUnencryptedLogsResponse } from '../logs/get_unencrypted_logs_response.js'; @@ -52,16 +49,19 @@ export class Tx { ); } - const kernelPublicCallStackSize = - data?.end.publicCallStack && arrayNonEmptyLength(data.end.publicCallStack, item => item.isEmpty()); - if (kernelPublicCallStackSize && kernelPublicCallStackSize > (enqueuedPublicFunctionCalls?.length ?? 0)) { + const kernelPublicCallStackSize = data.numberOfPublicCallRequests(); + if (kernelPublicCallStackSize !== enqueuedPublicFunctionCalls.length) { throw new Error( - `Missing preimages for enqueued public function calls in kernel circuit public inputs (expected - ${kernelPublicCallStackSize}, got ${enqueuedPublicFunctionCalls?.length})`, + `Mismatch number of enqueued public function calls in kernel circuit public inputs (expected + ${kernelPublicCallStackSize}, got ${enqueuedPublicFunctionCalls.length})`, ); } } + hasPublicCalls() { + return this.data.numberOfPublicCallRequests() > 0; + } + /** * Deserializes the Tx object from a Buffer. * @param buffer - Buffer or BufferReader object to deserialize. @@ -138,7 +138,7 @@ export class Tx { */ getTxHash(): TxHash { // Private kernel functions are executed client side and for this reason tx hash is already set as first nullifier - const firstNullifier = this.data?.endNonRevertibleData.newNullifiers[0]; + const firstNullifier = this.data.getNonEmptyNullifiers()[0]; if (!firstNullifier || firstNullifier.isEmpty()) { throw new Error(`Cannot get tx hash since first nullifier is missing`); } @@ -154,22 +154,17 @@ export class Tx { encryptedLogSize: this.encryptedLogs.getSerializedLength(), unencryptedLogSize: this.unencryptedLogs.getSerializedLength(), - newCommitmentCount: - arrayNonEmptyLength(this.data!.endNonRevertibleData.newNoteHashes, SideEffect.isEmpty) + - arrayNonEmptyLength(this.data!.end.newNoteHashes, SideEffect.isEmpty), - - newNullifierCount: - arrayNonEmptyLength(this.data!.endNonRevertibleData.newNullifiers, SideEffectLinkedToNoteHash.isEmpty) + - arrayNonEmptyLength(this.data!.end.newNullifiers, SideEffectLinkedToNoteHash.isEmpty), + newCommitmentCount: this.data.getNonEmptyNoteHashes().length, + newNullifierCount: this.data.getNonEmptyNullifiers().length, proofSize: this.proof.buffer.length, size: this.toBuffer().length, feePaymentMethod: // needsTeardown? then we pay a fee - this.data.needsTeardown + this.data.forPublic?.needsTeardown ? // needsSetup? then we pay through a fee payment contract - this.data.needsSetup + this.data.forPublic?.needsSetup ? // if the first call is to `approve_public_authwit`, then it's a public payment this.enqueuedPublicFunctionCalls.at(-1)!.functionData.selector.toField().toBigInt() === 0x43417bb1n ? 'fpc_public' diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index e2144817194..a87167a0ae5 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -14,18 +14,10 @@ export const MAX_NULLIFIER_READ_REQUESTS_PER_CALL = 2; export const MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 2; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; export const MAX_NEW_NOTE_HASHES_PER_TX = 64; -export const MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX = 8; -export const MAX_REVERTIBLE_NOTE_HASHES_PER_TX = 56; export const MAX_NEW_NULLIFIERS_PER_TX = 64; -export const MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX = 8; -export const MAX_REVERTIBLE_NULLIFIERS_PER_TX = 56; export const MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX = 8; export const MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX = 8; -export const MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX = 3; -export const MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX = 5; export const MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 32; -export const MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 16; -export const MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 16; export const MAX_PUBLIC_DATA_READS_PER_TX = 32; export const MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2; export const MAX_NOTE_HASH_READ_REQUESTS_PER_TX = 128; diff --git a/yarn-project/circuits.js/src/hints/build_hints.ts b/yarn-project/circuits.js/src/hints/build_hints.ts index 444a993220f..1266082c2d0 100644 --- a/yarn-project/circuits.js/src/hints/build_hints.ts +++ b/yarn-project/circuits.js/src/hints/build_hints.ts @@ -15,7 +15,7 @@ import { NullifierNonExistentReadRequestHintsBuilder } from '../structs/non_exis import { type ReadRequestContext } from '../structs/read_request.js'; import { NullifierReadRequestHintsBuilder } from '../structs/read_request_hints.js'; import { SideEffectLinkedToNoteHash } from '../structs/side_effects.js'; -import { countAccumulatedItems } from './utils.js'; +import { countAccumulatedItems } from '../utils/index.js'; export interface NullifierMembershipWitnessWithPreimage { membershipWitness: MembershipWitness; diff --git a/yarn-project/circuits.js/src/hints/index.ts b/yarn-project/circuits.js/src/hints/index.ts index ef50cf70092..476edce05e9 100644 --- a/yarn-project/circuits.js/src/hints/index.ts +++ b/yarn-project/circuits.js/src/hints/index.ts @@ -1,2 +1,2 @@ export * from './build_hints.js'; -export * from './utils.js'; +export * from '../utils/index.js'; diff --git a/yarn-project/circuits.js/src/keys/index.ts b/yarn-project/circuits.js/src/keys/index.ts index def8b480167..9d48a2a2783 100644 --- a/yarn-project/circuits.js/src/keys/index.ts +++ b/yarn-project/circuits.js/src/keys/index.ts @@ -18,7 +18,7 @@ export function derivePublicKey(secretKey: GrumpkinPrivateKey) { */ function deriveSecretKey(secretKey: GrumpkinPrivateKey, index: Fr): GrumpkinPrivateKey { // TODO: Temporary hack. Should replace it with a secure way to derive the secret key. - // Match the way keys are derived in noir-protocol-circuits/crates/private_kernel_lib/src/common.nr + // Match the way keys are derived in noir-protocol-circuits/crates/types/src/keys.nr const hash = pedersenHash([secretKey.high, secretKey.low, index]); return new GrumpkinScalar(hash.toBuffer()); } diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap index f36489ffeba..f6c0e0e8c86 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/public_call_stack_item.test.ts.snap @@ -4,4 +4,4 @@ exports[`PublicCallStackItem Computes a callstack item hash 1`] = `"0x1fe20dd657 exports[`PublicCallStackItem Computes a callstack item request hash 1`] = `"0x09bd19d3ebcda705ab1ed598db287340aed3efda0ad3bbbf3296737bda731fa9"`; -exports[`PublicCallStackItem computes hash 1`] = `Fr<0x131efdeaaf1e936042e5e5a24a8546863bbddfc70b8e6bdd6df457595df30577>`; +exports[`PublicCallStackItem computes hash 1`] = `Fr<0x199dfba7eaee0977e755d4b7b575845e94f37b94bffe27b03ad45dfafe53177c>`; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap index ac66f2c8c30..96c773f7947 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/__snapshots__/public_circuit_public_inputs.test.ts.snap @@ -2,4 +2,4 @@ exports[`PublicCircuitPublicInputs computes empty item hash 1`] = `Fr<0x0f1eb4e352e8dab6cbab3c63b6d8f3cd2cd90cc7ae5ff142e4dfa2b3e28e01c1>`; -exports[`PublicCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x292de5dfe34d2970781cc583f2273f880ed55a98bd7f8216bbb1297c2f29a2cc>`; +exports[`PublicCircuitPublicInputs hash matches snapshot 1`] = `Fr<0x0acad66a97a2ab5e0e4e916f95ed5921766762cf85b5c2db29ec0edcba06d63c>`; diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index 02984792090..c59c4811e5b 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -10,22 +10,23 @@ export * from './function_data.js'; export * from './global_variables.js'; export * from './header.js'; export * from './kernel/combined_accumulated_data.js'; +export * from './kernel/private_accumulated_data.js'; +export * from './kernel/public_accumulated_data.js'; export * from './kernel/combined_constant_data.js'; export * from './kernel/private_call_data.js'; export * from './kernel/private_kernel_init_circuit_private_inputs.js'; +export * from './kernel/private_kernel_circuit_public_inputs.js'; +export * from './kernel/private_kernel_data.js'; export * from './kernel/private_kernel_inner_circuit_private_inputs.js'; -export * from './kernel/private_kernel_inner_circuit_public_inputs.js'; -export * from './kernel/private_kernel_inner_data.js'; export * from './kernel/private_kernel_tail_circuit_private_inputs.js'; export * from './kernel/private_kernel_tail_circuit_public_inputs.js'; -export * from './kernel/private_kernel_tail_data.js'; export * from './kernel/public_call_data.js'; export * from './kernel/public_kernel_circuit_private_inputs.js'; export * from './kernel/public_kernel_circuit_public_inputs.js'; export * from './kernel/public_kernel_data.js'; export * from './kernel/public_kernel_tail_circuit_private_inputs.js'; -export * from './kernel/rollup_kernel_circuit_public_inputs.js'; -export * from './kernel/rollup_kernel_data.js'; +export * from './kernel/kernel_circuit_public_inputs.js'; +export * from './kernel/kernel_data.js'; export * from './l2_to_l1_message.js'; export * from './max_block_number.js'; export * from './membership_witness.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.test.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.test.ts index 474cd34b77d..64cbcb0cd1d 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.test.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.test.ts @@ -1,11 +1,5 @@ -import { makeCombinedAccumulatedData, makeFinalAccumulatedData } from '../../tests/factories.js'; -import { Fr } from '../index.js'; -import { - CombinedAccumulatedData, - PrivateAccumulatedRevertibleData, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, -} from './combined_accumulated_data.js'; +import { makeCombinedAccumulatedData } from '../../tests/factories.js'; +import { CombinedAccumulatedData } from './combined_accumulated_data.js'; describe('CombinedAccumulatedData', () => { it('Data after serialization and deserialization is equal to the original', () => { @@ -13,42 +7,4 @@ describe('CombinedAccumulatedData', () => { const afterSerialization = CombinedAccumulatedData.fromBuffer(original.toBuffer()); expect(original).toEqual(afterSerialization); }); - - it('recombines notes correctly', () => { - const nonRevertible = PublicAccumulatedNonRevertibleData.empty(); - nonRevertible.newNoteHashes[0].counter = new Fr(1); // a note created in private fee setup - nonRevertible.newNoteHashes[1].counter = new Fr(5); // a note created in public setup - nonRevertible.newNoteHashes[2].counter = new Fr(10); // a note created in public teardown - - const end = PublicAccumulatedRevertibleData.empty(); - end.newNoteHashes[0].counter = new Fr(2); // a note created in private app logic - end.newNoteHashes[1].counter = new Fr(8); // a note created in public app logic - - const combined = CombinedAccumulatedData.recombine(nonRevertible, end); - - expect(combined.newNoteHashes.map(x => x.counter.toNumber()).slice(0, 5)).toEqual([1, 2, 5, 8, 10]); - }); - - it('recombines nullifiers correctly', () => { - const nonRevertible = PublicAccumulatedNonRevertibleData.empty(); - nonRevertible.newNullifiers[0].counter = new Fr(1); // a nullifier created in private fee setup - nonRevertible.newNullifiers[1].counter = new Fr(5); // a nullifier created in public setup - nonRevertible.newNullifiers[2].counter = new Fr(10); // a nullifier created in public teardown - - const end = PublicAccumulatedRevertibleData.empty(); - end.newNullifiers[0].counter = new Fr(2); // a nullifier created in private app logic - end.newNullifiers[1].counter = new Fr(8); // a nullifier created in public app logic - - const combined = CombinedAccumulatedData.recombine(nonRevertible, end); - - expect(combined.newNullifiers.map(x => x.counter.toNumber()).slice(0, 5)).toEqual([1, 2, 5, 8, 10]); - }); -}); - -describe('FinalAccumulatedData', () => { - it('Data after serialization and deserialization is equal to the original', () => { - const original = makeFinalAccumulatedData(); - const afterSerialization = PrivateAccumulatedRevertibleData.fromBuffer(original.toBuffer()); - expect(original).toEqual(afterSerialization); - }); }); diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts index 0de9b528bbd..66be5891125 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -1,44 +1,22 @@ import { makeTuple } from '@aztec/foundation/array'; -import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; -import { createDebugOnlyLogger } from '@aztec/foundation/log'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; -import { inspect } from 'util'; - import { type MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, } from '../../constants.gen.js'; -import { CallRequest } from '../call_request.js'; import { PublicDataUpdateRequest } from '../public_data_update_request.js'; -import { RevertCode } from '../revert_code.js'; -import { SideEffect, SideEffectLinkedToNoteHash, sideEffectCmp } from '../side_effects.js'; - -const log = createDebugOnlyLogger('aztec:combined_accumulated_data'); +import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; /** * Data that is accumulated during the execution of the transaction. */ export class CombinedAccumulatedData { constructor( - /** - * Flag indicating whether the transaction reverted. - */ - public revertCode: RevertCode, /** * The new note hashes made in this transaction. */ @@ -47,14 +25,6 @@ export class CombinedAccumulatedData { * The new nullifiers made in this transaction. */ public newNullifiers: Tuple, - /** - * Current private call stack. - */ - public privateCallStack: Tuple, - /** - * Current public call stack. - */ - public publicCallStack: Tuple, /** * All the new L2 to L1 messages created in this transaction. */ @@ -85,11 +55,8 @@ export class CombinedAccumulatedData { toBuffer() { return serializeToBuffer( - this.revertCode, this.newNoteHashes, this.newNullifiers, - this.privateCallStack, - this.publicCallStack, this.newL2ToL1Msgs, this.encryptedLogsHash, this.unencryptedLogsHash, @@ -111,11 +78,8 @@ export class CombinedAccumulatedData { static fromBuffer(buffer: Buffer | BufferReader): CombinedAccumulatedData { const reader = BufferReader.asReader(buffer); return new CombinedAccumulatedData( - RevertCode.fromBuffer(reader), reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), Fr.fromBuffer(reader), Fr.fromBuffer(reader), @@ -136,11 +100,8 @@ export class CombinedAccumulatedData { static empty() { return new CombinedAccumulatedData( - RevertCode.OK, makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), Fr.zero(), Fr.zero(), @@ -149,480 +110,4 @@ export class CombinedAccumulatedData { makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), ); } - - /** - * - * @param nonRevertible the non-revertible accumulated data - * @param revertible the revertible accumulated data - * @returns a new CombinedAccumulatedData object, squashing the two inputs, and condensing arrays - */ - public static recombine( - nonRevertible: PublicAccumulatedNonRevertibleData, - revertible: PublicAccumulatedRevertibleData, - ): CombinedAccumulatedData { - if (!nonRevertible.revertCode.isOK() && !revertible.isEmpty()) { - log(inspect(revertible)); - throw new Error('Revertible data should be empty if the transaction is revertCode'); - } - - const newNoteHashes = padArrayEnd( - [...nonRevertible.newNoteHashes, ...revertible.newNoteHashes].filter(x => !x.isEmpty()).sort(sideEffectCmp), - SideEffect.empty(), - MAX_NEW_NOTE_HASHES_PER_TX, - ); - - const newNullifiers = padArrayEnd( - [...nonRevertible.newNullifiers, ...revertible.newNullifiers].filter(x => !x.isEmpty()).sort(sideEffectCmp), - SideEffectLinkedToNoteHash.empty(), - MAX_NEW_NULLIFIERS_PER_TX, - ); - - const publicCallStack = padArrayEnd( - [...nonRevertible.publicCallStack, ...revertible.publicCallStack].filter(x => !x.isEmpty()), - CallRequest.empty(), - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - ); - - const nonSquashedWrites = [ - ...revertible.publicDataUpdateRequests, - ...nonRevertible.publicDataUpdateRequests, - ].filter(x => !x.isEmpty()); - - const squashedWrites = Array.from( - nonSquashedWrites - .reduce>((acc, curr) => { - acc.set(curr.leafSlot.toString(), curr); - return acc; - }, new Map()) - .values(), - ); - - const publicDataUpdateRequests = padArrayEnd( - squashedWrites, - PublicDataUpdateRequest.empty(), - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - ); - - return new CombinedAccumulatedData( - nonRevertible.revertCode, - newNoteHashes, - newNullifiers, - revertible.privateCallStack, - publicCallStack, - revertible.newL2ToL1Msgs, - revertible.encryptedLogsHash, - revertible.unencryptedLogsHash, - revertible.encryptedLogPreimagesLength, - revertible.unencryptedLogPreimagesLength, - publicDataUpdateRequests, - ); - } -} - -export class PublicAccumulatedRevertibleData { - constructor( - /** - * The new note hashes made in this transaction. - */ - public newNoteHashes: Tuple, - /** - * The new nullifiers made in this transaction. - */ - public newNullifiers: Tuple, - /** - * Current private call stack. - */ - public privateCallStack: Tuple, - /** - * Current public call stack. - */ - public publicCallStack: Tuple, - /** - * All the new L2 to L1 messages created in this transaction. - */ - public newL2ToL1Msgs: Tuple, - /** - * Accumulated encrypted logs hash from all the previous kernel iterations. - * Note: Truncated to 31 bytes to fit in Fr. - */ - public encryptedLogsHash: Fr, - /** - * Accumulated unencrypted logs hash from all the previous kernel iterations. - * Note: Truncated to 31 bytes to fit in Fr. - */ - public unencryptedLogsHash: Fr, - /** - * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations - */ - public encryptedLogPreimagesLength: Fr, - /** - * Total accumulated length of the unencrypted log preimages emitted in all the previous kernel iterations - */ - public unencryptedLogPreimagesLength: Fr, - /** - * All the public data update requests made in this transaction. - */ - public publicDataUpdateRequests: Tuple< - PublicDataUpdateRequest, - typeof MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - >, - ) {} - - toBuffer() { - return serializeToBuffer( - this.newNoteHashes, - this.newNullifiers, - this.privateCallStack, - this.publicCallStack, - this.newL2ToL1Msgs, - this.encryptedLogsHash, - this.unencryptedLogsHash, - this.encryptedLogPreimagesLength, - this.unencryptedLogPreimagesLength, - this.publicDataUpdateRequests, - ); - } - - toString() { - return this.toBuffer().toString('hex'); - } - - isEmpty(): boolean { - return ( - this.newNoteHashes.every(x => x.isEmpty()) && - this.newNullifiers.every(x => x.isEmpty()) && - this.privateCallStack.every(x => x.isEmpty()) && - this.publicCallStack.every(x => x.isEmpty()) && - this.newL2ToL1Msgs.every(x => x.isZero()) && - this.encryptedLogsHash.isZero() && - this.unencryptedLogsHash.isZero() && - this.encryptedLogPreimagesLength.isZero() && - this.unencryptedLogPreimagesLength.isZero() && - this.publicDataUpdateRequests.every(x => x.isEmpty()) - ); - } - - [inspect.custom]() { - // print out the non-empty fields - return `PublicAccumulatedRevertibleData { - newNoteHashes: [${this.newNoteHashes.map(h => h.toString()).join(', ')}], - newNullifiers: [${this.newNullifiers.map(h => h.toString()).join(', ')}], - privateCallStack: [${this.privateCallStack.map(h => h.toString()).join(', ')}], - publicCallStack: [${this.publicCallStack.map(h => h.toString()).join(', ')}], - newL2ToL1Msgs: [${this.newL2ToL1Msgs.map(h => h.toString()).join(', ')}], - encryptedLogsHash: ${this.encryptedLogsHash}, - unencryptedLogsHash: ${this.unencryptedLogsHash}, - encryptedLogPreimagesLength: ${this.encryptedLogPreimagesLength} - unencryptedLogPreimagesLength: ${this.unencryptedLogPreimagesLength} - publicDataUpdateRequests: [${this.publicDataUpdateRequests.map(h => h.toString()).join(', ')}], -}`; - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer or reader to read from. - * @returns Deserialized object. - */ - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new this( - reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), - reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - reader.readArray(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), - ); - } - - static fromPrivateAccumulatedRevertibleData(finalData: PrivateAccumulatedRevertibleData) { - return new this( - padArrayEnd(finalData.newNoteHashes, SideEffect.empty(), MAX_REVERTIBLE_NOTE_HASHES_PER_TX), - padArrayEnd(finalData.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_REVERTIBLE_NULLIFIERS_PER_TX), - finalData.privateCallStack, - padArrayEnd(finalData.publicCallStack, CallRequest.empty(), MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX), - finalData.newL2ToL1Msgs, - finalData.encryptedLogsHash, - finalData.unencryptedLogsHash, - finalData.encryptedLogPreimagesLength, - finalData.unencryptedLogPreimagesLength, - makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - ); - } - - /** - * Deserializes from a string, corresponding to a write in cpp. - * @param str - String to read from. - * @returns Deserialized object. - */ - static fromString(str: string) { - return this.fromBuffer(Buffer.from(str, 'hex')); - } - - static empty() { - return new this( - makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), - makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), - Fr.zero(), - Fr.zero(), - Fr.zero(), - Fr.zero(), - makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - ); - } -} - -/** - * Specific accumulated data structure for the final ordering private kernel circuit. It is included - * in the final public inputs of private kernel circuit. - */ -export class PrivateAccumulatedRevertibleData { - constructor( - /** - * The new note hashes made in this transaction. - */ - public newNoteHashes: Tuple, - /** - * The new nullifiers made in this transaction. - */ - public newNullifiers: Tuple, - /** - * Current private call stack. - * TODO(#3417): Given this field must empty, should we just remove it? - */ - public privateCallStack: Tuple, - /** - * Current public call stack. - */ - public publicCallStack: Tuple, - /** - * All the new L2 to L1 messages created in this transaction. - */ - public newL2ToL1Msgs: Tuple, - /** - * Accumulated encrypted logs hash from all the previous kernel iterations. - * Note: Truncated to 31 bytes to fit in Fr. - */ - public encryptedLogsHash: Fr, - /** - * Accumulated unencrypted logs hash from all the previous kernel iterations. - * Note: Truncated to 31 bytes to fit in Fr. - */ - public unencryptedLogsHash: Fr, - /** - * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations - */ - public encryptedLogPreimagesLength: Fr, - /** - * Total accumulated length of the unencrypted log preimages emitted in all the previous kernel iterations - */ - public unencryptedLogPreimagesLength: Fr, - ) {} - - toBuffer() { - return serializeToBuffer( - this.newNoteHashes, - this.newNullifiers, - this.privateCallStack, - this.publicCallStack, - this.newL2ToL1Msgs, - this.encryptedLogsHash, - this.unencryptedLogsHash, - this.encryptedLogPreimagesLength, - this.unencryptedLogPreimagesLength, - ); - } - - toString() { - return this.toBuffer().toString('hex'); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer or reader to read from. - * @returns Deserialized object. - */ - static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedRevertibleData { - const reader = BufferReader.asReader(buffer); - return new PrivateAccumulatedRevertibleData( - reader.readArray(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), - reader.readArray(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), - reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - Fr.fromBuffer(reader), - ); - } - - /** - * Deserializes from a string, corresponding to a write in cpp. - * @param str - String to read from. - * @returns Deserialized object. - */ - static fromString(str: string) { - return PrivateAccumulatedRevertibleData.fromBuffer(Buffer.from(str, 'hex')); - } - - static empty() { - return new PrivateAccumulatedRevertibleData( - makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), - makeTuple(MAX_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), - Fr.zero(), - Fr.zero(), - Fr.zero(), - Fr.zero(), - ); - } -} - -export class PrivateAccumulatedNonRevertibleData { - constructor( - /** - * Flag indicating whether the transaction reverted. - */ - public revertCode: RevertCode, - /** - * The new non-revertible commitments made in this transaction. - */ - public newNoteHashes: Tuple, - /** - * The new non-revertible nullifiers made in this transaction. - */ - public newNullifiers: Tuple, - /** - * Current public call stack that will produce non-revertible side effects. - */ - public publicCallStack: Tuple, - ) {} - - toBuffer() { - return serializeToBuffer(this.revertCode.toBuffer(), this.newNoteHashes, this.newNullifiers, this.publicCallStack); - } - - static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedNonRevertibleData { - const reader = BufferReader.asReader(buffer); - return new PrivateAccumulatedNonRevertibleData( - RevertCode.fromBuffer(reader), - reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), - reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), - reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - ); - } - - toString() { - return this.toBuffer().toString('hex'); - } - - static fromString(str: string) { - return PrivateAccumulatedNonRevertibleData.fromBuffer(Buffer.from(str, 'hex')); - } - - static empty() { - return new PrivateAccumulatedNonRevertibleData( - RevertCode.OK, - makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), - makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - ); - } -} - -export class PublicAccumulatedNonRevertibleData { - constructor( - /** - * Flag indicating whether the transaction reverted. - */ - public revertCode: RevertCode, - /** - * The new non-revertible commitments made in this transaction. - */ - public newNoteHashes: Tuple, - /** - * The new non-revertible nullifiers made in this transaction. - */ - public newNullifiers: Tuple, - /** - * Current public call stack that will produce non-revertible side effects. - */ - public publicCallStack: Tuple, - /** - * All the public data update requests made in this transaction. - */ - public publicDataUpdateRequests: Tuple< - PublicDataUpdateRequest, - typeof MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - >, - ) {} - - toBuffer() { - return serializeToBuffer( - this.revertCode, - this.newNoteHashes, - this.newNullifiers, - this.publicCallStack, - this.publicDataUpdateRequests, - ); - } - - static fromBuffer(buffer: Buffer | BufferReader) { - const reader = BufferReader.asReader(buffer); - return new this( - RevertCode.fromBuffer(reader), - reader.readArray(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect), - reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), - reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), - reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), - ); - } - - toString() { - return this.toBuffer().toString('hex'); - } - - static fromString(str: string) { - return this.fromBuffer(Buffer.from(str, 'hex')); - } - - static empty() { - return new this( - RevertCode.OK, - makeTuple(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, SideEffect.empty), - makeTuple(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), - makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - ); - } - - static fromPrivateAccumulatedNonRevertibleData(data: PrivateAccumulatedNonRevertibleData) { - return new this( - data.revertCode, - data.newNoteHashes, - data.newNullifiers, - data.publicCallStack, - makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - ); - } - - [inspect.custom]() { - return `PublicAccumulatedNonRevertibleData { - revertCode: ${this.revertCode}, - newNoteHashes: [${this.newNoteHashes.map(h => h.toString()).join(', ')}], - newNullifiers: [${this.newNullifiers.map(h => h.toString()).join(', ')}], - publicCallStack: [${this.publicCallStack.map(h => h.toString()).join(', ')}], - publicDataUpdateRequests: [${this.publicDataUpdateRequests.map(h => h.toString()).join(', ')}], -}`; - } } diff --git a/yarn-project/circuits.js/src/structs/kernel/rollup_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts similarity index 69% rename from yarn-project/circuits.js/src/structs/kernel/rollup_kernel_circuit_public_inputs.ts rename to yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts index 9b973842448..61f8ae1d479 100644 --- a/yarn-project/circuits.js/src/structs/kernel/rollup_kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/kernel_circuit_public_inputs.ts @@ -1,6 +1,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { AggregationObject } from '../aggregation_object.js'; +import { RevertCode } from '../revert_code.js'; import { RollupValidationRequests } from '../rollup_validation_requests.js'; import { CombinedAccumulatedData } from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; @@ -9,12 +10,16 @@ import { CombinedConstantData } from './combined_constant_data.js'; * Outputs from the public kernel circuits. * All Public kernels use this shape for outputs. */ -export class RollupKernelCircuitPublicInputs { +export class KernelCircuitPublicInputs { constructor( /** * Aggregated proof of all the previous kernel iterations. */ public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations + /** + * Validation requests accumulated from private and public execution to be completed by the rollup. + */ + public rollupValidationRequests: RollupValidationRequests, /** * Data accumulated from both public and private circuits. */ @@ -24,36 +29,48 @@ export class RollupKernelCircuitPublicInputs { */ public constants: CombinedConstantData, /** - * Validation requests accumulated from private and public execution to be completed by the rollup. + * Flag indicating whether the transaction reverted. */ - public rollupValidationRequests: RollupValidationRequests, + public revertCode: RevertCode, ) {} + getNonEmptyNullifiers() { + return this.end.newNullifiers.filter(n => !n.isEmpty()); + } + toBuffer() { - return serializeToBuffer(this.aggregationObject, this.end, this.constants, this.rollupValidationRequests); + return serializeToBuffer( + this.aggregationObject, + this.rollupValidationRequests, + this.end, + this.constants, + this.revertCode, + ); } /** * Deserializes from a buffer or reader, corresponding to a write in cpp. * @param buffer - Buffer or reader to read from. - * @returns A new instance of RollupKernelCircuitPublicInputs. + * @returns A new instance of KernelCircuitPublicInputs. */ - static fromBuffer(buffer: Buffer | BufferReader): RollupKernelCircuitPublicInputs { + static fromBuffer(buffer: Buffer | BufferReader): KernelCircuitPublicInputs { const reader = BufferReader.asReader(buffer); - return new RollupKernelCircuitPublicInputs( + return new KernelCircuitPublicInputs( reader.readObject(AggregationObject), + reader.readObject(RollupValidationRequests), reader.readObject(CombinedAccumulatedData), reader.readObject(CombinedConstantData), - reader.readObject(RollupValidationRequests), + reader.readObject(RevertCode), ); } static empty() { - return new RollupKernelCircuitPublicInputs( + return new KernelCircuitPublicInputs( AggregationObject.makeFake(), + RollupValidationRequests.empty(), CombinedAccumulatedData.empty(), CombinedConstantData.empty(), - RollupValidationRequests.empty(), + RevertCode.OK, ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/rollup_kernel_data.ts b/yarn-project/circuits.js/src/structs/kernel/kernel_data.ts similarity index 71% rename from yarn-project/circuits.js/src/structs/kernel/rollup_kernel_data.ts rename to yarn-project/circuits.js/src/structs/kernel/kernel_data.ts index 384c383fac0..b12cdd0e8dc 100644 --- a/yarn-project/circuits.js/src/structs/kernel/rollup_kernel_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/kernel_data.ts @@ -6,17 +6,14 @@ import { VK_TREE_HEIGHT } from '../../constants.gen.js'; import { Proof, makeEmptyProof } from '../proof.js'; import { type UInt32 } from '../shared.js'; import { VerificationKey } from '../verification_key.js'; -import { RollupKernelCircuitPublicInputs } from './rollup_kernel_circuit_public_inputs.js'; +import { KernelCircuitPublicInputs } from './kernel_circuit_public_inputs.js'; -/** - * Data of the previous public kernel iteration in the chain of kernels. - */ -export class RollupKernelData { +export class KernelData { constructor( /** * Public inputs of the previous kernel. */ - public publicInputs: RollupKernelCircuitPublicInputs, + public publicInputs: KernelCircuitPublicInputs, /** * Proof of the previous kernel. */ @@ -35,10 +32,20 @@ export class RollupKernelData { public vkPath: Tuple, ) {} - static fromBuffer(buffer: Buffer | BufferReader): RollupKernelData { + static empty(): KernelData { + return new this( + KernelCircuitPublicInputs.empty(), + makeEmptyProof(), + VerificationKey.makeFake(), + 0, + makeTuple(VK_TREE_HEIGHT, Fr.zero), + ); + } + + static fromBuffer(buffer: Buffer | BufferReader): KernelData { const reader = BufferReader.asReader(buffer); return new this( - reader.readObject(RollupKernelCircuitPublicInputs), + reader.readObject(KernelCircuitPublicInputs), reader.readObject(Proof), reader.readObject(VerificationKey), reader.readNumber(), @@ -46,20 +53,6 @@ export class RollupKernelData { ); } - static empty(): RollupKernelData { - return new this( - RollupKernelCircuitPublicInputs.empty(), - makeEmptyProof(), - VerificationKey.makeFake(), - 0, - makeTuple(VK_TREE_HEIGHT, Fr.zero), - ); - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ toBuffer() { return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkPath); } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts new file mode 100644 index 00000000000..8334b019fe4 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/private_accumulated_data.ts @@ -0,0 +1,123 @@ +import { makeTuple } from '@aztec/foundation/array'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; + +import { + type MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, +} from '../../constants.gen.js'; +import { CallRequest } from '../call_request.js'; +import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; + +/** + * Specific accumulated data structure for the final ordering private kernel circuit. It is included + * in the final public inputs of private kernel circuit. + */ +export class PrivateAccumulatedData { + constructor( + /** + * The new note hashes made in this transaction. + */ + public newNoteHashes: Tuple, + /** + * The new nullifiers made in this transaction. + */ + public newNullifiers: Tuple, + /** + * All the new L2 to L1 messages created in this transaction. + */ + public newL2ToL1Msgs: Tuple, + /** + * Accumulated encrypted logs hash from all the previous kernel iterations. + * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. + */ + public encryptedLogsHash: Fr, + /** + * Accumulated unencrypted logs hash from all the previous kernel iterations. + * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. + */ + public unencryptedLogsHash: Fr, + /** + * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations + */ + public encryptedLogPreimagesLength: Fr, + /** + * Total accumulated length of the unencrypted log preimages emitted in all the previous kernel iterations + */ + public unencryptedLogPreimagesLength: Fr, + /** + * Current private call stack. + * TODO(#3417): Given this field must empty, should we just remove it? + */ + public privateCallStack: Tuple, + /** + * Current public call stack. + */ + public publicCallStack: Tuple, + ) {} + + toBuffer() { + return serializeToBuffer( + this.newNoteHashes, + this.newNullifiers, + this.newL2ToL1Msgs, + this.encryptedLogsHash, + this.unencryptedLogsHash, + this.encryptedLogPreimagesLength, + this.unencryptedLogPreimagesLength, + this.privateCallStack, + this.publicCallStack, + ); + } + + toString() { + return this.toBuffer().toString('hex'); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer or reader to read from. + * @returns Deserialized object. + */ + static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedData { + const reader = BufferReader.asReader(buffer); + return new PrivateAccumulatedData( + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), + reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), + reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + reader.readArray(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest), + reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), + ); + } + + /** + * Deserializes from a string, corresponding to a write in cpp. + * @param str - String to read from. + * @returns Deserialized object. + */ + static fromString(str: string) { + return PrivateAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + } + + static empty() { + return new PrivateAccumulatedData( + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), + makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), + makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), + Fr.zero(), + Fr.zero(), + Fr.zero(), + Fr.zero(), + makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), + makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts similarity index 77% rename from yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_public_inputs.ts rename to yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts index 55152cb8fd1..d5fd7a5bd2a 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_circuit_public_inputs.ts @@ -3,13 +3,13 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { AggregationObject } from '../aggregation_object.js'; import { ValidationRequests } from '../validation_requests.js'; -import { CombinedAccumulatedData } from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; +import { PrivateAccumulatedData } from './private_accumulated_data.js'; /** * Public inputs to the inner private kernel circuit */ -export class PrivateKernelInnerCircuitPublicInputs { +export class PrivateKernelCircuitPublicInputs { constructor( /** * Aggregated proof of all the previous kernel iterations. @@ -26,15 +26,11 @@ export class PrivateKernelInnerCircuitPublicInputs { /** * Data accumulated from both public and private circuits. */ - public end: CombinedAccumulatedData, + public end: PrivateAccumulatedData, /** * Data which is not modified by the circuits. */ public constants: CombinedConstantData, - /** - * Indicates whether the input is for a private or public kernel. - */ - public isPrivate: boolean, ) {} toBuffer() { @@ -44,7 +40,6 @@ export class PrivateKernelInnerCircuitPublicInputs { this.validationRequests, this.end, this.constants, - this.isPrivate, ); } @@ -53,26 +48,24 @@ export class PrivateKernelInnerCircuitPublicInputs { * @param buffer - Buffer or reader to read from. * @returns A new instance of PrivateKernelInnerCircuitPublicInputs. */ - static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelInnerCircuitPublicInputs { + static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelCircuitPublicInputs { const reader = BufferReader.asReader(buffer); - return new PrivateKernelInnerCircuitPublicInputs( + return new PrivateKernelCircuitPublicInputs( reader.readObject(AggregationObject), reader.readObject(Fr), reader.readObject(ValidationRequests), - reader.readObject(CombinedAccumulatedData), + reader.readObject(PrivateAccumulatedData), reader.readObject(CombinedConstantData), - reader.readBoolean(), ); } static empty() { - return new PrivateKernelInnerCircuitPublicInputs( + return new PrivateKernelCircuitPublicInputs( AggregationObject.makeFake(), Fr.zero(), ValidationRequests.empty(), - CombinedAccumulatedData.empty(), + PrivateAccumulatedData.empty(), CombinedConstantData.empty(), - true, ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_data.ts similarity index 79% rename from yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_data.ts rename to yarn-project/circuits.js/src/structs/kernel/private_kernel_data.ts index 580de7e57e3..d7310402ee4 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_data.ts @@ -6,17 +6,17 @@ import { VK_TREE_HEIGHT } from '../../constants.gen.js'; import { Proof, makeEmptyProof } from '../proof.js'; import { type UInt32 } from '../shared.js'; import { VerificationKey } from '../verification_key.js'; -import { PrivateKernelInnerCircuitPublicInputs } from './private_kernel_inner_circuit_public_inputs.js'; +import { PrivateKernelCircuitPublicInputs } from './private_kernel_circuit_public_inputs.js'; /** * Data of the previous kernel iteration in the chain of kernels. */ -export class PrivateKernelInnerData { +export class PrivateKernelData { constructor( /** * Public inputs of the previous kernel. */ - public publicInputs: PrivateKernelInnerCircuitPublicInputs, + public publicInputs: PrivateKernelCircuitPublicInputs, /** * Proof of the previous kernel. */ @@ -43,10 +43,10 @@ export class PrivateKernelInnerData { return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkPath); } - static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelInnerData { + static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelData { const reader = BufferReader.asReader(buffer); return new this( - reader.readObject(PrivateKernelInnerCircuitPublicInputs), + reader.readObject(PrivateKernelCircuitPublicInputs), reader.readObject(Proof), reader.readObject(VerificationKey), reader.readNumber(), @@ -54,9 +54,9 @@ export class PrivateKernelInnerData { ); } - static empty(): PrivateKernelInnerData { - return new PrivateKernelInnerData( - PrivateKernelInnerCircuitPublicInputs.empty(), + static empty(): PrivateKernelData { + return new PrivateKernelData( + PrivateKernelCircuitPublicInputs.empty(), makeEmptyProof(), VerificationKey.makeFake(), 0, diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts index 233f2d015b2..88496556684 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_inner_circuit_private_inputs.ts @@ -1,7 +1,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { PrivateCallData } from './private_call_data.js'; -import { PrivateKernelInnerData } from './private_kernel_inner_data.js'; +import { PrivateKernelData } from './private_kernel_data.js'; /** * Input to the private kernel circuit - Inner call. @@ -11,7 +11,7 @@ export class PrivateKernelInnerCircuitPrivateInputs { /** * The previous kernel data */ - public previousKernel: PrivateKernelInnerData, + public previousKernel: PrivateKernelData, /** * Private calldata corresponding to this iteration of the kernel. */ @@ -34,7 +34,7 @@ export class PrivateKernelInnerCircuitPrivateInputs { static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelInnerCircuitPrivateInputs { const reader = BufferReader.asReader(buffer); return new PrivateKernelInnerCircuitPrivateInputs( - reader.readObject(PrivateKernelInnerData), + reader.readObject(PrivateKernelData), reader.readObject(PrivateCallData), ); } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts index ad629499041..cabf3d15f7f 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_private_inputs.ts @@ -1,3 +1,4 @@ +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { @@ -6,11 +7,11 @@ import { MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, } from '../../constants.gen.js'; -import { type GrumpkinPrivateKey } from '../../index.js'; -import { Fr, GrumpkinScalar } from '../index.js'; +import { type GrumpkinPrivateKey } from '../../types/grumpkin_private_key.js'; +import { countAccumulatedItems } from '../../utils/index.js'; import { type NullifierReadRequestHints, nullifierReadRequestHintsFromBuffer } from '../read_request_hints.js'; import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; -import { PrivateKernelInnerData } from './private_kernel_inner_data.js'; +import { PrivateKernelData } from './private_kernel_data.js'; /** * Input to the private kernel circuit - tail call. @@ -20,7 +21,7 @@ export class PrivateKernelTailCircuitPrivateInputs { /** * The previous kernel data */ - public previousKernel: PrivateKernelInnerData, + public previousKernel: PrivateKernelData, /** * The sorted new note hashes. */ @@ -55,6 +56,10 @@ export class PrivateKernelTailCircuitPrivateInputs { public masterNullifierSecretKeys: Tuple, ) {} + isForPublic() { + return countAccumulatedItems(this.previousKernel.publicInputs.end.publicCallStack) > 0; + } + /** * Serialize this as a buffer. * @returns The buffer. @@ -81,7 +86,7 @@ export class PrivateKernelTailCircuitPrivateInputs { static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelTailCircuitPrivateInputs { const reader = BufferReader.asReader(buffer); return new PrivateKernelTailCircuitPrivateInputs( - reader.readObject(PrivateKernelInnerData), + reader.readObject(PrivateKernelData), reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), reader.readNumbers(MAX_NEW_NOTE_HASHES_PER_TX), reader.readArray(MAX_NOTE_HASH_READ_REQUESTS_PER_TX, Fr), diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.test.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.test.ts new file mode 100644 index 00000000000..3f379f8a970 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.test.ts @@ -0,0 +1,16 @@ +import { makePrivateKernelTailCircuitPublicInputs } from '../../tests/factories.js'; +import { PrivateKernelTailCircuitPublicInputs } from './private_kernel_tail_circuit_public_inputs.js'; + +describe('PrivateKernelTailCircuitPublicInputs', () => { + it('Data for public after serialization and deserialization is equal to the original', () => { + const original = makePrivateKernelTailCircuitPublicInputs(123, true); + const serialized = PrivateKernelTailCircuitPublicInputs.fromBuffer(original.toBuffer()); + expect(original).toEqual(serialized); + }); + + it('Data for rollup after serialization and deserialization is equal to the original', () => { + const original = makePrivateKernelTailCircuitPublicInputs(123, false); + const serialized = PrivateKernelTailCircuitPublicInputs.fromBuffer(original.toBuffer()); + expect(original).toEqual(serialized); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts index 2429a6f71cc..641f0ded81f 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_circuit_public_inputs.ts @@ -1,91 +1,203 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; +import { MAX_NEW_NULLIFIERS_PER_TX } from '../../constants.gen.js'; +import { countAccumulatedItems, mergeAccumulatedData } from '../../utils/index.js'; import { AggregationObject } from '../aggregation_object.js'; +import { RevertCode } from '../revert_code.js'; import { RollupValidationRequests } from '../rollup_validation_requests.js'; -import { PrivateAccumulatedNonRevertibleData, PrivateAccumulatedRevertibleData } from './combined_accumulated_data.js'; +import { ValidationRequests } from '../validation_requests.js'; +import { CombinedAccumulatedData } from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; +import { KernelCircuitPublicInputs } from './kernel_circuit_public_inputs.js'; +import { PublicAccumulatedData } from './public_accumulated_data.js'; +import { PublicKernelCircuitPublicInputs } from './public_kernel_circuit_public_inputs.js'; -/** - * Output from to the private kernel circuit - tail call. - */ -export class PrivateKernelTailCircuitPublicInputs { +export class PartialPrivateTailPublicInputsForPublic { constructor( /** - * Aggregated proof of all the previous kernel iterations. + * Validation requests accumulated from public functions. */ - public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations + public validationRequests: ValidationRequests, /** - * Validation requests for the rollup accumulated during private execution. + * Accumulated side effects and enqueued calls that are not revertible. */ - public rollupValidationRequests: RollupValidationRequests, + public endNonRevertibleData: PublicAccumulatedData, /** - * Accumulated side effects that are not revertible. + * Data accumulated from both public and private circuits. */ - public endNonRevertibleData: PrivateAccumulatedNonRevertibleData, + public end: PublicAccumulatedData, + ) {} + + get needsSetup() { + return !this.endNonRevertibleData.publicCallStack[1].isEmpty(); + } + + get needsAppLogic() { + return !this.end.publicCallStack[0].isEmpty(); + } + + get needsTeardown() { + return !this.endNonRevertibleData.publicCallStack[0].isEmpty(); + } + + static fromBuffer(buffer: Buffer | BufferReader): PartialPrivateTailPublicInputsForPublic { + const reader = BufferReader.asReader(buffer); + return new PartialPrivateTailPublicInputsForPublic( + reader.readObject(ValidationRequests), + reader.readObject(PublicAccumulatedData), + reader.readObject(PublicAccumulatedData), + ); + } + + toBuffer() { + return serializeToBuffer(this.validationRequests, this.endNonRevertibleData, this.end); + } + + static empty() { + return new PartialPrivateTailPublicInputsForPublic( + ValidationRequests.empty(), + PublicAccumulatedData.empty(), + PublicAccumulatedData.empty(), + ); + } +} + +export class PartialPrivateTailPublicInputsForRollup { + constructor(public rollupValidationRequests: RollupValidationRequests, public end: CombinedAccumulatedData) {} + + static fromBuffer(buffer: Buffer | BufferReader): PartialPrivateTailPublicInputsForRollup { + const reader = BufferReader.asReader(buffer); + return new PartialPrivateTailPublicInputsForRollup( + reader.readObject(RollupValidationRequests), + reader.readObject(CombinedAccumulatedData), + ); + } + + toBuffer() { + return serializeToBuffer(this.rollupValidationRequests, this.end); + } + + static empty() { + return new PartialPrivateTailPublicInputsForRollup( + RollupValidationRequests.empty(), + CombinedAccumulatedData.empty(), + ); + } +} + +export class PrivateKernelTailCircuitPublicInputs { + constructor( /** - * Data accumulated from both public and private circuits. + * Aggregated proof of all the previous kernel iterations. */ - public end: PrivateAccumulatedRevertibleData, + public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations /** * Data which is not modified by the circuits. */ public constants: CombinedConstantData, /** - * Indicates whether the setup kernel is needed. - */ - public needsSetup: boolean, - /** - * Indicates whether the app logic kernel is needed. - */ - public needsAppLogic: boolean, - /** - * Indicates whether the teardown kernel is needed. + * Indicates whether execution of the public circuit reverted. */ - public needsTeardown: boolean, - ) {} + public revertCode: RevertCode, + public forPublic?: PartialPrivateTailPublicInputsForPublic, + public forRollup?: PartialPrivateTailPublicInputsForRollup, + ) { + if (!forPublic && !forRollup) { + throw new Error('Missing partial public inputs for private tail circuit.'); + } + if (forPublic && forRollup) { + throw new Error( + 'Cannot create PrivateKernelTailCircuitPublicInputs that is for both public kernel circuit and rollup circuit.', + ); + } + } - toBuffer() { - return serializeToBuffer( + toPublicKernelCircuitPublicInputs() { + if (!this.forPublic) { + throw new Error('Private tail public inputs is not for public circuit.'); + } + return new PublicKernelCircuitPublicInputs( + this.aggregationObject, + this.forPublic.validationRequests, + this.forPublic.endNonRevertibleData, + this.forPublic.end, + this.constants, + this.revertCode, + ); + } + + toKernelCircuitPublicInputs() { + if (!this.forRollup) { + throw new Error('Private tail public inputs is not for rollup circuit.'); + } + return new KernelCircuitPublicInputs( this.aggregationObject, - this.rollupValidationRequests, - this.endNonRevertibleData, - this.end, + this.forRollup.rollupValidationRequests, + this.forRollup.end, this.constants, - this.needsSetup, - this.needsAppLogic, - this.needsTeardown, + this.revertCode, ); } - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer or reader to read from. - * @returns A new instance of PrivateKernelTailCircuitPublicInputs. - */ + numberOfPublicCallRequests() { + return this.forPublic + ? countAccumulatedItems(this.forPublic.endNonRevertibleData.publicCallStack) + + countAccumulatedItems(this.forPublic.end.publicCallStack) + : 0; + } + + getNonEmptyNoteHashes() { + const noteHashes = this.forPublic + ? mergeAccumulatedData( + MAX_NEW_NULLIFIERS_PER_TX, + this.forPublic.endNonRevertibleData.newNoteHashes, + this.forPublic.end.newNoteHashes, + ) + : this.forRollup!.end.newNoteHashes; + return noteHashes.filter(n => !n.isEmpty()); + } + + getNonEmptyNullifiers() { + const nullifiers = this.forPublic + ? mergeAccumulatedData( + MAX_NEW_NULLIFIERS_PER_TX, + this.forPublic.endNonRevertibleData.newNullifiers, + this.forPublic.end.newNullifiers, + ) + : this.forRollup!.end.newNullifiers; + return nullifiers.filter(n => !n.isEmpty()); + } + static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelTailCircuitPublicInputs { const reader = BufferReader.asReader(buffer); + const isForPublic = reader.readBoolean(); return new PrivateKernelTailCircuitPublicInputs( reader.readObject(AggregationObject), - reader.readObject(RollupValidationRequests), - reader.readObject(PrivateAccumulatedNonRevertibleData), - reader.readObject(PrivateAccumulatedRevertibleData), reader.readObject(CombinedConstantData), - reader.readBoolean(), - reader.readBoolean(), - reader.readBoolean(), + reader.readObject(RevertCode), + isForPublic ? reader.readObject(PartialPrivateTailPublicInputsForPublic) : undefined, + !isForPublic ? reader.readObject(PartialPrivateTailPublicInputsForRollup) : undefined, + ); + } + + toBuffer() { + const isForPublic = !!this.forPublic; + return serializeToBuffer( + isForPublic, + this.aggregationObject, + this.constants, + this.revertCode, + isForPublic ? this.forPublic!.toBuffer() : this.forRollup!.toBuffer(), ); } static empty() { return new PrivateKernelTailCircuitPublicInputs( AggregationObject.makeFake(), - RollupValidationRequests.empty(), - PrivateAccumulatedNonRevertibleData.empty(), - PrivateAccumulatedRevertibleData.empty(), CombinedConstantData.empty(), - true, - true, - true, + RevertCode.OK, + undefined, + PartialPrivateTailPublicInputsForRollup.empty(), ); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_data.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_data.ts deleted file mode 100644 index 837b2a138e3..00000000000 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel_tail_data.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { makeTuple } from '@aztec/foundation/array'; -import { Fr } from '@aztec/foundation/fields'; -import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; - -import { VK_TREE_HEIGHT } from '../../constants.gen.js'; -import { Proof, makeEmptyProof } from '../proof.js'; -import { type UInt32 } from '../shared.js'; -import { VerificationKey } from '../verification_key.js'; -import { PrivateKernelTailCircuitPublicInputs } from './private_kernel_tail_circuit_public_inputs.js'; - -/** - * Data of the private kernel tail. - */ -export class PrivateKernelTailData { - constructor( - /** - * Outputs of the private kernel tail. - */ - public publicInputs: PrivateKernelTailCircuitPublicInputs, - /** - * Proof of the previous kernel. - */ - public proof: Proof, - /** - * Verification key of the previous kernel. - */ - public vk: VerificationKey, - /** - * Index of the previous kernel's vk in a tree of vks. - */ - public vkIndex: UInt32, - /** - * Sibling path of the previous kernel's vk in a tree of vks. - */ - public vkPath: Tuple, - ) {} - - static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelTailData { - const reader = BufferReader.asReader(buffer); - return new this( - reader.readObject(PrivateKernelTailCircuitPublicInputs), - reader.readObject(Proof), - reader.readObject(VerificationKey), - reader.readNumber(), - reader.readArray(VK_TREE_HEIGHT, Fr), - ); - } - - static empty(): PrivateKernelTailData { - return new this( - PrivateKernelTailCircuitPublicInputs.empty(), - makeEmptyProof(), - VerificationKey.makeFake(), - 0, - makeTuple(VK_TREE_HEIGHT, Fr.zero), - ); - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkPath); - } -} diff --git a/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts new file mode 100644 index 00000000000..737a4ce608f --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/public_accumulated_data.ts @@ -0,0 +1,150 @@ +import { makeTuple } from '@aztec/foundation/array'; +import { Fr } from '@aztec/foundation/fields'; +import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; + +import { inspect } from 'util'; + +import { + type MAX_NEW_L2_TO_L1_MSGS_PER_CALL, + MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, +} from '../../constants.gen.js'; +import { CallRequest } from '../call_request.js'; +import { PublicDataUpdateRequest } from '../public_data_update_request.js'; +import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; + +export class PublicAccumulatedData { + constructor( + /** + * The new note hashes made in this transaction. + */ + public newNoteHashes: Tuple, + /** + * The new nullifiers made in this transaction. + */ + public newNullifiers: Tuple, + /** + * All the new L2 to L1 messages created in this transaction. + */ + public newL2ToL1Msgs: Tuple, + /** + * Accumulated encrypted logs hash from all the previous kernel iterations. + * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. + */ + public encryptedLogsHash: Fr, + /** + * Accumulated unencrypted logs hash from all the previous kernel iterations. + * Note: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. + */ + public unencryptedLogsHash: Fr, + /** + * Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations + */ + public encryptedLogPreimagesLength: Fr, + /** + * Total accumulated length of the unencrypted log preimages emitted in all the previous kernel iterations + */ + public unencryptedLogPreimagesLength: Fr, + /** + * All the public data update requests made in this transaction. + */ + public publicDataUpdateRequests: Tuple, + /** + * Current public call stack. + */ + public publicCallStack: Tuple, + ) {} + + toBuffer() { + return serializeToBuffer( + this.newNoteHashes, + this.newNullifiers, + this.newL2ToL1Msgs, + this.encryptedLogsHash, + this.unencryptedLogsHash, + this.encryptedLogPreimagesLength, + this.unencryptedLogPreimagesLength, + this.publicDataUpdateRequests, + this.publicCallStack, + ); + } + + toString() { + return this.toBuffer().toString('hex'); + } + + isEmpty(): boolean { + return ( + this.newNoteHashes.every(x => x.isEmpty()) && + this.newNullifiers.every(x => x.isEmpty()) && + this.newL2ToL1Msgs.every(x => x.isZero()) && + this.encryptedLogsHash.isZero() && + this.unencryptedLogsHash.isZero() && + this.encryptedLogPreimagesLength.isZero() && + this.unencryptedLogPreimagesLength.isZero() && + this.publicDataUpdateRequests.every(x => x.isEmpty()) && + this.publicCallStack.every(x => x.isEmpty()) + ); + } + + [inspect.custom]() { + // print out the non-empty fields + return `PublicAccumulatedData { + newNoteHashes: [${this.newNoteHashes.map(h => h.toString()).join(', ')}], + newNullifiers: [${this.newNullifiers.map(h => h.toString()).join(', ')}], + newL2ToL1Msgs: [${this.newL2ToL1Msgs.map(h => h.toString()).join(', ')}], + encryptedLogsHash: [${this.encryptedLogsHash}], + unencryptedLogsHash: [${this.unencryptedLogsHash}], + encryptedLogPreimagesLength: ${this.encryptedLogPreimagesLength} + unencryptedLogPreimagesLength: ${this.unencryptedLogPreimagesLength} + publicDataUpdateRequests: [${this.publicDataUpdateRequests.map(h => h.toString()).join(', ')}], + publicCallStack: [${this.publicCallStack.map(h => h.toString()).join(', ')}], +}`; + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer or reader to read from. + * @returns Deserialized object. + */ + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new this( + reader.readArray(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect), + reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), + reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + reader.readArray(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), + reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), + ); + } + + /** + * Deserializes from a string, corresponding to a write in cpp. + * @param str - String to read from. + * @returns Deserialized object. + */ + static fromString(str: string) { + return this.fromBuffer(Buffer.from(str, 'hex')); + } + + static empty() { + return new this( + makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, SideEffect.empty), + makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), + makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), + Fr.zero(), + Fr.zero(), + Fr.zero(), + Fr.zero(), + makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), + makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts index a6d6f1b5298..207a1db74d5 100644 --- a/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel_circuit_public_inputs.ts @@ -3,31 +3,21 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { inspect } from 'util'; import { AggregationObject } from '../aggregation_object.js'; -import { RollupValidationRequests } from '../rollup_validation_requests.js'; +import { RevertCode } from '../revert_code.js'; import { ValidationRequests } from '../validation_requests.js'; -import { - CombinedAccumulatedData, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, -} from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; +import { PublicAccumulatedData } from './public_accumulated_data.js'; /** * Outputs from the public kernel circuits. * All Public kernels use this shape for outputs. */ export class PublicKernelCircuitPublicInputs { - private combined: CombinedAccumulatedData | undefined = undefined; - constructor( /** * Aggregated proof of all the previous kernel iterations. */ public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations - /** - * Validation requests forwarded to the rollup accumulated from public functions. - */ - public rollupValidationRequests: RollupValidationRequests, /** * Validation requests accumulated from public functions. */ @@ -35,52 +25,42 @@ export class PublicKernelCircuitPublicInputs { /** * Accumulated side effects and enqueued calls that are not revertible. */ - public endNonRevertibleData: PublicAccumulatedNonRevertibleData, + public endNonRevertibleData: PublicAccumulatedData, /** * Data accumulated from both public and private circuits. */ - public end: PublicAccumulatedRevertibleData, + public end: PublicAccumulatedData, /** * Data which is not modified by the circuits. */ public constants: CombinedConstantData, /** - * Indicates whether the setup kernel is needed. - */ - public needsSetup: boolean, - /** - * Indicates whether the app logic kernel is needed. + * Indicates whether execution of the public circuit reverted. */ - public needsAppLogic: boolean, - /** - * Indicates whether the teardown kernel is needed. - */ - public needsTeardown: boolean, + public revertCode: RevertCode, ) {} toBuffer() { return serializeToBuffer( this.aggregationObject, - this.rollupValidationRequests, this.validationRequests, this.endNonRevertibleData, this.end, this.constants, - this.needsSetup, - this.needsAppLogic, - this.needsTeardown, + this.revertCode, ); } - get combinedData() { - if (this.needsSetup || this.needsAppLogic || this.needsTeardown) { - throw new Error('Cannot combine data when the circuit is not finished'); - } + get needsSetup() { + return !this.endNonRevertibleData.publicCallStack[1].isEmpty(); + } + + get needsAppLogic() { + return !this.end.publicCallStack[0].isEmpty(); + } - if (!this.combined) { - this.combined = CombinedAccumulatedData.recombine(this.endNonRevertibleData, this.end); - } - return this.combined; + get needsTeardown() { + return !this.endNonRevertibleData.publicCallStack[0].isEmpty(); } /** @@ -92,42 +72,33 @@ export class PublicKernelCircuitPublicInputs { const reader = BufferReader.asReader(buffer); return new PublicKernelCircuitPublicInputs( reader.readObject(AggregationObject), - reader.readObject(RollupValidationRequests), reader.readObject(ValidationRequests), - reader.readObject(PublicAccumulatedNonRevertibleData), - reader.readObject(PublicAccumulatedRevertibleData), + reader.readObject(PublicAccumulatedData), + reader.readObject(PublicAccumulatedData), reader.readObject(CombinedConstantData), - reader.readBoolean(), - reader.readBoolean(), - reader.readBoolean(), + reader.readObject(RevertCode), ); } static empty() { return new PublicKernelCircuitPublicInputs( AggregationObject.makeFake(), - RollupValidationRequests.empty(), ValidationRequests.empty(), - PublicAccumulatedNonRevertibleData.empty(), - PublicAccumulatedRevertibleData.empty(), + PublicAccumulatedData.empty(), + PublicAccumulatedData.empty(), CombinedConstantData.empty(), - false, - false, - false, + RevertCode.OK, ); } [inspect.custom]() { return `PublicKernelCircuitPublicInputs { - aggregationObject: ${this.aggregationObject}, - rollupValidationRequests: ${inspect(this.rollupValidationRequests)}, - validationRequests: ${inspect(this.validationRequests)}, - endNonRevertibleData: ${inspect(this.endNonRevertibleData)}, - end: ${inspect(this.end)}, - constants: ${this.constants}, - needsSetup: ${this.needsSetup}, - needsAppLogic: ${this.needsAppLogic}, - needsTeardown: ${this.needsTeardown}, -}`; + aggregationObject: ${this.aggregationObject}, + validationRequests: ${inspect(this.validationRequests)}, + endNonRevertibleData: ${inspect(this.endNonRevertibleData)}, + end: ${inspect(this.end)}, + constants: ${this.constants}, + revertCode: ${this.revertCode} + }`; } } diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts index a1eac84c3e5..355900afe9e 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts @@ -4,12 +4,11 @@ import { type FieldsOf } from '@aztec/foundation/types'; import { type ARCHIVE_HEIGHT, - type MAX_PUBLIC_DATA_READS_PER_TX, type MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, type PUBLIC_DATA_TREE_HEIGHT, } from '../../constants.gen.js'; import { GlobalVariables } from '../global_variables.js'; -import { type RollupKernelData } from '../kernel/rollup_kernel_data.js'; +import { type KernelData } from '../kernel/kernel_data.js'; import { type MembershipWitness } from '../membership_witness.js'; import { type PartialStateReference } from '../partial_state_reference.js'; import { type UInt32 } from '../shared.js'; @@ -88,7 +87,7 @@ export class ConstantRollupData { export class BaseRollupInputs { constructor( /** Data of the 2 kernels that preceded this base rollup circuit. */ - public kernelData: RollupKernelData, + public kernelData: KernelData, /** Partial state reference at the start of the rollup. */ public start: PartialStateReference, /** Hints used while proving state diff validity. */ @@ -120,19 +119,6 @@ export class BaseRollupInputs { typeof MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX >, - /** - * Preimages of leaves which are to be read by the public data reads. - */ - public publicDataReadsPreimages: Tuple, - /** - * Sibling paths of leaves which are to be read by the public data reads. - * Each item in the array is the sibling path that corresponds to a read request. - */ - public publicDataReadsMembershipWitnesses: Tuple< - MembershipWitness, - typeof MAX_PUBLIC_DATA_READS_PER_TX - >, - /** * Membership witnesses of blocks referred by each of the 2 kernels. */ @@ -156,8 +142,6 @@ export class BaseRollupInputs { fields.sortedPublicDataWritesIndexes, fields.lowPublicDataWritesPreimages, fields.lowPublicDataWritesMembershipWitnesses, - fields.publicDataReadsPreimages, - fields.publicDataReadsMembershipWitnesses, fields.archiveRootMembershipWitness, fields.constants, ] as const; diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 176e9248d32..ea651678f24 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -45,10 +45,6 @@ import { MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, @@ -65,10 +61,6 @@ import { MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MaxBlockNumber, MembershipWitness, MergeRollupInputs, @@ -86,20 +78,20 @@ import { PUBLIC_DATA_SUBTREE_SIBLING_PATH_LENGTH, PUBLIC_DATA_TREE_HEIGHT, ParityPublicInputs, + PartialPrivateTailPublicInputsForPublic, + PartialPrivateTailPublicInputsForRollup, PartialStateReference, Point, PreviousRollupData, - PrivateAccumulatedNonRevertibleData, - PrivateAccumulatedRevertibleData, + PrivateAccumulatedData, PrivateCallData, PrivateCallStackItem, PrivateCircuitPublicInputs, - PrivateKernelInnerCircuitPublicInputs, - PrivateKernelInnerData, + PrivateKernelCircuitPublicInputs, + PrivateKernelData, PrivateKernelTailCircuitPublicInputs, Proof, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, + PublicAccumulatedData, PublicCallData, PublicCallRequest, PublicCallStackItem, @@ -136,10 +128,10 @@ import { import { ContentCommitment, NUM_BYTES_PER_SHA256 } from '../structs/content_commitment.js'; import { GlobalVariables } from '../structs/global_variables.js'; import { Header } from '../structs/header.js'; +import { KernelCircuitPublicInputs } from '../structs/kernel/kernel_circuit_public_inputs.js'; +import { KernelData } from '../structs/kernel/kernel_data.js'; import { PrivateKernelInitCircuitPrivateInputs } from '../structs/kernel/private_kernel_init_circuit_private_inputs.js'; import { PrivateKernelInnerCircuitPrivateInputs } from '../structs/kernel/private_kernel_inner_circuit_private_inputs.js'; -import { RollupKernelCircuitPublicInputs } from '../structs/kernel/rollup_kernel_circuit_public_inputs.js'; -import { RollupKernelData } from '../structs/kernel/rollup_kernel_data.js'; import { RollupValidationRequests } from '../structs/rollup_validation_requests.js'; import { ValidationRequests } from '../structs/validation_requests.js'; @@ -295,17 +287,24 @@ export function makeCombinedAccumulatedData(seed = 1, full = false): CombinedAcc const tupleGenerator = full ? makeTuple : makeHalfFullTuple; return new CombinedAccumulatedData( - RevertCode.OK, - tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), - tupleGenerator(MAX_NEW_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), - tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), - tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), - tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120, SideEffect.empty), + tupleGenerator( + MAX_NEW_NULLIFIERS_PER_TX, + sideEffectLinkedFromNumber, + seed + 0x200, + SideEffectLinkedToNoteHash.empty, + ), + tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600, Fr.zero), fr(seed + 0x700), // encrypted logs hash fr(seed + 0x800), // unencrypted logs hash fr(seed + 0x900), // encrypted_log_preimages_length fr(seed + 0xa00), // unencrypted_log_preimages_length - tupleGenerator(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0xd00), + tupleGenerator( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + makePublicDataUpdateRequest, + seed + 0xd00, + PublicDataUpdateRequest.empty, + ), ); } @@ -314,69 +313,55 @@ export function makeCombinedAccumulatedData(seed = 1, full = false): CombinedAcc * @param seed - The seed to use for generating the accumulated data. * @returns An accumulated data. */ -export function makeCombinedAccumulatedRevertibleData(seed = 1, full = false): PublicAccumulatedRevertibleData { +export function makePublicAccumulatedData(seed = 1, full = false): PublicAccumulatedData { const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - return new PublicAccumulatedRevertibleData( - tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120), - tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), - tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), - tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), - tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600), + return new PublicAccumulatedData( + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120, SideEffect.empty), + tupleGenerator( + MAX_NEW_NULLIFIERS_PER_TX, + sideEffectLinkedFromNumber, + seed + 0x200, + SideEffectLinkedToNoteHash.empty, + ), + tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600, Fr.zero), fr(seed + 0x700), // encrypted logs hash fr(seed + 0x800), // unencrypted logs hash fr(seed + 0x900), // encrypted_log_preimages_length fr(seed + 0xa00), // unencrypted_log_preimages_length - tupleGenerator(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0xd00), + tupleGenerator( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + makePublicDataUpdateRequest, + seed + 0xd00, + PublicDataUpdateRequest.empty, + ), + tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500, CallRequest.empty), ); } /** - * Creates arbitrary final accumulated data. - * @param seed - The seed to use for generating the final accumulated data. - * @returns A final accumulated data. + * Creates arbitrary accumulated data. + * @param seed - The seed to use for generating the accumulated data. + * @returns An accumulated data. */ -export function makeFinalAccumulatedData(seed = 1, full = false): PrivateAccumulatedRevertibleData { +export function makePrivateAccumulatedData(seed = 1, full = false) { const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - return new PrivateAccumulatedRevertibleData( - tupleGenerator(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x100), - tupleGenerator(MAX_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), - tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400), - tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), - tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600), + return new PrivateAccumulatedData( + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x120, SideEffect.empty), + tupleGenerator( + MAX_NEW_NULLIFIERS_PER_TX, + sideEffectLinkedFromNumber, + seed + 0x200, + SideEffectLinkedToNoteHash.empty, + ), + tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600, Fr.zero), fr(seed + 0x700), // encrypted logs hash fr(seed + 0x800), // unencrypted logs hash fr(seed + 0x900), // encrypted_log_preimages_length fr(seed + 0xa00), // unencrypted_log_preimages_length - ); -} - -/** - * Creates arbitrary accumulated data for a Tx's non-revertible side effects. - * @param seed - The seed to use for generating the data. - * @returns An instance of AccumulatedNonRevertibleData. - */ -export function makeAccumulatedNonRevertibleData(seed = 1, full = false): PrivateAccumulatedNonRevertibleData { - const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - - return new PrivateAccumulatedNonRevertibleData( - RevertCode.OK, - tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), - tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), - tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), - ); -} - -export function makeCombinedAccumulatedNonRevertibleData(seed = 1, full = false): PublicAccumulatedNonRevertibleData { - const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - - return new PublicAccumulatedNonRevertibleData( - RevertCode.OK, - tupleGenerator(MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, sideEffectFromNumber, seed + 0x101), - tupleGenerator(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x201), - tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x501), - tupleGenerator(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0x601), + tupleGenerator(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x400, CallRequest.empty), + tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500, CallRequest.empty), ); } @@ -428,15 +413,25 @@ export function makePublicCircuitPublicInputs( return new PublicCircuitPublicInputs( makeCallContext(seed, storageContractAddress), fr(seed + 0x100), - tupleGenerator(RETURN_VALUES_LENGTH, fr, seed + 0x200), - tupleGenerator(MAX_NULLIFIER_READ_REQUESTS_PER_CALL, makeReadRequest, seed + 0x400), - tupleGenerator(MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, makeReadRequest, seed + 0x420), - tupleGenerator(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, makeContractStorageUpdateRequest, seed + 0x400), - tupleGenerator(MAX_PUBLIC_DATA_READS_PER_CALL, makeContractStorageRead, seed + 0x500), - tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600), - tupleGenerator(MAX_NEW_NOTE_HASHES_PER_CALL, makeNewSideEffect, seed + 0x700), - tupleGenerator(MAX_NEW_NULLIFIERS_PER_CALL, makeNewSideEffectLinkedToNoteHash, seed + 0x800), - tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x900), + tupleGenerator(RETURN_VALUES_LENGTH, fr, seed + 0x200, Fr.zero), + tupleGenerator(MAX_NULLIFIER_READ_REQUESTS_PER_CALL, makeReadRequest, seed + 0x400, ReadRequest.empty), + tupleGenerator(MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, makeReadRequest, seed + 0x420, ReadRequest.empty), + tupleGenerator( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, + makeContractStorageUpdateRequest, + seed + 0x400, + ContractStorageUpdateRequest.empty, + ), + tupleGenerator(MAX_PUBLIC_DATA_READS_PER_CALL, makeContractStorageRead, seed + 0x500, ContractStorageRead.empty), + tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, fr, seed + 0x600, Fr.zero), + tupleGenerator(MAX_NEW_NOTE_HASHES_PER_CALL, makeNewSideEffect, seed + 0x700, SideEffect.empty), + tupleGenerator( + MAX_NEW_NULLIFIERS_PER_CALL, + makeNewSideEffectLinkedToNoteHash, + seed + 0x800, + SideEffectLinkedToNoteHash.empty, + ), + tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, makeL2ToL1Message, seed + 0x900, L2ToL1Message.empty), fr(seed + 0xa00), fr(seed + 0xa01), fr(seed + 0x901), @@ -458,49 +453,26 @@ export function makePublicKernelCircuitPublicInputs( ): PublicKernelCircuitPublicInputs { return new PublicKernelCircuitPublicInputs( makeAggregationObject(seed), - makeRollupValidationRequests(seed), makeValidationRequests(seed), - makeCombinedAccumulatedNonRevertibleData(seed, fullAccumulatedData), - makeCombinedAccumulatedRevertibleData(seed, fullAccumulatedData), + makePublicAccumulatedData(seed, fullAccumulatedData), + makePublicAccumulatedData(seed, fullAccumulatedData), makeConstantData(seed + 0x100), - true, - true, - true, + RevertCode.OK, ); } -/** - * Creates arbitrary public kernel circuit public inputs. - * @param seed - The seed to use for generating the kernel circuit public inputs. - * @returns Public kernel circuit public inputs. - */ -export function makeRollupKernelCircuitPublicInputs( - seed = 1, - fullAccumulatedData = true, -): RollupKernelCircuitPublicInputs { - return new RollupKernelCircuitPublicInputs( - makeAggregationObject(seed), - makeCombinedAccumulatedData(seed, fullAccumulatedData), - makeConstantData(seed + 0x100), - makeRollupValidationRequests(seed), - ); -} /** * Creates arbitrary private kernel inner circuit public inputs. * @param seed - The seed to use for generating the kernel circuit public inputs. * @returns Private kernel circuit public inputs. */ -export function makePrivateKernelInnerCircuitPublicInputs( - seed = 1, - full = true, -): PrivateKernelInnerCircuitPublicInputs { - return new PrivateKernelInnerCircuitPublicInputs( +export function makePrivateKernelCircuitPublicInputs(seed = 1, full = true): PrivateKernelCircuitPublicInputs { + return new PrivateKernelCircuitPublicInputs( makeAggregationObject(seed), fr(seed + 0x100), makeValidationRequests(seed), - makeCombinedAccumulatedData(seed, full), + makePrivateAccumulatedData(seed, full), makeConstantData(seed + 0x100), - true, ); } @@ -509,16 +481,44 @@ export function makePrivateKernelInnerCircuitPublicInputs( * @param seed - The seed to use for generating the kernel circuit public inputs. * @returns Private kernel tail circuit public inputs. */ -export function makePrivateKernelTailCircuitPublicInputs(seed = 1, full = true): PrivateKernelTailCircuitPublicInputs { +export function makePrivateKernelTailCircuitPublicInputs( + seed = 1, + isForPublic = true, +): PrivateKernelTailCircuitPublicInputs { + const forPublic = isForPublic + ? new PartialPrivateTailPublicInputsForPublic( + ValidationRequests.empty(), + makePublicAccumulatedData(seed + 0x100, false), + makePublicAccumulatedData(seed + 0x200, false), + ) + : undefined; + const forRollup = !isForPublic + ? new PartialPrivateTailPublicInputsForRollup( + makeRollupValidationRequests(seed), + makeCombinedAccumulatedData(seed + 0x100), + ) + : undefined; return new PrivateKernelTailCircuitPublicInputs( makeAggregationObject(seed), - makeRollupValidationRequests(seed), - makeAccumulatedNonRevertibleData(seed + 0x100, full), - makeFinalAccumulatedData(seed + 0x200, full), makeConstantData(seed + 0x300), - true, - true, - true, + RevertCode.OK, + forPublic, + forRollup, + ); +} + +/** + * Creates arbitrary public kernel circuit public inputs. + * @param seed - The seed to use for generating the kernel circuit public inputs. + * @returns Public kernel circuit public inputs. + */ +export function makeKernelCircuitPublicInputs(seed = 1, fullAccumulatedData = true): KernelCircuitPublicInputs { + return new KernelCircuitPublicInputs( + makeAggregationObject(seed), + makeRollupValidationRequests(seed), + makeCombinedAccumulatedData(seed, fullAccumulatedData), + makeConstantData(seed + 0x100), + RevertCode.OK, ); } @@ -652,9 +652,9 @@ export function makePublicKernelData(seed = 1, kernelPublicInputs?: PublicKernel * @param kernelPublicInputs - The public kernel public inputs to use for generating the public kernel data. * @returns A previous kernel data. */ -export function makeRollupKernelData(seed = 1, kernelPublicInputs?: RollupKernelCircuitPublicInputs): RollupKernelData { - return new RollupKernelData( - kernelPublicInputs ?? makeRollupKernelCircuitPublicInputs(seed, true), +export function makeRollupKernelData(seed = 1, kernelPublicInputs?: KernelCircuitPublicInputs): KernelData { + return new KernelData( + kernelPublicInputs ?? makeKernelCircuitPublicInputs(seed, true), new Proof(Buffer.alloc(16, seed + 0x80)), makeVerificationKey(), 0x42, @@ -668,12 +668,9 @@ export function makeRollupKernelData(seed = 1, kernelPublicInputs?: RollupKernel * @param inputs - The kernel public inputs to use for generating the private kernel inner data. * @returns A previous kernel data. */ -export function makePrivateKernelInnerData( - seed = 1, - inputs?: PrivateKernelInnerCircuitPublicInputs, -): PrivateKernelInnerData { - return new PrivateKernelInnerData( - inputs ?? makePrivateKernelInnerCircuitPublicInputs(seed, true), +export function makePrivateKernelInnerData(seed = 1, inputs?: PrivateKernelCircuitPublicInputs): PrivateKernelData { + return new PrivateKernelData( + inputs ?? makePrivateKernelCircuitPublicInputs(seed, true), new Proof(Buffer.alloc(16, seed + 0x80)), makeVerificationKey(), 0x42, @@ -1249,18 +1246,6 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { seed + 0x8400, ); - const publicDataReadsPreimages = makeTuple( - MAX_PUBLIC_DATA_READS_PER_TX, - makePublicDataTreeLeafPreimage, - seed + 0x8800, - ); - - const publicDataReadsMembershipWitnesses = makeTuple( - MAX_PUBLIC_DATA_READS_PER_TX, - i => makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, i), - seed + 0x8a00, - ); - const archiveRootMembershipWitness = makeMembershipWitness(ARCHIVE_HEIGHT, seed + 0x9000); const constants = makeConstantBaseRollupData(0x100); @@ -1273,8 +1258,6 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { sortedPublicDataWritesIndexes, lowPublicDataWritesPreimages, lowPublicDataWritesMembershipWitnesses, - publicDataReadsPreimages, - publicDataReadsMembershipWitnesses, archiveRootMembershipWitness, constants, }); diff --git a/yarn-project/circuits.js/src/hints/utils.ts b/yarn-project/circuits.js/src/utils/index.ts similarity index 97% rename from yarn-project/circuits.js/src/hints/utils.ts rename to yarn-project/circuits.js/src/utils/index.ts index c63dad6aa8d..9863d50ffce 100644 --- a/yarn-project/circuits.js/src/hints/utils.ts +++ b/yarn-project/circuits.js/src/utils/index.ts @@ -1,9 +1,6 @@ +import { type IsEmpty } from '@aztec/foundation/interfaces'; import { type Tuple } from '@aztec/foundation/serialize'; -export interface IsEmpty { - isEmpty: () => boolean; -} - // Define these utils here as their design is very specific to kernel's accumulated data and not general enough to be put in foundation. // Returns number of non-empty items in an array. diff --git a/yarn-project/circuits.js/src/hints/utils.test.ts b/yarn-project/circuits.js/src/utils/utils.test.ts similarity index 98% rename from yarn-project/circuits.js/src/hints/utils.test.ts rename to yarn-project/circuits.js/src/utils/utils.test.ts index 1ae2d47ead5..80e46e7e93b 100644 --- a/yarn-project/circuits.js/src/hints/utils.test.ts +++ b/yarn-project/circuits.js/src/utils/utils.test.ts @@ -1,8 +1,8 @@ -import { type IsEmpty } from '@aztec/circuits.js'; import { makeTuple } from '@aztec/foundation/array'; +import { type IsEmpty } from '@aztec/foundation/interfaces'; import { type Tuple } from '@aztec/foundation/serialize'; -import { concatAccumulatedData, countAccumulatedItems, mergeAccumulatedData } from './utils.js'; +import { concatAccumulatedData, countAccumulatedItems, mergeAccumulatedData } from './index.js'; class TestItem { constructor(public value: number) {} 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 c373403d89b..e05f09b1d21 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -59,9 +59,6 @@ describe('e2e_ordering', () => { const expectedOrder = expectedOrders[method]; const action = parent.methods[method](child.address, pubSetValueSelector); const tx = await action.prove(); - expect(tx.data.needsSetup).toBe(false); - expect(tx.data.needsAppLogic).toBe(true); - expect(tx.data.needsTeardown).toBe(false); await action.send().wait(); @@ -71,7 +68,7 @@ describe('e2e_ordering', () => { // The call stack items in the output of the kernel proof match the tx enqueuedPublicFunctionCalls const callStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest())); - expect(tx.data.end.publicCallStack.slice(0, 2)).toEqual(callStackItems); + expect(tx.data.forPublic!.end.publicCallStack.slice(0, 2)).toEqual(callStackItems); // The enqueued public calls are in the expected order based on the argument they set (stack is reversed!) expect(enqueuedPublicCalls.map(c => c.args[0].toBigInt())).toEqual([...expectedOrder].reverse()); diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 41fa3a9ba84..2f4baba29c3 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -20,14 +20,13 @@ import { import { EthAddress, type Header, + KernelCircuitPublicInputs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, + MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PublicDataUpdateRequest, - PublicKernelCircuitPublicInputs, SideEffectLinkedToNoteHash, } from '@aztec/circuits.js'; import { fr, makeNewSideEffect, makeNewSideEffectLinkedToNoteHash, makeProof } from '@aztec/circuits.js/testing'; @@ -168,21 +167,21 @@ describe('L1Publisher integration', () => { const makeBloatedProcessedTx = (seed = 0x1) => { const tx = mockTx(seed); - const kernelOutput = PublicKernelCircuitPublicInputs.empty(); + const kernelOutput = KernelCircuitPublicInputs.empty(); kernelOutput.constants.txContext.chainId = fr(chainId); kernelOutput.constants.txContext.version = fr(config.version); kernelOutput.constants.historicalHeader = prevHeader; kernelOutput.end.publicDataUpdateRequests = makeTuple( - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(i + 10)), seed + 0x500, ); const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newNoteHashes = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100); + processedTx.data.end.newNoteHashes = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100); processedTx.data.end.newNullifiers = makeTuple( - MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, seed + 0x200, ); diff --git a/yarn-project/foundation/package.json b/yarn-project/foundation/package.json index 780d5cd721f..4cec78bb534 100644 --- a/yarn-project/foundation/package.json +++ b/yarn-project/foundation/package.json @@ -17,6 +17,7 @@ "./error": "./dest/error/index.js", "./eth-address": "./dest/eth-address/index.js", "./fifo": "./dest/fifo/index.js", + "./interfaces": "./dest/interfaces/index.js", "./json-rpc": "./dest/json-rpc/index.js", "./json-rpc/server": "./dest/json-rpc/server/index.js", "./json-rpc/client": "./dest/json-rpc/client/index.js", diff --git a/yarn-project/foundation/src/array/array.ts b/yarn-project/foundation/src/array/array.ts index 4821aa45f8d..a7f1d7a18fc 100644 --- a/yarn-project/foundation/src/array/array.ts +++ b/yarn-project/foundation/src/array/array.ts @@ -34,8 +34,13 @@ export function makeTuple(length: N, fn: (i: number) => T, * @param fn - The generator function. * @returns The array of numbers. */ -export function makeHalfFullTuple(length: N, fn: (i: number) => T, offset = 0) { - return Array.from({ length }, (v: any, i: number) => (i < length / 2 ? fn(i + offset) : fn(0))) as Tuple; +export function makeHalfFullTuple( + length: N, + fn: (i: number) => T, + offset = 0, + makeEmpty: () => T, +) { + return Array.from({ length }, (v: any, i: number) => (i < length / 2 ? fn(i + offset) : makeEmpty())) as Tuple; } /** diff --git a/yarn-project/foundation/src/index.ts b/yarn-project/foundation/src/index.ts index 7e06583f10d..bd36d4b0cf6 100644 --- a/yarn-project/foundation/src/index.ts +++ b/yarn-project/foundation/src/index.ts @@ -10,6 +10,7 @@ export * as errors from './errors/index.js'; export * as ethAddress from './eth-address/index.js'; export * as fields from './fields/index.js'; export * as fifo from './fifo/index.js'; +export * as interfaces from './interfaces/index.js'; export * as jsonRpc from './json-rpc/index.js'; export * as jsonRpcClient from './json-rpc/client/index.js'; export * as jsonRpcServer from './json-rpc/server/index.js'; diff --git a/yarn-project/foundation/src/interfaces/index.ts b/yarn-project/foundation/src/interfaces/index.ts new file mode 100644 index 00000000000..5672d325649 --- /dev/null +++ b/yarn-project/foundation/src/interfaces/index.ts @@ -0,0 +1,3 @@ +export interface IsEmpty { + isEmpty: () => boolean; +} diff --git a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap index a408a9bedd3..fa68c47f657 100644 --- a/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits-types/src/__snapshots__/index.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Private kernel Executes private kernel inner for a nested call 1`] = ` -PrivateKernelInnerCircuitPublicInputs { +PrivateKernelCircuitPublicInputs { "aggregationObject": AggregationObject { "hasData": false, "p0": G1AffineElement { @@ -38,19 +38,19 @@ PrivateKernelInnerCircuitPublicInputs { "inHash": Buffer<0x00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c>, "outHash": Buffer<0x0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c3>, "txTreeHeight": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, - "txsEffectsHash": Buffer<0x001070b95a463cd3e0c1eec74d545327d35f036fa6270ff9ee4ae4fd248e4b8c>, + "txsEffectsHash": Buffer<0x00cfbc308cd6489729b93e4b83deedfdc090e5092df3bcf30b748c634b91ab5f>, }, "globalVariables": { "blockNumber": "0x0000000000000000000000000000000000000000000000000000000000000003", "chainId": "0x0000000000000000000000000000000000000000000000000000000000007a69", "coinbase": "0x0000000000000000000000000000000000000000", "feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x000000000000000000000000000000000000000000000000000000006601bb64", + "timestamp": "0x00000000000000000000000000000000000000000000000000000000660cc102", "version": "0x0000000000000000000000000000000000000000000000000000000000000001", }, "lastArchive": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 3, - "root": Fr<0x12323626efdb913d8d0e878df766c402fbb5b61c87826363fa9cde7ba5e1ab8b>, + "root": Fr<0x11cc528a3c35c8a3cf72fc1e5b1e7624effe1149ff99169498377d7c211ec3ae>, }, "state": StateReference { "l1ToL2MessageTree": AppendOnlyTreeSnapshot { @@ -60,11 +60,11 @@ PrivateKernelInnerCircuitPublicInputs { "partial": PartialStateReference { "noteHashTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 384, - "root": Fr<0x1b64454c8b6f9ef03956bec11fe831358f8fe47a3593534790f822b35324ceef>, + "root": Fr<0x09131c800c5e7aeed76eb85bf3b2987976ac91a54cfe136e0588fc76e7041010>, }, "nullifierTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 512, - "root": Fr<0x1798310a7303baf83b94523073876af0682377b02f648d6368d4b750297a8008>, + "root": Fr<0x1167bce58d51ab022d3c750e786e814ce2a1dfbc4c05147db7fd7654ad61dc94>, }, "publicDataTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 256, @@ -80,7 +80,7 @@ PrivateKernelInnerCircuitPublicInputs { "version": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, }, }, - "end": CombinedAccumulatedData { + "end": PrivateAccumulatedData { "encryptedLogPreimagesLength": Fr<0x000000000000000000000000000000000000000000000000000000000000000c>, "encryptedLogsHash": Fr<0x00f33ae280239814c4dfaaafc16fc138a8d3eae52bb962af6576cbb61c2af246>, "newL2ToL1Msgs": [ @@ -349,7 +349,7 @@ PrivateKernelInnerCircuitPublicInputs { SideEffectLinkedToNoteHash { "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x1882c9614901f1f1b248a220cfca811c12c5fdd88c61804824a9319d9c308981>, + "value": Fr<0x2d2a435983827ebbecd91dbbf499d1e6481a4878119859558e197df4efb697ca>, }, SideEffectLinkedToNoteHash { "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, @@ -831,175 +831,9 @@ PrivateKernelInnerCircuitPublicInputs { "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, ], - "publicDataUpdateRequests": [ - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - PublicDataUpdateRequest { - "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "sideEffectCounter": undefined, - }, - ], - "revertCode": RevertCode { - "code": 0, - }, "unencryptedLogPreimagesLength": Fr<0x000000000000000000000000000000000000000000000000000000000000000c>, "unencryptedLogsHash": Fr<0x00f33ae280239814c4dfaaafc16fc138a8d3eae52bb962af6576cbb61c2af246>, }, - "isPrivate": true, "minRevertibleSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000002>, "validationRequests": ValidationRequests { "forRollup": RollupValidationRequests { @@ -1890,779 +1724,769 @@ PrivateKernelTailCircuitPublicInputs { "version": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, }, }, - "end": PrivateAccumulatedRevertibleData { - "encryptedLogPreimagesLength": Fr<0x0000000000000000000000000000000000000000000000000000000000000138>, - "encryptedLogsHash": Fr<0x0082cb025a081337054f138f2d4708d3ae2a35c1c024041344b5f55c6ed3ee83>, - "newL2ToL1Msgs": [ - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - ], - "newNoteHashes": [ - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000002>, - "value": Fr<0x12d57be1320db2f84e9ee09f4cb6d2845d5a813c7dc5be06779a58820db51183>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x028d5f9670104b5af44b1ae3ea44a5bbdc97f37425dc07a9acbfd6902e8fc3af>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000003>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x2905d10baaf69765d2b2f1e03ded36e2b50a91489515aa91d277a9658999cd51>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "privateCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + "forPublic": undefined, + "forRollup": PartialPrivateTailPublicInputsForRollup { + "end": CombinedAccumulatedData { + "encryptedLogPreimagesLength": Fr<0x0000000000000000000000000000000000000000000000000000000000000138>, + "encryptedLogsHash": Fr<0x009cc8e18616f51eefc2ece771190a444f783957147e0aa607de29223f1dbded>, + "newL2ToL1Msgs": [ + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + ], + "newNoteHashes": [ + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000002>, + "value": Fr<0x081522c68019fecc79c98e173533641c1732e1e75ad8979f3ab99ea1993600cf>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffect { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + ], + "newNullifiers": [ + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0fec8a31e3dfd8c9e778e89cfeae46776f3d3823052afa1f1f8cb215ec2fef70>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000001>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0b07b7bf05784e148c96095715aced29f1ce58042954a42824fdc0231c40695f>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000003>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x1accc21903026623cb913b7333ffc6e0a8642831aed98aa75644b62d0daa66d2>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + }, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "publicCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "unencryptedLogPreimagesLength": Fr<0x0000000000000000000000000000000000000000000000000000000000000004>, - "unencryptedLogsHash": Fr<0x006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b39>, - }, - "endNonRevertibleData": PrivateAccumulatedNonRevertibleData { - "newNoteHashes": [ - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffect { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x1ae0435114bcd3eab4c8994725a1b5a21e63c1ed26db53f0ec26af423562c07e>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - SideEffectLinkedToNoteHash { - "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - ], - "publicCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + SideEffectLinkedToNoteHash { + "counter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "noteHash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "storageContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, + ], + "publicDataUpdateRequests": [ + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, }, - "callerContractAddress": AztecAddress<0x0000000000000000000000000000000000000000000000000000000000000000>, - "endSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "hash": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - "startSideEffectCounter": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + PublicDataUpdateRequest { + "leafSlot": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "newValue": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, + "sideEffectCounter": undefined, + }, + ], + "unencryptedLogPreimagesLength": Fr<0x0000000000000000000000000000000000000000000000000000000000000004>, + "unencryptedLogsHash": Fr<0x006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b39>, + }, + "rollupValidationRequests": RollupValidationRequests { + "maxBlockNumber": MaxBlockNumber { + "isSome": false, + "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, }, - ], - "revertCode": RevertCode { - "code": 0, }, }, - "needsAppLogic": false, - "needsSetup": false, - "needsTeardown": false, - "rollupValidationRequests": RollupValidationRequests { - "maxBlockNumber": MaxBlockNumber { - "isSome": false, - "value": Fr<0x0000000000000000000000000000000000000000000000000000000000000000>, - }, + "revertCode": RevertCode { + "code": 0, }, } `; diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex index b429f7a21ee..792ad366945 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-init.hex @@ -1 +1 @@ -1cd5ad4b3a2730bb3e21d5483c7cba30278b7e86de666f712758642e58f9f23aaf9f8c4401000864ba282583f7e8885cd95c99d5b94e8e4e7e90f960f7d1f744d4e1a3d1184600000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000011cd5ad4b3a2730bb3e21d5483c7cba30278b7e86de666f712758642e58f9f23aaf9f8c44010000000000000000000000000000000000000000000000000000000000000000001cd5ad4b3a2730bb3e21d5483c7cba30278b7e86de666f712758642e58f9f23a0000000000000000000000000000000000000000af9f8c440000000000010864ba282583f7e8885cd95c99d5b94e8e4e7e90f960f7d1f744d4e1a3d11846000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276ccc1f739a2f32e67e0a69d000e0f24549e2daf7ba4ab92d0c396c749ef708000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003579f468b2283611cc4d7adfbb93b8a4815d93ac0b1e1d11dace012cf73c7aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011cd5ad4b3a2730bb3e21d5483c7cba30278b7e86de666f712758642e58f9f23a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040073ced0da546b196db6081a63207dd54a4471baa30273e0b81f7ca1896331ab00e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b80000000000000000000000000000000000000000000000000000000000000138000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f16100cde5c5b63f50c24f425289b93fb6719b045e905e9dcb9c281c79f8a10700e749f3a31cc27ed4aa1c105c023e78dbd20f922114e47d92d044fefc24e355f13f925dcd83bf6054ea0cce12d21a0b9d3be109d26fa9c333bae17b82becf29f188d5acf2ca79a04d6e2db7589ff5543f53308a162c360a65c80261e28f6768200000000000000000000000000000000000000000000000000000000000000022b09ad2b1765e61b2203cd359f9b833c9c611271e5c80df92c35ef522d3731e42706fc59cda1c448173c4a7739dca4fd4325c970e6f035ed9929fd84719533bb0bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +13818749abe7ebdebfc0a70841529473010d3ed9c010fcbea62a08303c6ca5caaf9f8c4401001fefc91f427fa4f8c1124f0279215fa5cdc7883c9c9fb140ce5bb565a515ac9300000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000113818749abe7ebdebfc0a70841529473010d3ed9c010fcbea62a08303c6ca5caaf9f8c440100000000000000000000000000000000000000000000000000000000000000000013818749abe7ebdebfc0a70841529473010d3ed9c010fcbea62a08303c6ca5ca0000000000000000000000000000000000000000af9f8c440000000000011fefc91f427fa4f8c1124f0279215fa5cdc7883c9c9fb140ce5bb565a515ac9300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019905eeb4ed6d832f933561cf7b442e839fc996976439c2523db6b691f4b653c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003579f468b2283611cc4d7adfbb93b8a4815d93ac0b1e1d11dace012cf73c7aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113818749abe7ebdebfc0a70841529473010d3ed9c010fcbea62a08303c6ca5ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004007695b70905c513fe7c9962460b9af3d3e00234c25b213e2c1c487851340d0e00e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b80000000000000000000000000000000000000000000000000000000000000138000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f1a64d25777857ae998c59ef898ab6b36ff568bfb7cb2ec9d10ea7f329c1a31e922664a87df907f732f4fa814018bb43063a411a6b4fa0072e5f5f443c9c9f089036cb9602cfdb3bdb3baf33fcf289f2404f0d276299265ec8594a3eec9daed1121bab18c85e7e2dd883a7caaf48de070eac103dd33c97654aa1e72c301038f0800000000000000000000000000000000000000000000000000000000000000022b09ad2b1765e61b2203cd359f9b833c9c611271e5c80df92c35ef522d3731e42706fc59cda1c448173c4a7739dca4fd4325c970e6f035ed9929fd84719533bb0bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex index cd099970554..06e5abde52e 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-inner.hex @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be2000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001882c9614901f1f1b248a220cfca811c12c5fdd88c61804824a9319d9c30898100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028e0cd51c331bac85a0b3e3ec688d034ab7eb5e75ab085dfd3aa200343d23460ed08e599e5db578d1fc18d29c1eded075b92ccd489624367e8852bc807861ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012323626efdb913d8d0e878df766c402fbb5b61c87826363fa9cde7ba5e1ab8b000000030000000000000000000000000000000000000000000000000000000000000001001070b95a463cd3e0c1eec74d545327d35f036fa6270ff9ee4ae4fd248e4b8c00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301b64454c8b6f9ef03956bec11fe831358f8fe47a3593534790f822b35324ceef000001801798310a7303baf83b94523073876af0682377b02f648d6368d4b750297a8008000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000006601bb640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0000000025ac0f8793721f4bed5541b84ac1b3d3a7979d2d5c367b7752fc0ee13db1aa9109b10c924d7b8ea453aa111249a391832ed60e771536c5f7496bea3d6e921d9502cb42d99fc18dfd0b7faebcbc4b04cac72deeaa804c2f881c734253b239915d25d4a020c2e9dd66895268ad6890d394df1b7bba1b5f68c5482f32502bfe7eda0906bca101000ed08e599e5db578d1fc18d29c1eded075b92ccd489624367e8852bc807861ed25d4a020c2e9dd66895268ad6890d394df1b7bba1b5f68c5482f32502bfe7eda00000000000000000000000000000000000000000906bca10000000000032898402da2fa95f47c47763fe5b171ff3155bd31e5af88d9823bccb26b6701540000000000000000000000000000000000000000000000000000000000007a6a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b800e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000412323626efdb913d8d0e878df766c402fbb5b61c87826363fa9cde7ba5e1ab8b000000030000000000000000000000000000000000000000000000000000000000000001001070b95a463cd3e0c1eec74d545327d35f036fa6270ff9ee4ae4fd248e4b8c00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301b64454c8b6f9ef03956bec11fe831358f8fe47a3593534790f822b35324ceef000001801798310a7303baf83b94523073876af0682377b02f648d6368d4b750297a8008000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000006601bb64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0943e0d2a4e58238525bf3e5f2b00d44ebfd6d27463767fce64425c1c95ca1a60ce0972a4958e5b11c7d51f6f803f78799b28bd1c2df941f869ef6c553d6941b27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed2665e9a78f03a58e48cb92a31a243d9906c13eb556d8feed67ea831230d9d8c900000000000000000000000000000000000000000000000000000000000000002452a14c748981acff167dba9088770b6c2c2dc34677295a1974f2c247236ba11e904e4d0a67667f8faaa89198f5e89684e213bc99a83c3b20888d5854d3dd320bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d2a435983827ebbecd91dbbf499d1e6481a4878119859558e197df4efb697ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c008d4d695766a616808caa331119da14269ac3271c251dec3a11df896131ba2c000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000081d52e0a54ba8474222a254c4313f4bd44f691e7e38234a9c34226dc57b89b1b91259f3e4012cef5a027b23971a8207abc0aac6283b63e368dca82ceebc2a40e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011cc528a3c35c8a3cf72fc1e5b1e7624effe1149ff99169498377d7c211ec3ae00000003000000000000000000000000000000000000000000000000000000000000000100cfbc308cd6489729b93e4b83deedfdc090e5092df3bcf30b748c634b91ab5f00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000003009131c800c5e7aeed76eb85bf3b2987976ac91a54cfe136e0588fc76e7041010000001801167bce58d51ab022d3c750e786e814ce2a1dfbc4c05147db7fd7654ad61dc94000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000660cc1020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000002323317dbbf31a6bc7e748ef2e49e9213287bb0cec3bddf786d4ce32057028d4194128903ec0545a378262f8f1e1fc5201468375cd4c466c1b309d16ca944689299332d57a7f7985186991c01e6edfa92d292baacd298a2a2e10852d305d01b5225d77e994adc9c44857ec529284fa2912eb3e4c94a5a620b90bfb338cf85f710906bca101001259f3e4012cef5a027b23971a8207abc0aac6283b63e368dca82ceebc2a40e0225d77e994adc9c44857ec529284fa2912eb3e4c94a5a620b90bfb338cf85f7100000000000000000000000000000000000000000906bca10000000000032898402da2fa95f47c47763fe5b171ff3155bd31e5af88d9823bccb26b6701540000000000000000000000000000000000000000000000000000000000007a6a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b800e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000411cc528a3c35c8a3cf72fc1e5b1e7624effe1149ff99169498377d7c211ec3ae00000003000000000000000000000000000000000000000000000000000000000000000100cfbc308cd6489729b93e4b83deedfdc090e5092df3bcf30b748c634b91ab5f00089a9d421a82c4a25f7acbebe69e638d5b064fa8a60e018793dcb0be53752c0007638bb56b6dda2b64b8f76841114ac3a87a1820030e2e16772c4d294879c31864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000003009131c800c5e7aeed76eb85bf3b2987976ac91a54cfe136e0588fc76e7041010000001801167bce58d51ab022d3c750e786e814ce2a1dfbc4c05147db7fd7654ad61dc94000002000572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b000001000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000660cc102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f2ade7319c2af1088ff40b65dcbd2c33a9ec6b2ec9714702671d027225acde4c9268220209c5229055952db6d99f7aca3997322c471c4d451f74f849ec2aef9da27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed1b3b36519e4878129438bdfc72cf2f7b258f800e413bd6ba2d9a8070c3defdc200000000000000000000000000000000000000000000000000000000000000002452a14c748981acff167dba9088770b6c2c2dc34677295a1974f2c247236ba11e904e4d0a67667f8faaa89198f5e89684e213bc99a83c3b20888d5854d3dd320bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex index 73a2d6e1f99..0c3a653b5a2 100644 --- a/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex +++ b/yarn-project/noir-protocol-circuits-types/src/fixtures/nested-call-private-kernel-ordering.hex @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002df6f1bebea79e7109e9a05d46eb4f3cbcd2ab2f1deddf1ee404519d06f6db4100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ae0435114bcd3eab4c8994725a1b5a21e63c1ed26db53f0ec26af423562c07e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028d5f9670104b5af44b1ae3ea44a5bbdc97f37425dc07a9acbfd6902e8fc3af000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012905d10baaf69765d2b2f1e03ded36e2b50a91489515aa91d277a9658999cd5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082cb025a081337054f138f2d4708d3ae2a35c1c024041344b5f55c6ed3ee83006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b3900000000000000000000000000000000000000000000000000000000000001380000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b0000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000001922b5761a51e19b5cb4d8b6bb2ee8268771782838b138bcbca98b4ac18627890bce5a69119854406c06308ba266813d1c29cf462591d0d9fcec48977c449a7a19d92aa77bbcd9971855e260da442e61407d51011a2f83479a5663c018aa933d2df6f1bebea79e7109e9a05d46eb4f3cbcd2ab2f1deddf1ee404519d06f6db410000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ae0435114bcd3eab4c8994725a1b5a21e63c1ed26db53f0ec26af423562c07e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028d5f9670104b5af44b1ae3ea44a5bbdc97f37425dc07a9acbfd6902e8fc3af000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012905d10baaf69765d2b2f1e03ded36e2b50a91489515aa91d277a9658999cd5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be2000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029ab1872049d52aae695fe3fe7ed5661f703a77c28f0247e7247f5c78e3aa20600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fec8a31e3dfd8c9e778e89cfeae46776f3d3823052afa1f1f8cb215ec2fef70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b07b7bf05784e148c96095715aced29f1ce58042954a42824fdc0231c40695f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011accc21903026623cb913b7333ffc6e0a8642831aed98aa75644b62d0daa66d20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009cc8e18616f51eefc2ece771190a444f783957147e0aa607de29223f1dbded006003947a07e21c81ce2062539d6d6864fe999b58b03fc46f6c190d9eac9b390000000000000000000000000000000000000000000000000000000000000138000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000800572c8db882674dd026b8877fbba1b700a4407da3ae9ce5fa43215a28163362b0000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a6900000000000000000000000000000000000000000000000000000000000000010000002a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000000d46a8a63452b463be837cf8d6d7d9be7eb45b55529596b51f86147ed456d3b92a92ecc44aa85c591f07a61aeb552f47f9df34266fa0541cefb5591894a951752a4afeb313613e9b25a6e1cd6e7216f37197a7b73fb39369ce4b3ed74a9a993529ab1872049d52aae695fe3fe7ed5661f703a77c28f0247e7247f5c78e3aa2060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fec8a31e3dfd8c9e778e89cfeae46776f3d3823052afa1f1f8cb215ec2fef70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b07b7bf05784e148c96095715aced29f1ce58042954a42824fdc0231c40695f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011accc21903026623cb913b7333ffc6e0a8642831aed98aa75644b62d0daa66d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000008000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits-types/src/index.ts b/yarn-project/noir-protocol-circuits-types/src/index.ts index fb07caed0b4..8657f68680a 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -2,11 +2,12 @@ import { type BaseOrMergeRollupPublicInputs, type BaseParityInputs, type BaseRollupInputs, + type KernelCircuitPublicInputs, type MergeRollupInputs, type ParityPublicInputs, + type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelInnerCircuitPublicInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, type PublicKernelCircuitPrivateInputs, @@ -34,6 +35,8 @@ import PrivateKernelInnerJson from './target/private_kernel_inner.json' assert { import PrivateKernelInnerSimulatedJson from './target/private_kernel_inner_simulated.json' assert { type: 'json' }; import PrivateKernelTailJson from './target/private_kernel_tail.json' assert { type: 'json' }; import PrivateKernelTailSimulatedJson from './target/private_kernel_tail_simulated.json' assert { type: 'json' }; +import PrivateKernelTailToPublicJson from './target/private_kernel_tail_to_public.json' assert { type: 'json' }; +import PrivateKernelTailToPublicSimulatedJson from './target/private_kernel_tail_to_public_simulated.json' assert { type: 'json' }; import PublicKernelAppLogicSimulatedJson from './target/public_kernel_app_logic_simulated.json' assert { type: 'json' }; import PublicKernelSetupSimulatedJson from './target/public_kernel_setup_simulated.json' assert { type: 'json' }; import PublicKernelTailSimulatedJson from './target/public_kernel_tail_simulated.json' assert { type: 'json' }; @@ -45,13 +48,16 @@ import { mapBaseOrMergeRollupPublicInputsFromNoir, mapBaseParityInputsToNoir, mapBaseRollupInputsToNoir, + mapKernelCircuitPublicInputsFromNoir, mapMergeRollupInputsToNoir, mapParityPublicInputsFromNoir, + mapPrivateKernelCircuitPublicInputsFromNoir, mapPrivateKernelInitCircuitPrivateInputsToNoir, mapPrivateKernelInnerCircuitPrivateInputsToNoir, - mapPrivateKernelInnerCircuitPublicInputsFromNoir, mapPrivateKernelTailCircuitPrivateInputsToNoir, - mapPrivateKernelTailCircuitPublicInputsFromNoir, + mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir, + mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir, + mapPrivateKernelTailToPublicCircuitPrivateInputsToNoir, mapPublicKernelCircuitPrivateInputsToNoir, mapPublicKernelCircuitPublicInputsFromNoir, mapPublicKernelTailCircuitPrivateInputsToNoir, @@ -69,6 +75,7 @@ import { type InputType as InnerInputType, type ReturnType as InnerReturnType, } from './types/private_kernel_inner_types.js'; +import { type InputType as TailToPublicInputType } from './types/private_kernel_tail_to_public_types.js'; import { type InputType as TailInputType, type ReturnType as TailReturnType, @@ -100,6 +107,8 @@ export const PrivateKernelInnerArtifact = PrivateKernelInnerJson as NoirCompiled export const PrivateKernelTailArtifact = PrivateKernelTailJson as NoirCompiledCircuit; +export const PrivateKernelTailToPublicArtifact = PrivateKernelTailToPublicJson as NoirCompiledCircuit; + export const PublicKernelSetupArtifact = PublicKernelSetupSimulatedJson as NoirCompiledCircuit; export const PublicKernelAppLogicArtifact = PublicKernelAppLogicSimulatedJson as NoirCompiledCircuit; @@ -134,14 +143,14 @@ const getSolver = (): Promise => { */ export async function executeInit( privateKernelInitCircuitPrivateInputs: PrivateKernelInitCircuitPrivateInputs, -): Promise { +): Promise { const params: InitInputType = { input: mapPrivateKernelInitCircuitPrivateInputsToNoir(privateKernelInitCircuitPrivateInputs), }; const returnType = await executePrivateKernelInitWithACVM(params); - return mapPrivateKernelInnerCircuitPublicInputsFromNoir(returnType); + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); } /** @@ -151,30 +160,47 @@ export async function executeInit( */ export async function executeInner( privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, -): Promise { +): Promise { const params: InnerInputType = { input: mapPrivateKernelInnerCircuitPrivateInputsToNoir(privateKernelInnerCircuitPrivateInputs), }; const returnType = await executePrivateKernelInnerWithACVM(params); - return mapPrivateKernelInnerCircuitPublicInputsFromNoir(returnType); + return mapPrivateKernelCircuitPublicInputsFromNoir(returnType); } /** * Executes the tail private kernel. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the tail private kernel. + * @param privateKernelCircuitPrivateInputs - The private inputs to the tail private kernel. * @returns The public inputs. */ export async function executeTail( - privateKernelInnerCircuitPrivateInputs: PrivateKernelTailCircuitPrivateInputs, + privateInputs: PrivateKernelTailCircuitPrivateInputs, ): Promise { const params: TailInputType = { - input: mapPrivateKernelTailCircuitPrivateInputsToNoir(privateKernelInnerCircuitPrivateInputs), + input: mapPrivateKernelTailCircuitPrivateInputsToNoir(privateInputs), }; const returnType = await executePrivateKernelTailWithACVM(params); - return mapPrivateKernelTailCircuitPublicInputsFromNoir(returnType); + return mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir(returnType); +} + +/** + * Executes the tail private kernel. + * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the tail private kernel. + * @returns The public inputs. + */ +export async function executeTailForPublic( + privateInputs: PrivateKernelTailCircuitPrivateInputs, +): Promise { + const params: TailToPublicInputType = { + input: mapPrivateKernelTailToPublicCircuitPrivateInputsToNoir(privateInputs), + }; + + const returnType = await executePrivateKernelTailToPublicWithACVM(params); + + return mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir(returnType); } /** @@ -400,14 +426,14 @@ export function convertPublicTeardownRollupOutputFromWitnessMap(outputs: Witness * @param outputs - The public kernel outputs as a witness map. * @returns The public inputs. */ -export function convertPublicTailOutputFromWitnessMap(outputs: WitnessMap): PublicKernelCircuitPublicInputs { +export function convertPublicTailOutputFromWitnessMap(outputs: WitnessMap): KernelCircuitPublicInputs { // Decode the witness map into two fields, the return values and the inputs const decodedInputs: DecodedInputs = abiDecode(PublicKernelTailSimulatedJson.abi as Abi, outputs); // Cast the inputs as the return type - const returnType = decodedInputs.return_value as PublicPublicPreviousReturnType; + const returnType = decodedInputs.return_value as TailReturnType; - return mapPublicKernelCircuitPublicInputsFromNoir(returnType); + return mapKernelCircuitPublicInputsFromNoir(returnType); } /** @@ -494,3 +520,30 @@ async function executePrivateKernelTailWithACVM(input: TailInputType): Promise { + const initialWitnessMap = abiEncode(PrivateKernelTailToPublicSimulatedJson.abi as Abi, input as any); + + // Execute the circuit on those initial witness values + // + // Decode the bytecode from base64 since the acvm does not know about base64 encoding + const decodedBytecode = Buffer.from(PrivateKernelTailToPublicSimulatedJson.bytecode, 'base64'); + // + // Execute the circuit + const _witnessMap = await executeCircuitWithBlackBoxSolver( + await getSolver(), + decodedBytecode, + initialWitnessMap, + () => { + throw Error('unexpected oracle during execution'); + }, + ); + + // Decode the witness map into two fields, the return values and the inputs + const decodedInputs: DecodedInputs = abiDecode(PrivateKernelTailToPublicSimulatedJson.abi as Abi, _witnessMap); + + // Cast the inputs as the return type + return decodedInputs.return_value as PublicPublicPreviousReturnType; +} diff --git a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts index 4c60072d12d..d42d36f9092 100644 --- a/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts +++ b/yarn-project/noir-protocol-circuits-types/src/scripts/generate_ts_from_abi.ts @@ -203,6 +203,7 @@ const circuits = [ 'private_kernel_init', 'private_kernel_inner', 'private_kernel_tail', + 'private_kernel_tail_to_public', 'public_kernel_setup', 'public_kernel_app_logic', 'public_kernel_teardown', diff --git a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts index 80835e3c71a..a541297ce24 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -24,14 +24,12 @@ import { type GrumpkinPrivateKey, GrumpkinScalar, Header, + KernelCircuitPublicInputs, + type KernelData, type L2ToL1Message, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, @@ -40,10 +38,6 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MaxBlockNumber, type MembershipWitness, type MergeRollupInputs, @@ -58,23 +52,23 @@ import { type NullifierReadRequestHints, type PUBLIC_DATA_TREE_HEIGHT, ParityPublicInputs, + PartialPrivateTailPublicInputsForPublic, + PartialPrivateTailPublicInputsForRollup, PartialStateReference, type PendingReadHint, Point, type PreviousRollupData, - PrivateAccumulatedNonRevertibleData, - PrivateAccumulatedRevertibleData, + PrivateAccumulatedData, type PrivateCallData, type PrivateCallStackItem, type PrivateCircuitPublicInputs, + PrivateKernelCircuitPublicInputs, + type PrivateKernelData, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, - PrivateKernelInnerCircuitPublicInputs, - type PrivateKernelInnerData, type PrivateKernelTailCircuitPrivateInputs, PrivateKernelTailCircuitPublicInputs, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, + PublicAccumulatedData, type PublicCallData, type PublicCallStackItem, type PublicCircuitPublicInputs, @@ -90,8 +84,6 @@ import { ReadRequestContext, type ReadRequestStatus, RevertCode, - type RollupKernelCircuitPublicInputs, - type RollupKernelData, RollupValidationRequests, type RootParityInput, type RootParityInputs, @@ -115,7 +107,6 @@ import { type CallContext as CallContextNoir, type CallRequest as CallRequestNoir, type CallerContext as CallerContextNoir, - type CombinedAccumulatedData as CombinedAccumulatedDataNoir, type CombinedConstantData as CombinedConstantDataNoir, type FunctionData as FunctionDataNoir, type FunctionLeafMembershipWitness as FunctionLeafMembershipWitnessNoir, @@ -130,12 +121,13 @@ import { type NoteHashReadRequestMembershipWitness as NoteHashReadRequestMembershipWitnessNoir, type NullifierKeyValidationRequestContext as NullifierKeyValidationRequestContextNoir, type NullifierKeyValidationRequest as NullifierKeyValidationRequestNoir, + type PrivateAccumulatedData as PrivateAccumulatedDataNoir, type PrivateCallData as PrivateCallDataNoir, type PrivateCallStackItem as PrivateCallStackItemNoir, type PrivateCircuitPublicInputs as PrivateCircuitPublicInputsNoir, + type PrivateKernelCircuitPublicInputs as PrivateKernelCircuitPublicInputsNoir, type PrivateKernelInitCircuitPrivateInputs as PrivateKernelInitCircuitPrivateInputsNoir, type PublicDataRead as PublicDataReadNoir, - type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, type ReadRequestContext as ReadRequestContextNoir, type ReadRequest as ReadRequestNoir, type RollupValidationRequests as RollupValidationRequestsNoir, @@ -145,24 +137,19 @@ import { type TxRequest as TxRequestNoir, type ValidationRequests as ValidationRequestsNoir, } from './types/private_kernel_init_types.js'; +import { type PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir } from './types/private_kernel_inner_types.js'; +import { type PrivateKernelTailToPublicCircuitPrivateInputs as PrivateKernelTailToPublicCircuitPrivateInputsNoir } from './types/private_kernel_tail_to_public_types.js'; import { - type PrivateKernelInnerCircuitPrivateInputs as PrivateKernelInnerCircuitPrivateInputsNoir, - type PrivateKernelInnerCircuitPublicInputs as PrivateKernelInnerCircuitPublicInputsNoir, - type PrivateKernelInnerData as PrivateKernelInnerDataNoir, -} from './types/private_kernel_inner_types.js'; -import { + type CombinedAccumulatedData as CombinedAccumulatedDataNoir, type NullifierReadRequestHints as NullifierReadRequestHintsNoir, type NullifierSettledReadHint as NullifierSettledReadHintNoir, type PendingReadHint as PendingReadHintNoir, - type PrivateAccumulatedNonRevertibleData as PrivateAccumulatedNonRevertibleDataNoir, - type PrivateAccumulatedRevertibleData as PrivateAccumulatedRevertibleDataNoir, + type PrivateKernelData as PrivateKernelDataNoir, type PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, - type PrivateKernelTailCircuitPublicInputs as PrivateKernelTailCircuitPublicInputsNoir, type ReadRequestStatus as ReadRequestStatusNoir, } from './types/private_kernel_tail_types.js'; import { - type PublicAccumulatedNonRevertibleData as PublicAccumulatedNonRevertibleDataNoir, - type PublicAccumulatedRevertibleData as PublicAccumulatedRevertibleDataNoir, + type PublicAccumulatedData as PublicAccumulatedDataNoir, type PublicKernelData as PublicKernelDataNoir, } from './types/public_kernel_app_logic_types.js'; import { @@ -177,18 +164,19 @@ import { import { type NullifierNonExistentReadRequestHints as NullifierNonExistentReadRequestHintsNoir, type NullifierNonMembershipHint as NullifierNonMembershipHintNoir, + type PublicDataUpdateRequest as PublicDataUpdateRequestNoir, type PublicKernelTailCircuitPrivateInputs as PublicKernelTailCircuitPrivateInputsNoir, } from './types/public_kernel_tail_types.js'; import { type ArchiveRootMembershipWitness as ArchiveRootMembershipWitnessNoir, type BaseRollupInputs as BaseRollupInputsNoir, + type KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, + type KernelData as KernelDataNoir, type NullifierLeafPreimage as NullifierLeafPreimageNoir, type NullifierMembershipWitness as NullifierMembershipWitnessNoir, type PublicDataMembershipWitness as PublicDataMembershipWitnessNoir, type PublicDataTreeLeaf as PublicDataTreeLeafNoir, type PublicDataTreeLeafPreimage as PublicDataTreeLeafPreimageNoir, - type RollupKernelCircuitPublicInputs as RollupKernelCircuitPublicInputsNoir, - type RollupKernelData as RollupKernelDataNoir, type StateDiffHints as StateDiffHintsNoir, } from './types/rollup_base_types.js'; import { type MergeRollupInputs as MergeRollupInputsNoir } from './types/rollup_merge_types.js'; @@ -972,6 +960,87 @@ function mapValidationRequestsFromNoir(requests: ValidationRequestsNoir): Valida ); } +export function mapPrivateAccumulatedDataFromNoir( + privateAccumulatedData: PrivateAccumulatedDataNoir, +): PrivateAccumulatedData { + return new PrivateAccumulatedData( + mapTupleFromNoir(privateAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(privateAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), + mapTupleFromNoir(privateAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), + mapFieldFromNoir(privateAccumulatedData.encrypted_logs_hash), + mapFieldFromNoir(privateAccumulatedData.unencrypted_logs_hash), + mapFieldFromNoir(privateAccumulatedData.encrypted_log_preimages_length), + mapFieldFromNoir(privateAccumulatedData.unencrypted_log_preimages_length), + mapTupleFromNoir( + privateAccumulatedData.private_call_stack, + MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, + mapCallRequestFromNoir, + ), + mapTupleFromNoir( + privateAccumulatedData.public_call_stack, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + mapCallRequestFromNoir, + ), + ); +} + +export function mapPrivateAccumulatedDataToNoir(data: PrivateAccumulatedData): PrivateAccumulatedDataNoir { + return { + new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), + new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), + new_l2_to_l1_msgs: mapTuple(data.newL2ToL1Msgs, mapFieldToNoir), + encrypted_logs_hash: mapFieldToNoir(data.encryptedLogsHash), + unencrypted_logs_hash: mapFieldToNoir(data.unencryptedLogsHash), + encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), + unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), + private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), + public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), + }; +} + +export function mapPublicAccumulatedDataFromNoir( + publicAccumulatedData: PublicAccumulatedDataNoir, +): PublicAccumulatedData { + return new PublicAccumulatedData( + mapTupleFromNoir(publicAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir(publicAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), + mapTupleFromNoir(publicAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), + mapFieldFromNoir(publicAccumulatedData.encrypted_logs_hash), + mapFieldFromNoir(publicAccumulatedData.unencrypted_logs_hash), + mapFieldFromNoir(publicAccumulatedData.encrypted_log_preimages_length), + mapFieldFromNoir(publicAccumulatedData.unencrypted_log_preimages_length), + mapTupleFromNoir( + publicAccumulatedData.public_data_update_requests, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + mapPublicDataUpdateRequestFromNoir, + ), + mapTupleFromNoir( + publicAccumulatedData.public_call_stack, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + mapCallRequestFromNoir, + ), + ); +} + +export function mapPublicAccumulatedDataToNoir( + publicAccumulatedData: PublicAccumulatedData, +): PublicAccumulatedDataNoir { + return { + new_note_hashes: mapTuple(publicAccumulatedData.newNoteHashes, mapSideEffectToNoir), + new_nullifiers: mapTuple(publicAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), + new_l2_to_l1_msgs: mapTuple(publicAccumulatedData.newL2ToL1Msgs, mapFieldToNoir), + encrypted_logs_hash: mapFieldToNoir(publicAccumulatedData.encryptedLogsHash), + unencrypted_logs_hash: mapFieldToNoir(publicAccumulatedData.unencryptedLogsHash), + encrypted_log_preimages_length: mapFieldToNoir(publicAccumulatedData.encryptedLogPreimagesLength), + unencrypted_log_preimages_length: mapFieldToNoir(publicAccumulatedData.unencryptedLogPreimagesLength), + public_data_update_requests: mapTuple( + publicAccumulatedData.publicDataUpdateRequests, + mapPublicDataUpdateRequestToNoir, + ), + public_call_stack: mapTuple(publicAccumulatedData.publicCallStack, mapCallRequestToNoir), + }; +} + export function mapRollupValidationRequestsToNoir( rollupValidationRequests: RollupValidationRequests, ): RollupValidationRequestsNoir { @@ -1008,19 +1077,8 @@ export function mapCombinedAccumulatedDataFromNoir( combinedAccumulatedData: CombinedAccumulatedDataNoir, ): CombinedAccumulatedData { return new CombinedAccumulatedData( - mapRevertCodeFromNoir(combinedAccumulatedData.revert_code), mapTupleFromNoir(combinedAccumulatedData.new_note_hashes, MAX_NEW_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), mapTupleFromNoir(combinedAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), - mapTupleFromNoir( - combinedAccumulatedData.private_call_stack, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), - mapTupleFromNoir( - combinedAccumulatedData.public_call_stack, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), mapTupleFromNoir(combinedAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), mapFieldFromNoir(combinedAccumulatedData.encrypted_logs_hash), mapFieldFromNoir(combinedAccumulatedData.unencrypted_logs_hash), @@ -1034,109 +1092,12 @@ export function mapCombinedAccumulatedDataFromNoir( ); } -/** - * Maps final accumulated data from noir to the parsed type. - * @param finalAccumulatedData - The noir final accumulated data. - * @returns The parsed final accumulated data. - */ -export function mapFinalAccumulatedDataFromNoir( - finalAccumulatedData: PrivateAccumulatedRevertibleDataNoir, -): PrivateAccumulatedRevertibleData { - return new PrivateAccumulatedRevertibleData( - mapTupleFromNoir(finalAccumulatedData.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), - mapTupleFromNoir( - finalAccumulatedData.new_nullifiers, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - mapSideEffectLinkedFromNoir, - ), - mapTupleFromNoir( - finalAccumulatedData.private_call_stack, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), - mapTupleFromNoir( - finalAccumulatedData.public_call_stack, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), - mapTupleFromNoir(finalAccumulatedData.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), - mapFieldFromNoir(finalAccumulatedData.encrypted_logs_hash), - mapFieldFromNoir(finalAccumulatedData.unencrypted_logs_hash), - mapFieldFromNoir(finalAccumulatedData.encrypted_log_preimages_length), - mapFieldFromNoir(finalAccumulatedData.unencrypted_log_preimages_length), - ); -} - -/** - * Maps accumulated data in the Tx's meta phase to the parsed type. - * @param accumulatedMetaData - The noir accumulated meta data. - * @returns The parsed accumulated meta data. - */ -export function mapAccumulatedNonRevertibleDataFromNoir( - accumulatedMetaData: PrivateAccumulatedNonRevertibleDataNoir, -): PrivateAccumulatedNonRevertibleData { - return new PrivateAccumulatedNonRevertibleData( - mapRevertCodeFromNoir(accumulatedMetaData.revert_code), - mapTupleFromNoir(accumulatedMetaData.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), - mapTupleFromNoir( - accumulatedMetaData.new_nullifiers, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - mapSideEffectLinkedFromNoir, - ), - mapTupleFromNoir( - accumulatedMetaData.public_call_stack, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), - ); -} - -/** - * Maps accumulated data in the Tx's meta phase to the parsed type. - * @param accumulatedMetaData - The noir accumulated meta data. - * @returns The parsed accumulated meta data. - */ -export function mapAccumulatedNonRevertibleDataToNoir( - accumulatedMetaData: PrivateAccumulatedNonRevertibleData, -): PrivateAccumulatedNonRevertibleDataNoir { - return { - revert_code: mapRevertCodeToNoir(accumulatedMetaData.revertCode), - new_note_hashes: mapTuple(accumulatedMetaData.newNoteHashes, mapSideEffectToNoir), - new_nullifiers: mapTuple(accumulatedMetaData.newNullifiers, mapSideEffectLinkedToNoir), - public_call_stack: mapTuple(accumulatedMetaData.publicCallStack, mapCallRequestToNoir), - }; -} - -export function mapPrivateAccumulatedRevertibleDataToNoir( - data: PrivateAccumulatedRevertibleData, -): PrivateAccumulatedRevertibleDataNoir { - return { - new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), - new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), - private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), - public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), - new_l2_to_l1_msgs: mapTuple(data.newL2ToL1Msgs, mapFieldToNoir), - encrypted_logs_hash: mapFieldToNoir(data.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(data.unencryptedLogsHash), - encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), - unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), - }; -} - -/** - * Maps combined accumulated data to noir combined accumulated data. - * @param combinedAccumulatedData - The combined accumulated data. - * @returns The noir combined accumulated data. - */ export function mapCombinedAccumulatedDataToNoir( combinedAccumulatedData: CombinedAccumulatedData, ): CombinedAccumulatedDataNoir { return { - revert_code: mapRevertCodeToNoir(combinedAccumulatedData.revertCode), new_note_hashes: mapTuple(combinedAccumulatedData.newNoteHashes, mapSideEffectToNoir), new_nullifiers: mapTuple(combinedAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), - private_call_stack: mapTuple(combinedAccumulatedData.privateCallStack, mapCallRequestToNoir), - public_call_stack: mapTuple(combinedAccumulatedData.publicCallStack, mapCallRequestToNoir), new_l2_to_l1_msgs: mapTuple(combinedAccumulatedData.newL2ToL1Msgs, mapFieldToNoir), encrypted_logs_hash: mapFieldToNoir(combinedAccumulatedData.encryptedLogsHash), unencrypted_logs_hash: mapFieldToNoir(combinedAccumulatedData.unencryptedLogsHash), @@ -1173,73 +1134,36 @@ export function mapCombinedConstantDataToNoir(combinedConstantData: CombinedCons }; } -/** - * Maps the inputs to the private kernel init to the noir representation. - * @param privateKernelInputsInit - The inputs to the private kernel init. - * @returns The noir representation of those inputs. - */ -export function mapPrivateKernelInitCircuitPrivateInputsToNoir( - privateKernelInputsInit: PrivateKernelInitCircuitPrivateInputs, -): PrivateKernelInitCircuitPrivateInputsNoir { - return { - tx_request: mapTxRequestToNoir(privateKernelInputsInit.txRequest), - private_call: mapPrivateCallDataToNoir(privateKernelInputsInit.privateCall), - }; -} - export function mapPublicKernelCircuitPublicInputsToNoir( inputs: PublicKernelCircuitPublicInputs, ): PublicKernelCircuitPublicInputsNoir { return { aggregation_object: {}, constants: mapCombinedConstantDataToNoir(inputs.constants), - rollup_validation_requests: mapRollupValidationRequestsToNoir(inputs.rollupValidationRequests), validation_requests: mapValidationRequestsToNoir(inputs.validationRequests), - end: mapPublicAccumulatedRevertibleDataToNoir(inputs.end), - end_non_revertible: mapPublicAccumulatedNonRevertibleDataToNoir(inputs.endNonRevertibleData), - needs_setup: inputs.needsSetup, - needs_app_logic: inputs.needsAppLogic, - needs_teardown: inputs.needsTeardown, + end: mapPublicAccumulatedDataToNoir(inputs.end), + end_non_revertible: mapPublicAccumulatedDataToNoir(inputs.endNonRevertibleData), + revert_code: mapRevertCodeToNoir(inputs.revertCode), }; } -export function mapRollupKernelCircuitPublicInputsToNoir( - inputs: RollupKernelCircuitPublicInputs, -): RollupKernelCircuitPublicInputsNoir { +export function mapKernelCircuitPublicInputsFromNoir(inputs: KernelCircuitPublicInputsNoir) { + return new KernelCircuitPublicInputs( + AggregationObject.makeFake(), + mapRollupValidationRequestsFromNoir(inputs.rollup_validation_requests), + mapCombinedAccumulatedDataFromNoir(inputs.end), + mapCombinedConstantDataFromNoir(inputs.constants), + mapRevertCodeFromNoir(inputs.revert_code), + ); +} + +export function mapKernelCircuitPublicInputsToNoir(inputs: KernelCircuitPublicInputs): KernelCircuitPublicInputsNoir { return { aggregation_object: {}, rollup_validation_requests: mapRollupValidationRequestsToNoir(inputs.rollupValidationRequests), constants: mapCombinedConstantDataToNoir(inputs.constants), end: mapCombinedAccumulatedDataToNoir(inputs.end), - }; -} - -export function mapPublicAccumulatedRevertibleDataToNoir( - data: PublicAccumulatedRevertibleData, -): PublicAccumulatedRevertibleDataNoir { - return { - new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), - new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), - private_call_stack: mapTuple(data.privateCallStack, mapCallRequestToNoir), - public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), - new_l2_to_l1_msgs: mapTuple(data.newL2ToL1Msgs, mapFieldToNoir), - encrypted_logs_hash: mapFieldToNoir(data.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(data.unencryptedLogsHash), - encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), - unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), - public_data_update_requests: mapTuple(data.publicDataUpdateRequests, mapPublicDataUpdateRequestToNoir), - }; -} - -export function mapPublicAccumulatedNonRevertibleDataToNoir( - data: PublicAccumulatedNonRevertibleData, -): PublicAccumulatedNonRevertibleDataNoir { - return { - revert_code: mapRevertCodeToNoir(data.revertCode), - new_note_hashes: mapTuple(data.newNoteHashes, mapSideEffectToNoir), - new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), - public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), - public_data_update_requests: mapTuple(data.publicDataUpdateRequests, mapPublicDataUpdateRequestToNoir), + revert_code: mapRevertCodeToNoir(inputs.revertCode), }; } @@ -1258,39 +1182,37 @@ export function mapPublicKernelDataToNoir(publicKernelData: PublicKernelData): P }; } -export function mapRollupKernelDataToNoir(rollupKernelData: RollupKernelData): RollupKernelDataNoir { +export function mapKernelDataToNoir(kernelData: KernelData): KernelDataNoir { return { - public_inputs: mapRollupKernelCircuitPublicInputsToNoir(rollupKernelData.publicInputs), + public_inputs: mapKernelCircuitPublicInputsToNoir(kernelData.publicInputs), proof: {}, vk: {}, - vk_index: mapFieldToNoir(new Fr(rollupKernelData.vkIndex)), - vk_path: mapTuple(rollupKernelData.vkPath, mapFieldToNoir), + vk_index: mapFieldToNoir(new Fr(kernelData.vkIndex)), + vk_path: mapTuple(kernelData.vkPath, mapFieldToNoir), }; } -export function mapPrivateKernelInnerCircuitPublicInputsFromNoir( - inputs: PrivateKernelInnerCircuitPublicInputsNoir, -): PrivateKernelInnerCircuitPublicInputs { - return new PrivateKernelInnerCircuitPublicInputs( +export function mapPrivateKernelCircuitPublicInputsFromNoir( + inputs: PrivateKernelCircuitPublicInputsNoir, +): PrivateKernelCircuitPublicInputs { + return new PrivateKernelCircuitPublicInputs( AggregationObject.makeFake(), mapFieldFromNoir(inputs.min_revertible_side_effect_counter), mapValidationRequestsFromNoir(inputs.validation_requests), - mapCombinedAccumulatedDataFromNoir(inputs.end), + mapPrivateAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), - inputs.is_private, ); } -export function mapPrivateKernelInnerCircuitPublicInputsToNoir( - inputs: PrivateKernelInnerCircuitPublicInputs, -): PrivateKernelInnerCircuitPublicInputsNoir { +export function mapPrivateKernelCircuitPublicInputsToNoir( + inputs: PrivateKernelCircuitPublicInputs, +): PrivateKernelCircuitPublicInputsNoir { return { aggregation_object: {}, constants: mapCombinedConstantDataToNoir(inputs.constants), validation_requests: mapValidationRequestsToNoir(inputs.validationRequests), - end: mapCombinedAccumulatedDataToNoir(inputs.end), + end: mapPrivateAccumulatedDataToNoir(inputs.end), min_revertible_side_effect_counter: mapFieldToNoir(inputs.minRevertibleSideEffectCounter), - is_private: inputs.isPrivate, }; } @@ -1299,11 +1221,9 @@ export function mapPrivateKernelInnerCircuitPublicInputsToNoir( * @param privateKernelInnerData - The private kernel inner data. * @returns The noir private kernel inner data. */ -export function mapPrivateKernelInnerDataToNoir( - privateKernelInnerData: PrivateKernelInnerData, -): PrivateKernelInnerDataNoir { +export function mapPrivateKernelDataToNoir(privateKernelInnerData: PrivateKernelData): PrivateKernelDataNoir { return { - public_inputs: mapPrivateKernelInnerCircuitPublicInputsToNoir(privateKernelInnerData.publicInputs), + public_inputs: mapPrivateKernelCircuitPublicInputsToNoir(privateKernelInnerData.publicInputs), proof: {}, vk: {}, vk_index: mapFieldToNoir(new Fr(privateKernelInnerData.vkIndex)), @@ -1311,81 +1231,77 @@ export function mapPrivateKernelInnerDataToNoir( }; } -/** - * Maps final accumulated data to noir final accumulated data. - * @param finalAccumulatedData - The final accumulated data. - * @returns The noir final accumulated data. - */ -export function mapFinalAccumulatedDataToNoir( - finalAccumulatedData: PrivateAccumulatedRevertibleData, -): PrivateAccumulatedRevertibleDataNoir { - return { - new_note_hashes: mapTuple(finalAccumulatedData.newNoteHashes, mapSideEffectToNoir), - new_nullifiers: mapTuple(finalAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), - private_call_stack: mapTuple(finalAccumulatedData.privateCallStack, mapCallRequestToNoir), - public_call_stack: mapTuple(finalAccumulatedData.publicCallStack, mapCallRequestToNoir), - new_l2_to_l1_msgs: mapTuple(finalAccumulatedData.newL2ToL1Msgs, mapFieldToNoir), - encrypted_logs_hash: mapFieldToNoir(finalAccumulatedData.encryptedLogsHash), - unencrypted_logs_hash: mapFieldToNoir(finalAccumulatedData.unencryptedLogsHash), - encrypted_log_preimages_length: mapFieldToNoir(finalAccumulatedData.encryptedLogPreimagesLength), - unencrypted_log_preimages_length: mapFieldToNoir(finalAccumulatedData.unencryptedLogPreimagesLength), - }; +export function mapPrivateKernelTailCircuitPublicInputsForRollupFromNoir( + inputs: KernelCircuitPublicInputsNoir, +): PrivateKernelTailCircuitPublicInputs { + const forRollup = new PartialPrivateTailPublicInputsForRollup( + mapRollupValidationRequestsFromNoir(inputs.rollup_validation_requests), + mapCombinedAccumulatedDataFromNoir(inputs.end), + ); + return new PrivateKernelTailCircuitPublicInputs( + AggregationObject.makeFake(), + mapCombinedConstantDataFromNoir(inputs.constants), + mapRevertCodeFromNoir(inputs.revert_code), + undefined, + forRollup, + ); } -export function mapPrivateKernelTailCircuitPublicInputsFromNoir( - inputs: PrivateKernelTailCircuitPublicInputsNoir, +export function mapPrivateKernelTailCircuitPublicInputsForPublicFromNoir( + inputs: PublicKernelCircuitPublicInputsNoir, ): PrivateKernelTailCircuitPublicInputs { + const forPublic = new PartialPrivateTailPublicInputsForPublic( + mapValidationRequestsFromNoir(inputs.validation_requests), + mapPublicAccumulatedDataFromNoir(inputs.end_non_revertible), + mapPublicAccumulatedDataFromNoir(inputs.end), + ); return new PrivateKernelTailCircuitPublicInputs( AggregationObject.makeFake(), - mapRollupValidationRequestsFromNoir(inputs.rollup_validation_requests), - mapAccumulatedNonRevertibleDataFromNoir(inputs.end_non_revertible), - mapFinalAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), - inputs.needs_setup, - inputs.needs_app_logic, - inputs.needs_teardown, + mapRevertCodeFromNoir(inputs.revert_code), + forPublic, ); } -export function mapPrivateKernelTailCircuitPublicInputsToNoir( - inputs: PrivateKernelTailCircuitPublicInputs, -): PrivateKernelTailCircuitPublicInputsNoir { +export function mapPrivateKernelInitCircuitPrivateInputsToNoir( + privateKernelInputsInit: PrivateKernelInitCircuitPrivateInputs, +): PrivateKernelInitCircuitPrivateInputsNoir { return { - aggregation_object: {}, - rollup_validation_requests: mapRollupValidationRequestsToNoir(inputs.rollupValidationRequests), - constants: mapCombinedConstantDataToNoir(inputs.constants), - end: mapFinalAccumulatedDataToNoir(inputs.end), - end_non_revertible: mapAccumulatedNonRevertibleDataToNoir(inputs.endNonRevertibleData), - needs_setup: inputs.needsSetup, - needs_app_logic: inputs.needsAppLogic, - needs_teardown: inputs.needsTeardown, + tx_request: mapTxRequestToNoir(privateKernelInputsInit.txRequest), + private_call: mapPrivateCallDataToNoir(privateKernelInputsInit.privateCall), }; } -/** - * Maps the private inputs to the private kernel inner to the noir representation. - * @param privateKernelInnerCircuitPrivateInputs - The private inputs to the private kernel inner. - * @returns The noir representation of those inputs. - */ export function mapPrivateKernelInnerCircuitPrivateInputsToNoir( privateKernelInnerCircuitPrivateInputs: PrivateKernelInnerCircuitPrivateInputs, ): PrivateKernelInnerCircuitPrivateInputsNoir { return { - previous_kernel: mapPrivateKernelInnerDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), + previous_kernel: mapPrivateKernelDataToNoir(privateKernelInnerCircuitPrivateInputs.previousKernel), private_call: mapPrivateCallDataToNoir(privateKernelInnerCircuitPrivateInputs.privateCall), }; } -/** - * Maps a private kernel inputs ordering from the circuits.js type to noir. - * @param inputs - The circuits.js private kernel inputs ordering. - * @returns The noir private kernel inputs ordering. - */ export function mapPrivateKernelTailCircuitPrivateInputsToNoir( inputs: PrivateKernelTailCircuitPrivateInputs, ): PrivateKernelTailCircuitPrivateInputsNoir { return { - previous_kernel: mapPrivateKernelInnerDataToNoir(inputs.previousKernel), + previous_kernel: mapPrivateKernelDataToNoir(inputs.previousKernel), + sorted_new_note_hashes: mapTuple(inputs.sortedNewNoteHashes, mapSideEffectToNoir), + sorted_new_note_hashes_indexes: mapTuple(inputs.sortedNewNoteHashesIndexes, mapNumberToNoir), + read_commitment_hints: mapTuple(inputs.readCommitmentHints, mapFieldToNoir), + sorted_new_nullifiers: mapTuple(inputs.sortedNewNullifiers, mapSideEffectLinkedToNoir), + sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), + nullifier_read_request_hints: mapNullifierReadRequestHintsToNoir(inputs.nullifierReadRequestHints), + nullifier_commitment_hints: mapTuple(inputs.nullifierCommitmentHints, mapFieldToNoir), + master_nullifier_secret_keys: mapTuple(inputs.masterNullifierSecretKeys, mapGrumpkinPrivateKeyToNoir), + }; +} + +export function mapPrivateKernelTailToPublicCircuitPrivateInputsToNoir( + inputs: PrivateKernelTailCircuitPrivateInputs, +): PrivateKernelTailToPublicCircuitPrivateInputsNoir { + return { + previous_kernel: mapPrivateKernelDataToNoir(inputs.previousKernel), sorted_new_note_hashes: mapTuple(inputs.sortedNewNoteHashes, mapSideEffectToNoir), sorted_new_note_hashes_indexes: mapTuple(inputs.sortedNewNoteHashesIndexes, mapNumberToNoir), read_commitment_hints: mapTuple(inputs.readCommitmentHints, mapFieldToNoir), @@ -1423,55 +1339,11 @@ export function mapPublicKernelCircuitPublicInputsFromNoir( ): PublicKernelCircuitPublicInputs { return new PublicKernelCircuitPublicInputs( AggregationObject.makeFake(), - mapRollupValidationRequestsFromNoir(inputs.rollup_validation_requests), mapValidationRequestsFromNoir(inputs.validation_requests), - mapPublicAccumulatedNonRevertibleDataFromNoir(inputs.end_non_revertible), - mapPublicAccumulatedRevertibleDataFromNoir(inputs.end), + mapPublicAccumulatedDataFromNoir(inputs.end_non_revertible), + mapPublicAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), - inputs.needs_setup, - inputs.needs_app_logic, - inputs.needs_teardown, - ); -} - -export function mapPublicAccumulatedNonRevertibleDataFromNoir( - data: PublicAccumulatedNonRevertibleDataNoir, -): PublicAccumulatedNonRevertibleData { - return new PublicAccumulatedNonRevertibleData( - mapRevertCodeFromNoir(data.revert_code), - mapTupleFromNoir(data.new_note_hashes, MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), - mapTupleFromNoir(data.new_nullifiers, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), - mapTupleFromNoir( - data.public_call_stack, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - mapCallRequestFromNoir, - ), - mapTupleFromNoir( - data.public_data_update_requests, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - mapPublicDataUpdateRequestFromNoir, - ), - ); -} - -export function mapPublicAccumulatedRevertibleDataFromNoir( - data: PublicAccumulatedRevertibleDataNoir, -): PublicAccumulatedRevertibleData { - return new PublicAccumulatedRevertibleData( - mapTupleFromNoir(data.new_note_hashes, MAX_REVERTIBLE_NOTE_HASHES_PER_TX, mapSideEffectFromNoir), - mapTupleFromNoir(data.new_nullifiers, MAX_REVERTIBLE_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), - mapTupleFromNoir(data.private_call_stack, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), - mapTupleFromNoir(data.public_call_stack, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir), - mapTupleFromNoir(data.new_l2_to_l1_msgs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, mapFieldFromNoir), - mapFieldFromNoir(data.encrypted_logs_hash), - mapFieldFromNoir(data.unencrypted_logs_hash), - mapFieldFromNoir(data.encrypted_log_preimages_length), - mapFieldFromNoir(data.unencrypted_log_preimages_length), - mapTupleFromNoir( - data.public_data_update_requests, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - mapPublicDataUpdateRequestFromNoir, - ), + mapRevertCodeFromNoir(inputs.revert_code), ); } @@ -2018,7 +1890,7 @@ export function mapRootParityInputsToNoir(inputs: RootParityInputs): RootParityI */ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupInputsNoir { return { - kernel_data: mapRollupKernelDataToNoir(inputs.kernelData), + kernel_data: mapKernelDataToNoir(inputs.kernelData), start: mapPartialStateReferenceToNoir(inputs.start), state_diff_hints: mapStateDiffHintsToNoir(inputs.stateDiffHints), @@ -2033,13 +1905,6 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI mapPublicDataMembershipWitnessToNoir, ), - public_data_reads_preimages: mapTuple(inputs.publicDataReadsPreimages, mapPublicDataTreePreimageToNoir), - - public_data_reads_witnesses: mapTuple( - inputs.publicDataReadsMembershipWitnesses, - mapPublicDataMembershipWitnessToNoir, - ), - archive_root_membership_witness: mapArchiveRootMembershipWitnessToNoir(inputs.archiveRootMembershipWitness), constants: mapConstantRollupDataToNoir(inputs.constants), }; diff --git a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts index 587881aad0c..1fc3ed3cd7f 100644 --- a/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts +++ b/yarn-project/prover-client/src/orchestrator/block-building-helpers.ts @@ -8,10 +8,10 @@ import { ConstantRollupData, Fr, type GlobalVariables, + KernelData, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, MAX_NEW_NULLIFIERS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, MergeRollupInputs, @@ -29,10 +29,8 @@ import { PreviousRollupData, type Proof, PublicDataTreeLeaf, - PublicDataTreeLeafPreimage, + type PublicDataTreeLeafPreimage, ROLLUP_VK_TREE_HEIGHT, - RollupKernelCircuitPublicInputs, - RollupKernelData, RollupTypes, RootParityInput, type RootParityInputs, @@ -94,12 +92,11 @@ export async function buildBaseRollupInput( // Update the note hash trees with the new items being inserted to get the new roots // that will be used by the next iteration of the base rollup circuit, skipping the empty ones - const newNoteHashes = tx.data.combinedData.newNoteHashes.map(x => x.value); + const newNoteHashes = tx.data.end.newNoteHashes.map(x => x.value); await db.appendLeaves(MerkleTreeId.NOTE_HASH_TREE, newNoteHashes); // The read witnesses for a given TX should be generated before the writes of the same TX are applied. // All reads that refer to writes in the same tx are transient and can be simplified out. - const txPublicDataReadsInfo = await getPublicDataReadsInfo(tx, db); const txPublicDataUpdateRequestInfo = await processPublicDataUpdateRequests(tx, db); // Update the nullifier tree, capturing the low nullifier info for each individual operation @@ -110,7 +107,7 @@ export async function buildBaseRollupInput( sortedNewLeavesIndexes, } = await db.batchInsert( MerkleTreeId.NULLIFIER_TREE, - tx.data.combinedData.newNullifiers.map(sideEffectLinkedToNoteHash => sideEffectLinkedToNoteHash.value.toBuffer()), + tx.data.end.newNullifiers.map(sideEffectLinkedToNoteHash => sideEffectLinkedToNoteHash.value.toBuffer()), NULLIFIER_SUBTREE_HEIGHT, ); if (nullifierWitnessLeaves === undefined) { @@ -166,8 +163,6 @@ export async function buildBaseRollupInput( sortedPublicDataWritesIndexes: txPublicDataUpdateRequestInfo.sortedPublicDataWritesIndexes, lowPublicDataWritesPreimages: txPublicDataUpdateRequestInfo.lowPublicDataWritesPreimages, lowPublicDataWritesMembershipWitnesses: txPublicDataUpdateRequestInfo.lowPublicDataWritesMembershipWitnesses, - publicDataReadsPreimages: txPublicDataReadsInfo.newPublicDataReadsPreimages, - publicDataReadsMembershipWitnesses: txPublicDataReadsInfo.newPublicDataReadsWitnesses, archiveRootMembershipWitness, @@ -354,15 +349,9 @@ export async function getTreeSnapshot(id: MerkleTreeId, db: MerkleTreeOperations return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size)); } -export function getKernelDataFor(tx: ProcessedTx, vks: VerificationKeys): RollupKernelData { - const inputs = new RollupKernelCircuitPublicInputs( - tx.data.aggregationObject, - tx.data.combinedData, - tx.data.constants, - tx.data.rollupValidationRequests, - ); - return new RollupKernelData( - inputs, +export function getKernelDataFor(tx: ProcessedTx, vks: VerificationKeys): KernelData { + return new KernelData( + tx.data, tx.proof, // VK for the kernel circuit @@ -382,40 +371,8 @@ export function makeEmptyMembershipWitness(height: N) { ); } -export async function getPublicDataReadsInfo(tx: ProcessedTx, db: MerkleTreeOperations) { - const newPublicDataReadsWitnesses: Tuple< - MembershipWitness, - typeof MAX_PUBLIC_DATA_READS_PER_TX - > = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT, 0n)); - - const newPublicDataReadsPreimages: Tuple = makeTuple( - MAX_PUBLIC_DATA_READS_PER_TX, - () => PublicDataTreeLeafPreimage.empty(), - ); - - for (const i in tx.data.validationRequests.publicDataReads) { - const leafSlot = tx.data.validationRequests.publicDataReads[i].leafSlot.value; - const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot); - if (!lowLeafResult) { - throw new Error(`Public data tree should have one initial leaf`); - } - const preimage = await db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); - const path = await db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); - newPublicDataReadsWitnesses[i] = new MembershipWitness( - PUBLIC_DATA_TREE_HEIGHT, - BigInt(lowLeafResult.index), - path.toTuple(), - ); - newPublicDataReadsPreimages[i] = preimage! as PublicDataTreeLeafPreimage; - } - return { - newPublicDataReadsWitnesses, - newPublicDataReadsPreimages, - }; -} - export async function processPublicDataUpdateRequests(tx: ProcessedTx, db: MerkleTreeOperations) { - const combinedPublicDataUpdateRequests = tx.data.combinedData.publicDataUpdateRequests.map(updateRequest => { + const combinedPublicDataUpdateRequests = tx.data.end.publicDataUpdateRequests.map(updateRequest => { return new PublicDataTreeLeaf(updateRequest.leafSlot, updateRequest.newValue); }); const { lowLeavesWitnessData, newSubtreeSiblingPath, sortedNewLeaves, sortedNewLeavesIndexes } = await db.batchInsert( diff --git a/yarn-project/prover-client/src/orchestrator/orchestrator.test.ts b/yarn-project/prover-client/src/orchestrator/orchestrator.test.ts index 9dc8c09ad18..cf2257e3084 100644 --- a/yarn-project/prover-client/src/orchestrator/orchestrator.test.ts +++ b/yarn-project/prover-client/src/orchestrator/orchestrator.test.ts @@ -13,22 +13,17 @@ import { EthAddress, Fr, GlobalVariables, + KernelCircuitPublicInputs, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - MAX_REVERTIBLE_NULLIFIERS_PER_TX, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PUBLIC_DATA_SUBTREE_HEIGHT, Proof, PublicDataTreeLeaf, PublicDataUpdateRequest, - PublicKernelCircuitPublicInputs, type RootRollupPublicInputs, SideEffect, SideEffectLinkedToNoteHash, @@ -131,9 +126,7 @@ describe('prover/tx-prover', () => { MerkleTreeId.NOTE_HASH_TREE, txs.flatMap(tx => padArrayEnd( - [...tx.data.endNonRevertibleData.newNoteHashes, ...tx.data.end.newNoteHashes] - .filter(x => !x.isEmpty()) - .sort(sideEffectCmp), + tx.data.end.newNoteHashes.filter(x => !x.isEmpty()).sort(sideEffectCmp), SideEffect.empty(), MAX_NEW_NOTE_HASHES_PER_TX, ).map(l => l.value), @@ -143,9 +136,7 @@ describe('prover/tx-prover', () => { MerkleTreeId.NULLIFIER_TREE, txs.flatMap(tx => padArrayEnd( - [...tx.data.endNonRevertibleData.newNullifiers, ...tx.data.end.newNullifiers] - .filter(x => !x.isEmpty()) - .sort(sideEffectCmp), + tx.data.end.newNullifiers.filter(x => !x.isEmpty()).sort(sideEffectCmp), SideEffectLinkedToNoteHash.empty(), MAX_NEW_NULLIFIERS_PER_TX, ).map(x => x.value.toBuffer()), @@ -155,11 +146,9 @@ describe('prover/tx-prover', () => { for (const tx of txs) { await expectsDb.batchInsert( MerkleTreeId.PUBLIC_DATA_TREE, - [...tx.data.endNonRevertibleData.publicDataUpdateRequests, ...tx.data.end.publicDataUpdateRequests].map( - write => { - return new PublicDataTreeLeaf(write.leafSlot, write.newValue).toBuffer(); - }, - ), + tx.data.end.publicDataUpdateRequests.map(write => { + return new PublicDataTreeLeaf(write.leafSlot, write.newValue).toBuffer(); + }), PUBLIC_DATA_SUBTREE_HEIGHT, ); } @@ -324,44 +313,30 @@ describe('prover/tx-prover', () => { const makeBloatedProcessedTx = async (seed = 0x1) => { seed *= MAX_NEW_NULLIFIERS_PER_TX; // Ensure no clashing given incremental seeds const tx = mockTx(seed); - const kernelOutput = PublicKernelCircuitPublicInputs.empty(); + const kernelOutput = KernelCircuitPublicInputs.empty(); kernelOutput.constants.historicalHeader = await builderDb.buildInitialHeader(); kernelOutput.end.publicDataUpdateRequests = makeTuple( - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(i + 10)), seed + 0x500, ); - kernelOutput.endNonRevertibleData.publicDataUpdateRequests = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + kernelOutput.end.publicDataUpdateRequests = makeTuple( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(i + 10)), seed + 0x600, ); const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newNoteHashes = makeTuple( - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, - makeNewSideEffect, - seed + 0x100, - ); - processedTx.data.endNonRevertibleData.newNoteHashes = makeTuple( - MAX_NON_REVERTIBLE_NOTE_HASHES_PER_TX, - makeNewSideEffect, - seed + 0x100, - ); + processedTx.data.end.newNoteHashes = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, makeNewSideEffect, seed + 0x100); processedTx.data.end.newNullifiers = makeTuple( - MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, seed + 0x100000, ); - processedTx.data.endNonRevertibleData.newNullifiers = makeTuple( - MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, - makeNewSideEffectLinkedToNoteHash, - seed + 0x100000 + MAX_REVERTIBLE_NULLIFIERS_PER_TX, - ); - - processedTx.data.end.newNullifiers[tx.data.end.newNullifiers.length - 1] = SideEffectLinkedToNoteHash.empty(); + processedTx.data.end.newNullifiers[tx.data.forPublic!.end.newNullifiers.length - 1] = + SideEffectLinkedToNoteHash.empty(); processedTx.data.end.newL2ToL1Msgs = makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x300); processedTx.data.end.encryptedLogsHash = Fr.fromBuffer(processedTx.encryptedLogs.hash()); diff --git a/yarn-project/prover-client/src/prover/empty.ts b/yarn-project/prover-client/src/prover/empty.ts index c06d68ad444..31d20ebecc2 100644 --- a/yarn-project/prover-client/src/prover/empty.ts +++ b/yarn-project/prover-client/src/prover/empty.ts @@ -4,6 +4,7 @@ import { type BaseOrMergeRollupPublicInputs, type BaseParityInputs, type BaseRollupInputs, + type KernelCircuitPublicInputs, type MergeRollupInputs, type ParityPublicInputs, Proof, @@ -94,4 +95,8 @@ export class EmptyPublicProver implements PublicProver { async getPublicKernelCircuitProof(_publicInputs: PublicKernelCircuitPublicInputs): Promise { return new Proof(Buffer.alloc(EMPTY_PROOF_SIZE, 0)); } + + async getPublicTailKernelCircuitProof(_publicInputs: KernelCircuitPublicInputs): Promise { + return new Proof(Buffer.alloc(EMPTY_PROOF_SIZE, 0)); + } } diff --git a/yarn-project/prover-client/src/prover/index.ts b/yarn-project/prover-client/src/prover/index.ts index 4c1be5db433..cb5e0412918 100644 --- a/yarn-project/prover-client/src/prover/index.ts +++ b/yarn-project/prover-client/src/prover/index.ts @@ -2,6 +2,7 @@ import { type BaseOrMergeRollupPublicInputs, type BaseParityInputs, type BaseRollupInputs, + type KernelCircuitPublicInputs, type MergeRollupInputs, type ParityPublicInputs, type Proof, @@ -67,4 +68,10 @@ export interface PublicProver { * @param publicInputs - Public inputs obtained via simulation. */ getPublicKernelCircuitProof(publicInputs: PublicKernelCircuitPublicInputs): Promise; + + /** + * Creates a proof for the given input. + * @param publicInputs - Public inputs obtained via simulation. + */ + getPublicTailKernelCircuitProof(publicInputs: KernelCircuitPublicInputs): Promise; } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts index 094acb78924..8e7394b5dd9 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -5,12 +5,11 @@ import { MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NOTE_HASHES_PER_TX, MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, - MAX_REVERTIBLE_NOTE_HASHES_PER_TX, MembershipWitness, NoteHashReadRequestMembershipWitness, PrivateCallStackItem, PrivateCircuitPublicInputs, - PrivateKernelInnerCircuitPublicInputs, + PrivateKernelCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, SideEffect, type TxRequest, @@ -26,7 +25,7 @@ import { type ExecutionResult, type NoteAndSlot } from '@aztec/simulator'; import { mock } from 'jest-mock-extended'; -import { KernelProver, type OutputNoteData } from './kernel_prover.js'; +import { KernelProver } from './kernel_prover.js'; import { type ProofCreator } from './proof_creator.js'; import { type ProvingDataOracle } from './proving_data_oracle.js'; @@ -82,7 +81,7 @@ describe('Kernel Prover', () => { }; const createProofOutput = (newNoteIndices: number[]) => { - const publicInputs = PrivateKernelInnerCircuitPublicInputs.empty(); + const publicInputs = PrivateKernelCircuitPublicInputs.empty(); const commitments = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); @@ -97,12 +96,13 @@ describe('Kernel Prover', () => { const createProofOutputFinal = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelTailCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_REVERTIBLE_NOTE_HASHES_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_NEW_NOTE_HASHES_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } - publicInputs.end.newNoteHashes = commitments; + publicInputs.forRollup!.end.newNoteHashes = commitments; + return { publicInputs, proof: makeEmptyProof(), @@ -124,13 +124,6 @@ describe('Kernel Prover', () => { proofCreator.createProofInit.mockClear(); }; - const expectOutputNotes = (outputNotes: OutputNoteData[], expectedNoteIndices: number[]) => { - expect(outputNotes.length).toBe(expectedNoteIndices.length); - outputNotes.forEach((n, i) => { - expect(n.data).toEqual(notesAndSlots[expectedNoteIndices[i]]); - }); - }; - const prove = (executionResult: ExecutionResult) => prover.prove(txRequest, executionResult); beforeEach(() => { @@ -191,22 +184,4 @@ describe('Kernel Prover', () => { expectExecution(['k', 'o', 'r', 'p', 'n', 'm', 'q']); } }); - - it('should only return notes that are outputted from the final proof', async () => { - const resultA = createExecutionResult('a', [1, 2, 3]); - const resultB = createExecutionResult('b', [4]); - const resultC = createExecutionResult('c', [5, 6]); - proofCreator.createProofInit.mockResolvedValueOnce(createProofOutput([1, 2, 3])); - proofCreator.createProofInner.mockResolvedValueOnce(createProofOutput([1, 3, 4])); - proofCreator.createProofInner.mockResolvedValueOnce(createProofOutput([1, 3, 5, 6])); - proofCreator.createProofTail.mockResolvedValueOnce(createProofOutputFinal([1, 3, 5, 6])); - - const executionResult = { - ...resultA, - nestedExecutions: [resultB, resultC], - }; - const { outputNotes } = await prove(executionResult); - expectExecution(['a', 'c', 'b']); - expectOutputNotes(outputNotes, [1, 3, 5, 6]); - }); }); diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 6875db0ec9f..123ee026b92 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -1,5 +1,4 @@ import { - type AztecAddress, CallRequest, Fr, type MAX_NEW_NOTE_HASHES_PER_TX, @@ -9,10 +8,10 @@ import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, NoteHashReadRequestMembershipWitness, PrivateCallData, + PrivateKernelCircuitPublicInputs, + PrivateKernelData, PrivateKernelInitCircuitPrivateInputs, PrivateKernelInnerCircuitPrivateInputs, - PrivateKernelInnerCircuitPublicInputs, - PrivateKernelInnerData, PrivateKernelTailCircuitPrivateInputs, type SideEffect, type SideEffectLinkedToNoteHash, @@ -26,43 +25,12 @@ import { padArrayEnd } from '@aztec/foundation/collection'; import { createDebugLogger } from '@aztec/foundation/log'; import { assertLength, mapTuple } from '@aztec/foundation/serialize'; import { pushTestData } from '@aztec/foundation/testing'; -import { type ExecutionResult, type NoteAndSlot } from '@aztec/simulator'; +import { type ExecutionResult } from '@aztec/simulator'; import { HintsBuilder } from './hints_builder.js'; import { KernelProofCreator, type ProofCreator, type ProofOutput, type ProofOutputFinal } from './proof_creator.js'; import { type ProvingDataOracle } from './proving_data_oracle.js'; -/** - * Represents an output note data object. - * Contains the contract address, new note data and commitment for the note, - * resulting from the execution of a transaction in the Aztec network. - */ -export interface OutputNoteData { - /** - * The address of the contract the note was created in. - */ - contractAddress: AztecAddress; - /** - * The encrypted note data for an output note. - */ - data: NoteAndSlot; - /** - * The unique value representing the note. - */ - commitment: Fr; -} - -/** - * Represents the output data of the Kernel Prover. - * Provides information about the newly created notes, along with the public inputs and proof. - */ -export interface KernelProverOutput extends ProofOutputFinal { - /** - * An array of output notes containing the contract address, note data, and commitment for each new note. - */ - outputNotes: OutputNoteData[]; -} - /** * The KernelProver class is responsible for generating kernel proofs. * It takes a transaction request, its signature, and the simulation result as inputs, and outputs a proof @@ -87,14 +55,13 @@ export class KernelProver { * @param executionResult - The execution result object containing nested executions and preimages. * @returns A Promise that resolves to a KernelProverOutput object containing proof, public inputs, and output notes. */ - async prove(txRequest: TxRequest, executionResult: ExecutionResult): Promise { + async prove(txRequest: TxRequest, executionResult: ExecutionResult): Promise { const executionStack = [executionResult]; - const newNotes: { [commitmentStr: string]: OutputNoteData } = {}; let firstIteration = true; let previousVerificationKey = VerificationKey.makeFake(); let output: ProofOutput = { - publicInputs: PrivateKernelInnerCircuitPublicInputs.empty(), + publicInputs: PrivateKernelCircuitPublicInputs.empty(), proof: makeEmptyProof(), }; @@ -147,7 +114,7 @@ export class KernelProver { output = await this.proofCreator.createProofInit(proofInput); } else { const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(previousVerificationKey); - const previousKernelData = new PrivateKernelInnerData( + const previousKernelData = new PrivateKernelData( output.publicInputs, output.proof, previousVerificationKey, @@ -158,15 +125,12 @@ export class KernelProver { pushTestData('private-kernel-inputs-inner', proofInput); output = await this.proofCreator.createProofInner(proofInput); } - (await this.getNewNotes(currentExecution)).forEach(n => { - newNotes[n.commitment.toString()] = n; - }); firstIteration = false; previousVerificationKey = privateCallData.vk; } const previousVkMembershipWitness = await this.oracle.getVkMembershipWitness(previousVerificationKey); - const previousKernelData = new PrivateKernelInnerData( + const previousKernelData = new PrivateKernelData( output.publicInputs, output.proof, previousVerificationKey, @@ -174,6 +138,20 @@ export class KernelProver { assertLength(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT), ); + const readNoteHashHints = this.hintsBuilder.getNoteHashReadRequestHints( + output.publicInputs.validationRequests.noteHashReadRequests, + output.publicInputs.end.newNoteHashes, + ); + + const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( + output.publicInputs.validationRequests.nullifierReadRequests, + output.publicInputs.end.newNullifiers, + ); + + const masterNullifierSecretKeys = await this.hintsBuilder.getMasterNullifierSecretKeys( + output.publicInputs.validationRequests.nullifierKeyValidationRequests, + ); + const [sortedNoteHashes, sortedNoteHashesIndexes] = this.hintsBuilder.sortSideEffects< SideEffect, typeof MAX_NEW_NOTE_HASHES_PER_TX @@ -184,25 +162,11 @@ export class KernelProver { typeof MAX_NEW_NULLIFIERS_PER_TX >(output.publicInputs.end.newNullifiers); - const readNoteHashHints = this.hintsBuilder.getNoteHashReadRequestHints( - output.publicInputs.validationRequests.noteHashReadRequests, - sortedNoteHashes, - ); - - const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( - output.publicInputs.validationRequests.nullifierReadRequests, - output.publicInputs.end.newNullifiers, - ); - const nullifierNoteHashHints = this.hintsBuilder.getNullifierHints( mapTuple(sortedNullifiers, n => n.noteHash), sortedNoteHashes, ); - const masterNullifierSecretKeys = await this.hintsBuilder.getMasterNullifierSecretKeys( - output.publicInputs.validationRequests.nullifierKeyValidationRequests, - ); - this.log.debug( `Calling private kernel tail with hwm ${previousKernelData.publicInputs.minRevertibleSideEffectCounter}`, ); @@ -219,13 +183,7 @@ export class KernelProver { masterNullifierSecretKeys, ); pushTestData('private-kernel-inputs-ordering', privateInputs); - const outputFinal = await this.proofCreator.createProofTail(privateInputs); - - // Only return the notes whose commitment is in the commitments of the final proof. - const finalNewCommitments = outputFinal.publicInputs.end.newNoteHashes; - const outputNotes = finalNewCommitments.map(c => newNotes[c.value.toString()]).filter(c => !!c); - - return { ...outputFinal, outputNotes }; + return await this.proofCreator.createProofTail(privateInputs); } private async createPrivateCallData( @@ -282,28 +240,4 @@ export class KernelProver { acirHash, }); } - - /** - * Retrieves the new output notes for a given execution result. - * The function maps over the new notes and associates them with their corresponding - * commitments in the public inputs of the execution result. It also includes the contract address - * from the call context of the public inputs. - * - * @param executionResult - The execution result object containing notes and public inputs. - * @returns An array of OutputNoteData objects, each representing an output note with its associated data. - */ - private async getNewNotes(executionResult: ExecutionResult): Promise { - const { - callStackItem: { publicInputs }, - newNotes, - } = executionResult; - const contractAddress = publicInputs.callContext.storageContractAddress; - // Assuming that for each new commitment there's an output note added to the execution result. - const newNoteHashes = await this.proofCreator.getSiloedCommitments(publicInputs); - return newNotes.map((data, i) => ({ - contractAddress, - data, - commitment: newNoteHashes[i], - })); - } } diff --git a/yarn-project/pxe/src/kernel_prover/proof_creator.ts b/yarn-project/pxe/src/kernel_prover/proof_creator.ts index c7db9590c60..9e79d1fc552 100644 --- a/yarn-project/pxe/src/kernel_prover/proof_creator.ts +++ b/yarn-project/pxe/src/kernel_prover/proof_creator.ts @@ -1,9 +1,9 @@ import { type CircuitSimulationStats } from '@aztec/circuit-types/stats'; import { type PrivateCircuitPublicInputs, + type PrivateKernelCircuitPublicInputs, type PrivateKernelInitCircuitPrivateInputs, type PrivateKernelInnerCircuitPrivateInputs, - type PrivateKernelInnerCircuitPublicInputs, type PrivateKernelTailCircuitPrivateInputs, type PrivateKernelTailCircuitPublicInputs, type Proof, @@ -13,7 +13,7 @@ import { siloNoteHash } from '@aztec/circuits.js/hash'; import { type Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; -import { executeInit, executeInner, executeTail } from '@aztec/noir-protocol-circuits-types'; +import { executeInit, executeInner, executeTail, executeTailForPublic } from '@aztec/noir-protocol-circuits-types'; /** * Represents the output of the proof creation process for init and inner private kernel circuit. @@ -23,7 +23,7 @@ export interface ProofOutput { /** * The public inputs required for the proof generation process. */ - publicInputs: PrivateKernelInnerCircuitPublicInputs; + publicInputs: PrivateKernelCircuitPublicInputs; /** * The zk-SNARK proof for the kernel execution. */ @@ -138,7 +138,10 @@ export class KernelProofCreator implements ProofCreator { } public async createProofTail(privateInputs: PrivateKernelTailCircuitPrivateInputs): Promise { - const [duration, result] = await elapsed(() => executeTail(privateInputs)); + const isForPublic = privateInputs.isForPublic(); + const [duration, result] = await elapsed(() => + isForPublic ? executeTailForPublic(privateInputs) : executeTail(privateInputs), + ); this.log(`Simulated private kernel ordering`, { eventName: 'circuit-simulation', circuitName: 'private-kernel-ordering', diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index c08323ce9e6..92079b73330 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -28,8 +28,7 @@ import { CompleteAddress, FunctionData, type GrumpkinPrivateKey, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, type PartialAddress, type PrivateKernelTailCircuitPublicInputs, type PublicCallRequest, @@ -637,9 +636,6 @@ export class PXEService implements PXE { const kernelProver = new KernelProver(kernelOracle); this.log(`Executing kernel prover...`); const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult); - this.log( - `Needs setup: ${publicInputs.needsSetup}, needs app logic: ${publicInputs.needsAppLogic}, needs teardown: ${publicInputs.needsTeardown}`, - ); const encryptedLogs = new EncryptedTxL2Logs(collectEncryptedLogs(executionResult)); const unencryptedLogs = new UnencryptedTxL2Logs(collectUnencryptedLogs(executionResult)); @@ -701,55 +697,62 @@ export class PXEService implements PXE { publicInputs: PrivateKernelTailCircuitPublicInputs, enqueuedPublicCalls: PublicCallRequest[], ) { + if (!publicInputs.forPublic) { + return; + } + const enqueuedPublicCallStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest())); // Validate all items in enqueued public calls are in the kernel emitted stack const enqueuedRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued => - publicInputs.end.publicCallStack.find(item => item.equals(enqueued)), + publicInputs.forPublic!.end.publicCallStack.find(item => item.equals(enqueued)), ); - const revertibleStackSize = arrayNonEmptyLength(publicInputs.end.publicCallStack, item => item.isEmpty()); + const revertibleStackSize = arrayNonEmptyLength(publicInputs.forPublic.end.publicCallStack, item => item.isEmpty()); if (enqueuedRevertiblePublicCallStackItems.length !== revertibleStackSize) { throw new Error( `Enqueued revertible public function calls and revertible public call stack do not match.\nEnqueued calls: ${enqueuedRevertiblePublicCallStackItems .map(h => h.hash.toString()) - .join(', ')}\nPublic call stack: ${publicInputs.end.publicCallStack.map(i => i.toString()).join(', ')}`, + .join(', ')}\nPublic call stack: ${publicInputs.forPublic.end.publicCallStack + .map(i => i.toString()) + .join(', ')}`, ); } // Override kernel output - publicInputs.end.publicCallStack = padArrayEnd( + publicInputs.forPublic.end.publicCallStack = padArrayEnd( enqueuedRevertiblePublicCallStackItems, CallRequest.empty(), - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, ); // Do the same for non-revertible const enqueuedNonRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued => - publicInputs.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)), + publicInputs.forPublic!.endNonRevertibleData.publicCallStack.find(item => item.equals(enqueued)), ); - const nonRevertibleStackSize = arrayNonEmptyLength(publicInputs.endNonRevertibleData.publicCallStack, item => - item.isEmpty(), + const nonRevertibleStackSize = arrayNonEmptyLength( + publicInputs.forPublic.endNonRevertibleData.publicCallStack, + item => item.isEmpty(), ); if (enqueuedNonRevertiblePublicCallStackItems.length !== nonRevertibleStackSize) { throw new Error( `Enqueued non-revertible public function calls and non-revertible public call stack do not match.\nEnqueued calls: ${enqueuedNonRevertiblePublicCallStackItems .map(h => h.hash.toString()) - .join(', ')}\nPublic call stack: ${publicInputs.endNonRevertibleData.publicCallStack + .join(', ')}\nPublic call stack: ${publicInputs.forPublic.endNonRevertibleData.publicCallStack .map(i => i.toString()) .join(', ')}`, ); } // Override kernel output - publicInputs.endNonRevertibleData.publicCallStack = padArrayEnd( + publicInputs.forPublic.endNonRevertibleData.publicCallStack = padArrayEnd( enqueuedNonRevertiblePublicCallStackItems, CallRequest.empty(), - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, ); } diff --git a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts index c26f2a2e2a2..8f162660247 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -7,18 +7,18 @@ import { Fr, type GlobalVariables, type Header, + type KernelCircuitPublicInputs, L2ToL1Message, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NOTE_HASHES_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL, MAX_NULLIFIER_READ_REQUESTS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, type PrivateKernelTailCircuitPublicInputs, type Proof, @@ -31,7 +31,6 @@ import { PublicKernelCircuitPrivateInputs, type PublicKernelCircuitPublicInputs, PublicKernelData, - PublicKernelTailCircuitPrivateInputs, RETURN_VALUES_LENGTH, ReadRequest, RevertCode, @@ -109,6 +108,10 @@ export abstract class AbstractPhaseManager { * the output of the public kernel circuit for this phase */ publicKernelOutput: PublicKernelCircuitPublicInputs; + /** + * the final output of the public kernel circuit for this phase + */ + finalKernelOutput?: KernelCircuitPublicInputs; /** * the proof of the public kernel circuit for this phase */ @@ -125,8 +128,10 @@ export abstract class AbstractPhaseManager { enqueuedPublicFunctionCalls: PublicCallRequest[], ): Record { const publicCallsStack = enqueuedPublicFunctionCalls.slice().reverse(); - const nonRevertibleCallStack = publicInputs.endNonRevertibleData.publicCallStack.filter(i => !i.isEmpty()); - const revertibleCallStack = publicInputs.end.publicCallStack.filter(i => !i.isEmpty()); + const nonRevertibleCallStack = publicInputs.forPublic!.endNonRevertibleData.publicCallStack.filter( + i => !i.isEmpty(), + ); + const revertibleCallStack = publicInputs.forPublic!.end.publicCallStack.filter(i => !i.isEmpty()); const callRequestsStack = publicCallsStack .map(call => call.toCallRequest()) @@ -258,7 +263,7 @@ export abstract class AbstractPhaseManager { // sanity check. Note we can't expect them to just be equal, because e.g. // if the simulator reverts in app logic, it "resets" and result.reverted will be false when we run teardown, // but the kernel carries the reverted flag forward. But if the simulator reverts, so should the kernel. - if (result.reverted && kernelOutput.endNonRevertibleData.revertCode.isOK()) { + if (result.reverted && kernelOutput.revertCode.isOK()) { throw new Error( `Public kernel circuit did not revert on ${result.execution.contractAddress.toString()}:${functionSelector}, but simulator did.`, ); @@ -297,7 +302,7 @@ export abstract class AbstractPhaseManager { } // TODO(#3675): This should be done in a public kernel circuit - removeRedundantPublicDataWrites(kernelOutput); + removeRedundantPublicDataWrites(kernelOutput, this.phase); return [kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns]; } @@ -305,43 +310,19 @@ export abstract class AbstractPhaseManager { protected async runKernelCircuit( previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof, - callData?: PublicCallData, + callData: PublicCallData, ): Promise<[PublicKernelCircuitPublicInputs, Proof]> { const output = await this.getKernelCircuitOutput(previousOutput, previousProof, callData); return [output, makeEmptyProof()]; } - protected async getKernelCircuitOutput( + protected getKernelCircuitOutput( previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof, - callData?: PublicCallData, + callData: PublicCallData, ): Promise { const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); - if (this.phase === PublicKernelPhase.TAIL) { - const { validationRequests, endNonRevertibleData, end } = previousOutput; - const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( - validationRequests.nullifierReadRequests, - endNonRevertibleData.newNullifiers, - end.newNullifiers, - ); - const nullifierNonExistentReadRequestHints = await this.hintsBuilder.getNullifierNonExistentReadRequestHints( - validationRequests.nullifierNonExistentReadRequests, - endNonRevertibleData.newNullifiers, - end.newNullifiers, - ); - const inputs = new PublicKernelTailCircuitPrivateInputs( - previousKernel, - nullifierReadRequestHints, - nullifierNonExistentReadRequestHints, - ); - return this.publicKernel.publicKernelCircuitTail(inputs); - } - - if (!callData) { - throw new Error(`Cannot run public kernel circuit without call data for phase '${this.phase}'.`); - } - const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); switch (this.phase) { case PublicKernelPhase.SETUP: @@ -467,26 +448,30 @@ export abstract class AbstractPhaseManager { } } -function removeRedundantPublicDataWrites(publicInputs: PublicKernelCircuitPublicInputs) { - const patch = (requests: Tuple) => { - const lastWritesMap = new Map(); - for (const write of requests) { - const key = write.leafSlot.toString(); - lastWritesMap.set(key, write); - } - return requests.filter(write => lastWritesMap.get(write.leafSlot.toString())?.equals(write)); - }; +function removeRedundantPublicDataWrites(publicInputs: PublicKernelCircuitPublicInputs, phase: PublicKernelPhase) { + const lastWritesMap = new Map(); + const patch = (requests: Tuple) => + requests.filter(write => { + const leafSlot = write.leafSlot.toString(); + const exists = lastWritesMap.get(leafSlot); + lastWritesMap.set(leafSlot, true); + return !exists; + }); + + const [prev, curr] = PhaseIsRevertible[phase] + ? [publicInputs.endNonRevertibleData, publicInputs.end] + : [publicInputs.end, publicInputs.endNonRevertibleData]; - publicInputs.end.publicDataUpdateRequests = padArrayEnd( - patch(publicInputs.end.publicDataUpdateRequests), + curr.publicDataUpdateRequests = padArrayEnd( + patch(curr.publicDataUpdateRequests.reverse()).reverse(), PublicDataUpdateRequest.empty(), - MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ); - publicInputs.endNonRevertibleData.publicDataUpdateRequests = padArrayEnd( - patch(publicInputs.endNonRevertibleData.publicDataUpdateRequests), + prev.publicDataUpdateRequests = padArrayEnd( + patch(prev.publicDataUpdateRequests.reverse()), PublicDataUpdateRequest.empty(), - MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ); } @@ -563,8 +548,6 @@ function patchPublicStorageActionOrdering( ...simPublicDataUpdateRequests, ], PublicDataUpdateRequest.empty(), - PhaseIsRevertible[phase] - ? MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX - : MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ); } diff --git a/yarn-project/sequencer-client/src/sequencer/hints_builder.ts b/yarn-project/sequencer-client/src/sequencer/hints_builder.ts index 61e28fc5dcf..b2a581d7696 100644 --- a/yarn-project/sequencer-client/src/sequencer/hints_builder.ts +++ b/yarn-project/sequencer-client/src/sequencer/hints_builder.ts @@ -2,18 +2,21 @@ import { MerkleTreeId } from '@aztec/circuit-types'; import { type Fr, MAX_NEW_NULLIFIERS_PER_TX, - type MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, type MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_TX, type MAX_NULLIFIER_READ_REQUESTS_PER_TX, - type MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_PUBLIC_DATA_READS_PER_TX, MembershipWitness, NULLIFIER_TREE_HEIGHT, + PUBLIC_DATA_TREE_HEIGHT, + type PublicDataRead, + PublicDataTreeLeafPreimage, type ReadRequestContext, type SideEffectLinkedToNoteHash, buildNullifierNonExistentReadRequestHints, buildNullifierReadRequestHints, - concatAccumulatedData, + mergeAccumulatedData, } from '@aztec/circuits.js'; +import { makeTuple } from '@aztec/foundation/array'; import { type Tuple } from '@aztec/foundation/serialize'; import { type MerkleTreeOperations } from '@aztec/world-state'; @@ -22,22 +25,22 @@ export class HintsBuilder { getNullifierReadRequestHints( nullifierReadRequests: Tuple, - nullifiersNonRevertible: Tuple, - nullifiersRevertible: Tuple, + nullifiersNonRevertible: Tuple, + nullifiersRevertible: Tuple, ) { return buildNullifierReadRequestHints( this, nullifierReadRequests, - concatAccumulatedData(MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible), + mergeAccumulatedData(MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible), ); } getNullifierNonExistentReadRequestHints( nullifierNonExistentReadRequests: Tuple, - nullifiersNonRevertible: Tuple, - nullifiersRevertible: Tuple, + nullifiersNonRevertible: Tuple, + nullifiersRevertible: Tuple, ) { - const pendingNullifiers = concatAccumulatedData( + const pendingNullifiers = mergeAccumulatedData( MAX_NEW_NULLIFIERS_PER_TX, nullifiersNonRevertible, nullifiersRevertible, @@ -83,4 +86,34 @@ export class HintsBuilder { return { membershipWitness, leafPreimage }; } + + async getPublicDataReadsInfo(publicDataReads: PublicDataRead[]) { + const newPublicDataReadsWitnesses: Tuple< + MembershipWitness, + typeof MAX_PUBLIC_DATA_READS_PER_TX + > = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT, 0n)); + + const newPublicDataReadsPreimages: Tuple = + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataTreeLeafPreimage.empty()); + + for (const i in publicDataReads) { + const leafSlot = publicDataReads[i].leafSlot.value; + const lowLeafResult = await this.db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot); + if (!lowLeafResult) { + throw new Error(`Public data tree should have one initial leaf`); + } + const preimage = await this.db.getLeafPreimage(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); + const path = await this.db.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index); + newPublicDataReadsWitnesses[i] = new MembershipWitness( + PUBLIC_DATA_TREE_HEIGHT, + BigInt(lowLeafResult.index), + path.toTuple(), + ); + newPublicDataReadsPreimages[i] = preimage! as PublicDataTreeLeafPreimage; + } + return { + newPublicDataReadsWitnesses, + newPublicDataReadsPreimages, + }; + } } diff --git a/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts b/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts index d2e3ec594a4..dd4d24c6a82 100644 --- a/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts +++ b/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts @@ -34,7 +34,8 @@ export class PhaseManagerFactory { publicContractsDB: ContractsDataSourcePublicDB, publicStateDB: PublicStateDB, ): AbstractPhaseManager | undefined { - if (tx.data.needsSetup) { + const data = tx.data.forPublic!; + if (data.needsSetup) { return new SetupPhaseManager( db, publicExecutor, @@ -44,7 +45,7 @@ export class PhaseManagerFactory { publicContractsDB, publicStateDB, ); - } else if (tx.data.needsAppLogic) { + } else if (data.needsAppLogic) { return new AppLogicPhaseManager( db, publicExecutor, @@ -54,7 +55,7 @@ export class PhaseManagerFactory { publicContractsDB, publicStateDB, ); - } else if (tx.data.needsTeardown) { + } else if (data.needsTeardown) { return new TeardownPhaseManager( db, publicExecutor, diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index cd589b0e70d..b1794ec5999 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -22,17 +22,13 @@ import { FunctionData, GlobalVariables, Header, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PUBLIC_DATA_TREE_HEIGHT, type PrivateKernelTailCircuitPublicInputs, type Proof, - PublicAccumulatedNonRevertibleData, - PublicAccumulatedRevertibleData, type PublicCallRequest, - PublicKernelCircuitPublicInputs, - ValidationRequests, + PublicDataUpdateRequest, makeEmptyProof, } from '@aztec/circuits.js'; import { computePublicDataTreeLeafSlot } from '@aztec/circuits.js/hash'; @@ -96,18 +92,10 @@ describe('public_processor', () => { }); it('skips txs without public execution requests', async function () { - const seed = 1; - const includeLogs = false; - const tx = mockTx(seed, includeLogs); - tx.data.end.publicCallStack = makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty); - tx.data.end.unencryptedLogsHash = Fr.ZERO; - tx.data.endNonRevertibleData.publicCallStack = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - CallRequest.empty, - ); - tx.data.needsSetup = false; - tx.data.needsAppLogic = false; - tx.data.needsTeardown = false; + const tx = mockTx(1, { + numberOfNonRevertiblePublicCallRequests: 0, + numberOfRevertiblePublicCallRequests: 0, + }); const hash = tx.getTxHash(); const [processed, failed] = await processor.process([tx]); @@ -117,17 +105,7 @@ describe('public_processor', () => { const p = processed[0]; const e: ProcessedTx = { hash, - data: new PublicKernelCircuitPublicInputs( - tx.data.aggregationObject, - tx.data.rollupValidationRequests, - ValidationRequests.empty(), - PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData), - PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end), - tx.data.constants, - tx.data.needsSetup, - tx.data.needsAppLogic, - tx.data.needsTeardown, - ), + data: tx.data.toKernelCircuitPublicInputs(), proof: tx.proof, encryptedLogs: tx.encryptedLogs, unencryptedLogs: tx.unencryptedLogs, @@ -153,8 +131,7 @@ describe('public_processor', () => { it('returns failed txs without aborting entire operation', async function () { publicExecutor.simulate.mockRejectedValue(new SimulationError(`Failed`, [])); - const tx = mockTx(1, false); - tx.data.needsSetup = false; + const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 1 }); const [processed, failed] = await processor.process([tx]); expect(processed).toEqual([]); @@ -190,36 +167,10 @@ describe('public_processor', () => { }); it('runs a tx with enqueued public calls', async function () { - const publicCallRequests: PublicCallRequest[] = [makePublicCallRequest(0x100), makePublicCallRequest(0x100)]; - const callRequests = publicCallRequests.map(call => call.toCallRequest()); - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.end.publicCallStack = padArrayEnd( - callRequests, - CallRequest.empty(), - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - ); - kernelOutput.end.privateCallStack = padArrayEnd([], CallRequest.empty(), MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX); - - kernelOutput.endNonRevertibleData.publicCallStack = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - CallRequest.empty, - ); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; - - const tx = new Tx( - kernelOutput, - proof, - EncryptedTxL2Logs.empty(), - UnencryptedTxL2Logs.empty(), - publicCallRequests, - ); - - tx.data.needsSetup = false; - tx.data.needsTeardown = false; + const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 2 }); publicExecutor.simulate.mockImplementation(execution => { - for (const request of publicCallRequests) { + for (const request of tx.enqueuedPublicFunctionCalls) { if (execution.contractAddress.equals(request.contractAddress)) { const result = PublicExecutionResultBuilder.fromPublicCallRequest({ request }).build(); // result.unencryptedLogs = tx.unencryptedLogs.functionLogs[0]; @@ -240,26 +191,8 @@ describe('public_processor', () => { }); it('runs a tx with an enqueued public call with nested execution', async function () { - const callRequest: PublicCallRequest = makePublicCallRequest(0x100); - const callStackItem = callRequest.toCallRequest(); - - const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.end.publicCallStack = padArrayEnd( - [callStackItem], - CallRequest.empty(), - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - ); - kernelOutput.end.privateCallStack = padArrayEnd([], CallRequest.empty(), MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX); - kernelOutput.endNonRevertibleData.publicCallStack = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - CallRequest.empty, - ); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; - - kernelOutput.needsSetup = false; - kernelOutput.needsTeardown = false; - - const tx = new Tx(kernelOutput, proof, EncryptedTxL2Logs.empty(), UnencryptedTxL2Logs.empty(), [callRequest]); + const tx = mockTx(1, { numberOfNonRevertiblePublicCallRequests: 0, numberOfRevertiblePublicCallRequests: 1 }); + const callRequest = tx.enqueuedPublicFunctionCalls[0]; const publicExecutionResult = PublicExecutionResultBuilder.fromPublicCallRequest({ request: callRequest, @@ -298,7 +231,14 @@ describe('public_processor', () => { callRequests[2].callContext.sideEffectCounter = 4; const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; + kernelOutput.forPublic!.endNonRevertibleData.publicDataUpdateRequests = makeTuple( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PublicDataUpdateRequest.empty, + ); + kernelOutput.forPublic!.end.publicDataUpdateRequests = makeTuple( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PublicDataUpdateRequest.empty, + ); addKernelPublicCallStack(kernelOutput, { setupCalls: [callRequests[0]], @@ -387,8 +327,6 @@ describe('public_processor', () => { expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); expect(publicWorldStateDB.rollbackToCommit).toHaveBeenCalledTimes(0); - expect(arrayNonEmptyLength(processed[0].data.combinedData.publicCallStack, i => i.isEmpty())).toEqual(0); - const txEffect = toTxEffect(processed[0]); expect(arrayNonEmptyLength(txEffect.publicDataWrites, PublicDataWrite.isEmpty)).toEqual(2); expect(txEffect.publicDataWrites[0]).toEqual( @@ -414,7 +352,6 @@ describe('public_processor', () => { callRequests[2].callContext.sideEffectCounter = 4; const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; addKernelPublicCallStack(kernelOutput, { setupCalls: [callRequests[0]], @@ -518,7 +455,6 @@ describe('public_processor', () => { callRequests[2].callContext.sideEffectCounter = 4; const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; addKernelPublicCallStack(kernelOutput, { setupCalls: [callRequests[0]], @@ -621,8 +557,17 @@ describe('public_processor', () => { callRequests[2].callContext.sideEffectCounter = 4; const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); + kernelOutput.forPublic!.end.encryptedLogsHash = Fr.ZERO; + kernelOutput.forPublic!.end.unencryptedLogsHash = Fr.ZERO; + kernelOutput.forPublic!.endNonRevertibleData.publicDataUpdateRequests = makeTuple( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PublicDataUpdateRequest.empty, + ); + kernelOutput.forPublic!.end.publicDataUpdateRequests = makeTuple( + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + PublicDataUpdateRequest.empty, + ); - kernelOutput.end.unencryptedLogsHash = Fr.ZERO; addKernelPublicCallStack(kernelOutput, { setupCalls: [callRequests[0]], appLogicCalls: [callRequests[2]], @@ -708,13 +653,13 @@ describe('public_processor', () => { const txEffect = toTxEffect(processed[0]); expect(arrayNonEmptyLength(txEffect.publicDataWrites, PublicDataWrite.isEmpty)).toEqual(3); expect(txEffect.publicDataWrites[0]).toEqual( - new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotA), fr(0x102)), + new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotC), fr(0x201)), ); expect(txEffect.publicDataWrites[1]).toEqual( - new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotB), fr(0x151)), + new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotA), fr(0x102)), ); expect(txEffect.publicDataWrites[2]).toEqual( - new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotC), fr(0x201)), + new PublicDataWrite(computePublicDataTreeLeafSlot(baseContractAddress, contractSlotB), fr(0x151)), ); expect(txEffect.encryptedLogs.getTotalLogCount()).toBe(0); expect(txEffect.unencryptedLogs.getTotalLogCount()).toBe(0); @@ -844,18 +789,17 @@ function addKernelPublicCallStack( ) { // the first two calls are non-revertible // the first is for setup, the second is for teardown - kernelOutput.endNonRevertibleData.publicCallStack = padArrayEnd( + kernelOutput.forPublic!.endNonRevertibleData.publicCallStack = padArrayEnd( // this is a stack, so the first item is the last call // and callRequests is in the order of the calls [calls.teardownCall.toCallRequest(), ...calls.setupCalls.map(c => c.toCallRequest())], CallRequest.empty(), - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, ); - kernelOutput.end.publicCallStack = padArrayEnd( + kernelOutput.forPublic!.end.publicCallStack = padArrayEnd( calls.appLogicCalls.map(c => c.toCallRequest()), CallRequest.empty(), - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, ); - kernelOutput.end.privateCallStack = padArrayEnd([], CallRequest.empty(), MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX); } diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.ts index 14c15d70b9b..0b451883d7e 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.ts @@ -3,14 +3,13 @@ import { type ProcessedTx, type SimulationError, Tx, - getPreviousOutputAndProof, makeEmptyProcessedTx, makeProcessedTx, toTxEffect, validateProcessedTx, } from '@aztec/circuit-types'; import { type TxSequencerProcessingStats } from '@aztec/circuit-types/stats'; -import { type GlobalVariables, type Header } from '@aztec/circuits.js'; +import { type GlobalVariables, type Header, type KernelCircuitPublicInputs } from '@aztec/circuits.js'; import { type ProcessReturnValues } from '@aztec/foundation/abi'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; @@ -93,58 +92,13 @@ export class PublicProcessor { const returns: ProcessReturnValues[] = []; for (const tx of txs) { - let returnValues: ProcessReturnValues = undefined; - let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx( - tx, - this.db, - this.publicExecutor, - this.publicKernel, - this.globalVariables, - this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, - ); - this.log(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`); - let { publicKernelPublicInput, previousProof: proof } = getPreviousOutputAndProof(tx, undefined, undefined); - let revertReason: SimulationError | undefined; - const timer = new Timer(); try { - while (phase) { - const output = await phase.handle(tx, publicKernelPublicInput, proof); - if (phase.phase === PublicKernelPhase.APP_LOGIC) { - returnValues = output.returnValues; - } - publicKernelPublicInput = output.publicKernelOutput; - proof = output.publicKernelProof; - revertReason ??= output.revertReason; - phase = PhaseManagerFactory.phaseFromOutput( - publicKernelPublicInput, - phase, - this.db, - this.publicExecutor, - this.publicKernel, - this.globalVariables, - this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, - ); - } - - const processedTransaction = makeProcessedTx(tx, publicKernelPublicInput, proof, revertReason); - validateProcessedTx(processedTransaction); - - result.push(processedTransaction); + const [processedTx, returnValues] = !tx.hasPublicCalls() + ? [makeProcessedTx(tx, tx.data.toKernelCircuitPublicInputs(), tx.proof)] + : await this.processTxWithPublicCalls(tx); + validateProcessedTx(processedTx); + result.push(processedTx); returns.push(returnValues); - - this.log(`Processed public part of ${tx.data.endNonRevertibleData.newNullifiers[0].value}`, { - eventName: 'tx-sequencer-processing', - duration: timer.ms(), - effectsSize: toTxEffect(processedTransaction).toBuffer().length, - publicDataUpdateRequests: - processedTransaction.data.combinedData.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ?? - 0, - ...tx.getStats(), - } satisfies TxSequencerProcessingStats); } catch (err: any) { const errorMessage = err instanceof Error ? err.message : 'Unknown error'; this.log.warn(`Failed to process tx ${tx.getTxHash()}: ${errorMessage}`); @@ -168,4 +122,62 @@ export class PublicProcessor { const { chainId, version } = this.globalVariables; return makeEmptyProcessedTx(this.historicalHeader, chainId, version); } + + private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, ProcessReturnValues | undefined]> { + let returnValues: ProcessReturnValues = undefined; + let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx( + tx, + this.db, + this.publicExecutor, + this.publicKernel, + this.globalVariables, + this.historicalHeader, + this.publicContractsDB, + this.publicStateDB, + ); + this.log(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`); + let proof = tx.proof; + let publicKernelPublicInput = tx.data.toPublicKernelCircuitPublicInputs(); + let finalKernelOutput: KernelCircuitPublicInputs | undefined; + let revertReason: SimulationError | undefined; + const timer = new Timer(); + while (phase) { + const output = await phase.handle(tx, publicKernelPublicInput, proof); + if (phase.phase === PublicKernelPhase.APP_LOGIC) { + returnValues = output.returnValues; + } + publicKernelPublicInput = output.publicKernelOutput; + finalKernelOutput = output.finalKernelOutput; + proof = output.publicKernelProof; + revertReason ??= output.revertReason; + phase = PhaseManagerFactory.phaseFromOutput( + publicKernelPublicInput, + phase, + this.db, + this.publicExecutor, + this.publicKernel, + this.globalVariables, + this.historicalHeader, + this.publicContractsDB, + this.publicStateDB, + ); + } + + if (!finalKernelOutput) { + throw new Error('Final public kernel was not executed.'); + } + + const processedTx = makeProcessedTx(tx, finalKernelOutput, proof, revertReason); + + this.log(`Processed public part of ${tx.getTxHash()}`, { + eventName: 'tx-sequencer-processing', + duration: timer.ms(), + effectsSize: toTxEffect(processedTx).toBuffer().length, + publicDataUpdateRequests: + processedTx.data.end.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ?? 0, + ...tx.getStats(), + } satisfies TxSequencerProcessingStats); + + return [processedTx, returnValues]; + } } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index f4b77c110b7..1b875fbbcf2 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -9,7 +9,7 @@ import { type ProvingTicket, makeEmptyProcessedTx, makeProcessedTx, - mockTx, + mockTxForRollup, } from '@aztec/circuit-types'; import { AztecAddress, @@ -20,6 +20,7 @@ import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, makeEmptyProof, } from '@aztec/circuits.js'; +import { makeProof } from '@aztec/circuits.js/testing'; import { type P2P, P2PClientState } from '@aztec/p2p'; import { type ContractDataSource } from '@aztec/types/contracts'; import { type MerkleTreeOperations, WorldStateRunningState, type WorldStateSynchronizer } from '@aztec/world-state'; @@ -71,7 +72,11 @@ describe('sequencer', () => { }); publicProcessor = mock({ - process: async txs => [await Promise.all(txs.map(tx => makeProcessedTx(tx))), [], []], + process: async txs => [ + await Promise.all(txs.map(tx => makeProcessedTx(tx, tx.data.toKernelCircuitPublicInputs(), makeProof()))), + [], + [], + ], makeEmptyProcessedTx: () => makeEmptyProcessedTx(Header.empty(), chainId, version), }); @@ -111,10 +116,8 @@ describe('sequencer', () => { }); it('builds a block out of a single tx', async () => { - const tx = mockTx(); + const tx = mockTxForRollup(); tx.data.constants.txContext.chainId = chainId; - tx.data.needsSetup = false; - tx.data.needsTeardown = false; const block = L2Block.random(lastBlockNumber + 1); const proof = makeEmptyProof(); const result: ProvingSuccess = { @@ -147,11 +150,9 @@ describe('sequencer', () => { }); it('builds a block out of several txs rejecting double spends', async () => { - const txs = [mockTx(0x10000), mockTx(0x20000), mockTx(0x30000)]; + const txs = [mockTxForRollup(0x10000), mockTxForRollup(0x20000), mockTxForRollup(0x30000)]; txs.forEach(tx => { tx.data.constants.txContext.chainId = chainId; - tx.data.needsSetup = false; - tx.data.needsTeardown = false; }); const doubleSpendTx = txs[1]; const block = L2Block.random(lastBlockNumber + 1); @@ -173,7 +174,7 @@ describe('sequencer', () => { ); // We make a nullifier from tx1 a part of the nullifier tree, so it gets rejected as double spend - const doubleSpendNullifier = doubleSpendTx.data.end.newNullifiers[0].value.toBuffer(); + const doubleSpendNullifier = doubleSpendTx.data.forRollup!.end.newNullifiers[0].value.toBuffer(); merkleTreeOps.findLeafIndex.mockImplementation((treeId: MerkleTreeId, value: any) => { return Promise.resolve( treeId === MerkleTreeId.NULLIFIER_TREE && value.equals(doubleSpendNullifier) ? 1n : undefined, @@ -196,11 +197,9 @@ describe('sequencer', () => { }); it('builds a block out of several txs rejecting incorrect chain ids', async () => { - const txs = [mockTx(0x10000), mockTx(0x20000), mockTx(0x30000)]; + const txs = [mockTxForRollup(0x10000), mockTxForRollup(0x20000), mockTxForRollup(0x30000)]; txs.forEach(tx => { tx.data.constants.txContext.chainId = chainId; - tx.data.needsSetup = false; - tx.data.needsTeardown = false; }); const invalidChainTx = txs[1]; const block = L2Block.random(lastBlockNumber + 1); @@ -240,7 +239,7 @@ describe('sequencer', () => { }); it('aborts building a block if the chain moves underneath it', async () => { - const tx = mockTx(); + const tx = mockTxForRollup(); tx.data.constants.txContext.chainId = chainId; const block = L2Block.random(lastBlockNumber + 1); const proof = makeEmptyProof(); diff --git a/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts index aa26bad1583..9253ae06055 100644 --- a/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts @@ -1,11 +1,5 @@ import { mockTx } from '@aztec/circuit-types'; -import { - CallRequest, - GlobalVariables, - Header, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, -} from '@aztec/circuits.js'; +import { CallRequest, GlobalVariables, Header, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX } from '@aztec/circuits.js'; import { makeTuple } from '@aztec/foundation/array'; import { type PublicExecutor } from '@aztec/simulator'; import { type MerkleTreeOperations, type TreeInfo } from '@aztec/world-state'; @@ -56,9 +50,9 @@ describe('setup_phase_manager', () => { it('does not extract non-revertible calls when none exist', function () { const tx = mockTx(); - tx.data.end.publicCallStack = makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty); - tx.data.endNonRevertibleData.publicCallStack = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + tx.data.forPublic!.end.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty); + tx.data.forPublic!.endNonRevertibleData.publicCallStack = makeTuple( + MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty, ); const enqueuedNonRevertibleCalls = phaseManager.extractEnqueuedPublicCalls(tx); diff --git a/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts index ff1ca8c7de4..e41a05b818b 100644 --- a/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/tail_phase_manager.ts @@ -2,9 +2,15 @@ import { type Tx } from '@aztec/circuit-types'; import { type GlobalVariables, type Header, + type KernelCircuitPublicInputs, + type MAX_NEW_NOTE_HASHES_PER_TX, type Proof, type PublicKernelCircuitPublicInputs, + PublicKernelTailCircuitPrivateInputs, + type SideEffect, + makeEmptyProof, } from '@aztec/circuits.js'; +import { type Tuple } from '@aztec/foundation/serialize'; import { type PublicExecutor, type PublicStateDB } from '@aztec/simulator'; import { type MerkleTreeOperations } from '@aztec/world-state'; @@ -28,7 +34,7 @@ export class TailPhaseManager extends AbstractPhaseManager { async handle(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs, previousPublicKernelProof: Proof) { this.log(`Processing tx ${tx.getTxHash()}`); - const [publicKernelOutput, publicKernelProof] = await this.runKernelCircuit( + const [finalKernelOutput, publicKernelProof] = await this.runTailKernelCircuit( previousPublicKernelOutput, previousPublicKernelProof, ).catch( @@ -42,6 +48,57 @@ export class TailPhaseManager extends AbstractPhaseManager { // commit the state updates from this transaction await this.publicStateDB.commit(); - return { publicKernelOutput, publicKernelProof, revertReason: undefined, returnValues: undefined }; + return { + publicKernelOutput: previousPublicKernelOutput, + finalKernelOutput, + publicKernelProof, + revertReason: undefined, + returnValues: undefined, + }; + } + + private async runTailKernelCircuit( + previousOutput: PublicKernelCircuitPublicInputs, + previousProof: Proof, + ): Promise<[KernelCircuitPublicInputs, Proof]> { + const output = await this.simulate(previousOutput, previousProof); + // Temporary hack. Should sort them in the tail circuit. + // TODO(#757): Enforce proper ordering of public state actions + output.end.newNoteHashes = this.sortNoteHashes(output.end.newNoteHashes); + return [output, makeEmptyProof()]; + } + + private async simulate( + previousOutput: PublicKernelCircuitPublicInputs, + previousProof: Proof, + ): Promise { + const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); + + const { validationRequests, endNonRevertibleData, end } = previousOutput; + const nullifierReadRequestHints = await this.hintsBuilder.getNullifierReadRequestHints( + validationRequests.nullifierReadRequests, + endNonRevertibleData.newNullifiers, + end.newNullifiers, + ); + const nullifierNonExistentReadRequestHints = await this.hintsBuilder.getNullifierNonExistentReadRequestHints( + validationRequests.nullifierNonExistentReadRequests, + endNonRevertibleData.newNullifiers, + end.newNullifiers, + ); + const inputs = new PublicKernelTailCircuitPrivateInputs( + previousKernel, + nullifierReadRequestHints, + nullifierNonExistentReadRequestHints, + ); + return this.publicKernel.publicKernelCircuitTail(inputs); + } + + private sortNoteHashes(noteHashes: Tuple): Tuple { + return noteHashes.sort((n0, n1) => { + if (n0.isEmpty()) { + return 1; + } + return Number(n0.counter.toBigInt() - n1.counter.toBigInt()); + }); } } diff --git a/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts b/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts index 8336bd31619..ee8bd7c4212 100644 --- a/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts @@ -1,19 +1,15 @@ -import { mockTx as baseMockTx } from '@aztec/circuit-types'; +import { mockTx, mockTxForRollup } from '@aztec/circuit-types'; import { type AztecAddress, CallContext, - CallRequest, EthAddress, Fr, FunctionData, FunctionSelector, type GlobalVariables, - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, PublicCallRequest, } from '@aztec/circuits.js'; import { makeAztecAddress, makeGlobalVariables } from '@aztec/circuits.js/testing'; -import { makeTuple } from '@aztec/foundation/array'; import { pedersenHash } from '@aztec/foundation/crypto'; import { getCanonicalGasTokenAddress } from '@aztec/protocol-contracts/gas-token'; import { type ContractDataSource } from '@aztec/types/contracts'; @@ -82,26 +78,26 @@ describe('TxValidator', () => { describe('inspects tx nullifiers', () => { it('rejects duplicates in non revertible data', async () => { const badTx = nonFeePayingTx(); - badTx.data.endNonRevertibleData.newNullifiers[1] = badTx.data.endNonRevertibleData.newNullifiers[0]; + badTx.data.forRollup!.end.newNullifiers[1] = badTx.data.forRollup!.end.newNullifiers[0]; await expect(validator.validateTxs([badTx])).resolves.toEqual([[], [badTx]]); }); it('rejects duplicates in revertible data', async () => { const badTx = nonFeePayingTx(); - badTx.data.end.newNullifiers[1] = badTx.data.end.newNullifiers[0]; + badTx.data.forRollup!.end.newNullifiers[1] = badTx.data.forRollup!.end.newNullifiers[0]; await expect(validator.validateTxs([badTx])).resolves.toEqual([[], [badTx]]); }); it('rejects duplicates across phases', async () => { - const badTx = nonFeePayingTx(); - badTx.data.end.newNullifiers[0] = badTx.data.endNonRevertibleData.newNullifiers[0]; + const badTx = nativeFeePayingTx(makeAztecAddress()); + badTx.data.forPublic!.end.newNullifiers[0] = badTx.data.forPublic!.endNonRevertibleData.newNullifiers[0]; await expect(validator.validateTxs([badTx])).resolves.toEqual([[], [badTx]]); }); it('rejects duplicates across txs', async () => { const firstTx = nonFeePayingTx(); const secondTx = nonFeePayingTx(); - secondTx.data.end.newNullifiers[0] = firstTx.data.end.newNullifiers[0]; + secondTx.data.forRollup!.end.newNullifiers[0] = firstTx.data.forRollup!.end.newNullifiers[0]; await expect(validator.validateTxs([firstTx, secondTx])).resolves.toEqual([[firstTx], [secondTx]]); }); @@ -252,33 +248,24 @@ describe('TxValidator', () => { // get unique txs that are also stable across test runs let txSeed = 1; - /** Creates a mock tx for the current chain */ - function nonFeePayingTx() { - const tx = baseMockTx(txSeed++, false); + function mockValidTx(forRollup = true, numberOfNonRevertiblePublicCallRequests = 0) { + const tx = forRollup + ? mockTxForRollup(txSeed++) + : mockTx(txSeed++, { numberOfNonRevertiblePublicCallRequests, numberOfRevertiblePublicCallRequests: 0 }); tx.data.constants.txContext.chainId = globalVariables.chainId; tx.data.constants.txContext.version = globalVariables.version; - - // clear public call stacks as it's mocked data but the arrays are not correlated - tx.data.endNonRevertibleData.publicCallStack = makeTuple( - MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, - CallRequest.empty, - ); - tx.data.end.publicCallStack = makeTuple(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty); - // use splice because it's a readonly property - tx.enqueuedPublicFunctionCalls.splice(0, tx.enqueuedPublicFunctionCalls.length); - - // clear these flags because the call stack is empty now - tx.data.needsSetup = false; - tx.data.needsAppLogic = false; - tx.data.needsTeardown = false; - return tx; } + /** Creates a mock tx for the current chain */ + function nonFeePayingTx() { + return mockValidTx(); + } + /** Create a tx that pays for its cost natively */ function nativeFeePayingTx(feePayer: AztecAddress) { - const tx = nonFeePayingTx(); + const tx = mockValidTx(false, 1); const gasTokenAddress = getCanonicalGasTokenAddress(gasPortalAddress); const signature = FunctionSelector.random(); @@ -290,16 +277,15 @@ describe('TxValidator', () => { [], ); - tx.data.endNonRevertibleData.publicCallStack[0] = feeExecutionFn.toCallRequest(); + tx.data.forPublic!.endNonRevertibleData.publicCallStack[0] = feeExecutionFn.toCallRequest(); tx.enqueuedPublicFunctionCalls[0] = feeExecutionFn; - tx.data.needsTeardown = true; return tx; } /** Create a tx that uses fee abstraction to pay for its cost */ function fxFeePayingTx(feePaymentContract: AztecAddress) { - const tx = nonFeePayingTx(); + const tx = mockValidTx(false, 2); // the contract calls itself. Both functions are internal const feeSetupSelector = FunctionSelector.random(); @@ -310,9 +296,8 @@ describe('TxValidator', () => { CallContext.empty(), [], ); - tx.data.endNonRevertibleData.publicCallStack[0] = feeSetupFn.toCallRequest(); + tx.data.forPublic!.endNonRevertibleData.publicCallStack[0] = feeSetupFn.toCallRequest(); tx.enqueuedPublicFunctionCalls[0] = feeSetupFn; - tx.data.needsSetup = true; const feeExecutionSelector = FunctionSelector.random(); const feeExecutionFn = new PublicCallRequest( @@ -322,9 +307,8 @@ describe('TxValidator', () => { CallContext.empty(), [], ); - tx.data.endNonRevertibleData.publicCallStack[1] = feeExecutionFn.toCallRequest(); + tx.data.forPublic!.endNonRevertibleData.publicCallStack[1] = feeExecutionFn.toCallRequest(); tx.enqueuedPublicFunctionCalls[1] = feeExecutionFn; - tx.data.needsTeardown = true; return tx; } @@ -333,8 +317,8 @@ describe('TxValidator', () => { function maxBlockNumberTx(maxBlockNumber: Fr) { const tx = nonFeePayingTx(); - tx.data.rollupValidationRequests.maxBlockNumber.isSome = true; - tx.data.rollupValidationRequests.maxBlockNumber.value = maxBlockNumber; + tx.data.forRollup!.rollupValidationRequests.maxBlockNumber.isSome = true; + tx.data.forRollup!.rollupValidationRequests.maxBlockNumber.value = maxBlockNumber; return tx; } diff --git a/yarn-project/sequencer-client/src/sequencer/tx_validator.ts b/yarn-project/sequencer-client/src/sequencer/tx_validator.ts index 5460aab82e3..457aedf2d34 100644 --- a/yarn-project/sequencer-client/src/sequencer/tx_validator.ts +++ b/yarn-project/sequencer-client/src/sequencer/tx_validator.ts @@ -138,9 +138,7 @@ export class TxValidator { * @returns Whether this is a problematic double spend that the L1 contract would reject. */ async #validateNullifiers(tx: Tx | ProcessedTx, thisBlockNullifiers: Set): Promise { - const newNullifiers = [...tx.data.endNonRevertibleData.newNullifiers, ...tx.data.end.newNullifiers] - .filter(x => !x.isEmpty()) - .map(x => x.value.toBigInt()); + const newNullifiers = tx.data.getNonEmptyNullifiers().map(x => x.value.toBigInt()); // Ditch this tx if it has repeated nullifiers const uniqueNullifiers = new Set(newNullifiers); @@ -172,7 +170,7 @@ export class TxValidator { } async #validateGasBalance(tx: Tx): Promise { - if (!tx.data.needsTeardown) { + if (!tx.data.forPublic || !tx.data.forPublic.needsTeardown) { return VALID_TX; } @@ -200,7 +198,11 @@ export class TxValidator { } #validateMaxBlockNumber(tx: Tx | ProcessedTx): TxValidationStatus { - const maxBlockNumber = tx.data.rollupValidationRequests.maxBlockNumber; + const target = + tx instanceof Tx + ? tx.data.forRollup?.rollupValidationRequests || tx.data.forPublic!.validationRequests.forRollup + : tx.data.rollupValidationRequests; + const maxBlockNumber = target.maxBlockNumber; if (maxBlockNumber.isSome && maxBlockNumber.value < this.#globalVariables.blockNumber) { this.#log.warn(`Rejecting tx ${Tx.getHash(tx)} for low max block number`); @@ -211,7 +213,7 @@ export class TxValidator { } async #validateFee(tx: Tx): Promise { - if (!tx.data.needsTeardown) { + if (!tx.data.forPublic || !tx.data.forPublic.needsTeardown) { // TODO check if fees are mandatory and reject this tx this.#log.debug(`Tx ${Tx.getHash(tx)} doesn't pay for gas`); return VALID_TX; diff --git a/yarn-project/sequencer-client/src/sequencer/utils.test.ts b/yarn-project/sequencer-client/src/sequencer/utils.test.ts index d080b920600..7186ed626eb 100644 --- a/yarn-project/sequencer-client/src/sequencer/utils.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/utils.test.ts @@ -10,16 +10,16 @@ describe('sequencer utils', () => { // mockTx creates a Tx with side effect counts of all 0 expect(lastSideEffectCounter(tx)).toBe(0); - tx.data.endNonRevertibleData.newNoteHashes.at(-1)!.counter = new Fr(8); + tx.data.forPublic!.endNonRevertibleData.newNoteHashes.at(-1)!.counter = new Fr(8); expect(lastSideEffectCounter(tx)).toBe(8); - tx.data.endNonRevertibleData.publicCallStack.at(-1)!.startSideEffectCounter = new Fr(9); + tx.data.forPublic!.endNonRevertibleData.publicCallStack.at(-1)!.startSideEffectCounter = new Fr(9); expect(lastSideEffectCounter(tx)).toBe(9); - tx.data.end.newNoteHashes.at(-1)!.counter = new Fr(10); + tx.data.forPublic!.end.newNoteHashes.at(-1)!.counter = new Fr(10); expect(lastSideEffectCounter(tx)).toBe(10); - tx.data.end.newNullifiers.at(-1)!.counter = new Fr(11); + tx.data.forPublic!.end.newNullifiers.at(-1)!.counter = new Fr(11); expect(lastSideEffectCounter(tx)).toBe(11); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/utils.ts b/yarn-project/sequencer-client/src/sequencer/utils.ts index 8dbc45241f8..8918c39030b 100644 --- a/yarn-project/sequencer-client/src/sequencer/utils.ts +++ b/yarn-project/sequencer-client/src/sequencer/utils.ts @@ -7,13 +7,14 @@ import { CallRequest } from '@aztec/circuits.js'; * @returns The highest side effect counter in the transaction so far */ export function lastSideEffectCounter(tx: Tx): number { + const data = tx.data.forPublic!; const sideEffectCounters = [ - ...tx.data.endNonRevertibleData.newNoteHashes, - ...tx.data.endNonRevertibleData.newNullifiers, - ...tx.data.endNonRevertibleData.publicCallStack, - ...tx.data.end.newNoteHashes, - ...tx.data.end.newNullifiers, - ...tx.data.end.publicCallStack, + ...data.endNonRevertibleData.newNoteHashes, + ...data.endNonRevertibleData.newNullifiers, + ...data.endNonRevertibleData.publicCallStack, + ...data.end.newNoteHashes, + ...data.end.newNullifiers, + ...data.end.publicCallStack, ]; let max = 0; diff --git a/yarn-project/sequencer-client/src/simulator/index.ts b/yarn-project/sequencer-client/src/simulator/index.ts index 0991a64755f..05bf3182f0e 100644 --- a/yarn-project/sequencer-client/src/simulator/index.ts +++ b/yarn-project/sequencer-client/src/simulator/index.ts @@ -1,4 +1,5 @@ import { + type KernelCircuitPublicInputs, type PublicKernelCircuitPrivateInputs, type PublicKernelCircuitPublicInputs, type PublicKernelTailCircuitPrivateInputs, @@ -31,5 +32,5 @@ export interface PublicKernelCircuitSimulator { * @param inputs - Inputs to the circuit. * @returns The public inputs as outputs of the simulation. */ - publicKernelCircuitTail(inputs: PublicKernelTailCircuitPrivateInputs): Promise; + publicKernelCircuitTail(inputs: PublicKernelTailCircuitPrivateInputs): Promise; } diff --git a/yarn-project/sequencer-client/src/simulator/public_kernel.ts b/yarn-project/sequencer-client/src/simulator/public_kernel.ts index 3cf576f2981..04700d7c68c 100644 --- a/yarn-project/sequencer-client/src/simulator/public_kernel.ts +++ b/yarn-project/sequencer-client/src/simulator/public_kernel.ts @@ -1,5 +1,6 @@ import { type CircuitSimulationStats } from '@aztec/circuit-types/stats'; import { + type KernelCircuitPublicInputs, type PublicKernelCircuitPrivateInputs, type PublicKernelCircuitPublicInputs, type PublicKernelTailCircuitPrivateInputs, @@ -120,7 +121,7 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu */ public async publicKernelCircuitTail( input: PublicKernelTailCircuitPrivateInputs, - ): Promise { + ): Promise { const inputWitness = convertPublicTailInputsToWitnessMap(input); const [duration, witness] = await elapsed(() => this.wasmSimulator.simulateCircuit(inputWitness, PublicKernelTailArtifact),