From 9e0977261aea723d6ea68750788f29a40730c404 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Mon, 19 Feb 2024 16:26:50 +0000 Subject: [PATCH 01/10] fix(dsl): Add full recursive verification test (#4658) This PR adds a test that does a full recursive verification similar to `TestFullRecursiveComposition` under `recursion_constraint.test.cpp` but using Noir. A couple bugs fixes were done to enable the new `double_verify_nested_proof` test: - We have an assert in the recursion constraint that checks `num_public_inputs == RecursionConstraint::AGGREGATION_OBJECT_SIZE` when generating the dummy transcript for when we do not have valid witness assignments. If we want to recursively verify a recursive proof that itself has extra public inputs this assertion makes that impossible (in fact the cpp test does not use any public inputs for `TestFullRecursiveComposition` and this may be why this assertion wasn't hit earlier). - After moving to a definition of a proof as separate from its public inputs in (https://github.com/AztecProtocol/aztec-packages/pull/3528) we were missing the accurate copy constraints in the case of no valid witness assignment. In the case of a nested proof the public inputs will contain an aggregation object for which we expect two accurate G1 points. Otherwise, even with the removed assertion above we will always hit a "trying to invert 0" error when working without valid witness assignments. --- barretenberg/acir_tests/README.md | 10 +++--- .../dsl/acir_format/acir_format.cpp | 14 +++++--- .../dsl/acir_format/recursion_constraint.cpp | 33 ++++++++++++++----- .../double_verify_nested_proof/Nargo.toml | 7 ++++ .../double_verify_nested_proof/Prover.toml | 5 +++ .../double_verify_nested_proof/src/main.nr | 28 ++++++++++++++++ .../double_verify_proof/src/main.nr | 3 +- 7 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 noir/test_programs/execution_success/double_verify_nested_proof/Nargo.toml create mode 100644 noir/test_programs/execution_success/double_verify_nested_proof/Prover.toml create mode 100644 noir/test_programs/execution_success/double_verify_nested_proof/src/main.nr diff --git a/barretenberg/acir_tests/README.md b/barretenberg/acir_tests/README.md index 8bdf7fa65857..e356cc0074d4 100644 --- a/barretenberg/acir_tests/README.md +++ b/barretenberg/acir_tests/README.md @@ -43,18 +43,20 @@ The `all_cmds` flow tests all the supported commands on the binary. Slower, but $ FLOW=all_cmds ./run_acir_tests.sh 1_mul ``` -## Regenerating witness for `double_verify_proof` +## Regenerating witness for `double_verify_proof` and `double_verify_nested_proof` `double_verify_proof` has inputs that are proof system specific such as the circuit verification key and the proofs themselves which are being recursively verified. Certain proof system changes can sometimes lead to the key or inner proofs now being invalid. This means we have to generate the proof specific inputs using our backend and pass it back into `double_verify_proof` to regenerate the accurate witness. The following is a temporary solution to manually regenerate the inputs for `double_verify_proof` on a specific Noir branch. -First find `acir_tests/gen_inner_proof_inputs.sh`. Change the $BRANCH env var to your working branch and $PROOF_NAME to your first input you want to recursively verify. The script is going to generate the proof system specific verification key output and proof for the `assert_statement` test. +First find `acir_tests/gen_inner_proof_inputs.sh`. Change the $BRANCH env var to your working branch and $PROOF_NAME to your first input you want to recursively verify. The script is going to generate the proof system specific verification key output and proof for the `assert_statement_recursive` test. To run: ``` ./gen_inner_proof_inputs.sh ``` -To generate a new input you can run the script again. To generate a new file under `assert_statement/proofs/` be sure to change the $PROOF_NAME inside of the script. +To generate a new input you can run the script again. To generate a new file under `assert_statement_recursive/proofs/` be sure to change the $PROOF_NAME inside of the script. -You can then copy these inputs over to your working branch in Noir and regenerate the witness for `double_verify_proof`. You can then change the branch in `run_acir_tests.sh` to this Noir working branch as well and `double_verify_proof` should pass. \ No newline at end of file +You can then copy these inputs over to your working branch in Noir and regenerate the witness for `double_verify_proof`. You can then change the branch in `run_acir_tests.sh` to this Noir working branch as well and `double_verify_proof` should pass. + +The same process should then be repeated, but now `double_verify_proof` will be the circuit for which we will be generating recursive inputs using `gen_inner_proof_inputs.sh`. The recursive artifacts should then supplied as inputs to `double_verify_nested_proof`. \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 47ca2e460a36..fd2f23fe0f85 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -113,7 +113,7 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo // TODO(https://github.com/AztecProtocol/barretenberg/issues/817): disable these for UGH for now since we're not yet // dealing with proper recursion if constexpr (IsGoblinBuilder) { - if (constraint_system.recursion_constraints.size() > 0) { + if (!constraint_system.recursion_constraints.empty()) { info("WARNING: this circuit contains recursion_constraints!"); } } else { @@ -148,8 +148,15 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo // If the proof has public inputs attached to it, we should handle setting the nested aggregation object if (constraint.proof.size() > proof_size_no_pub_inputs) { // The public inputs attached to a proof should match the aggregation object in size - ASSERT(constraint.proof.size() - proof_size_no_pub_inputs == - RecursionConstraint::AGGREGATION_OBJECT_SIZE); + if (constraint.proof.size() - proof_size_no_pub_inputs != + RecursionConstraint::AGGREGATION_OBJECT_SIZE) { + auto error_string = format( + "Public inputs are always stripped from proofs unless we have a recursive proof.\n" + "Thus, public inputs attached to a proof must match the recursive aggregation object in size " + "which is {}\n", + RecursionConstraint::AGGREGATION_OBJECT_SIZE); + throw_or_abort(error_string); + } for (size_t i = 0; i < RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++i) { // Set the nested aggregation object indices to the current size of the public inputs // This way we know that the nested aggregation object indices will always be the last @@ -165,7 +172,6 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo constraint.proof.begin() + static_cast(RecursionConstraint::AGGREGATION_OBJECT_SIZE)); } - current_output_aggregation_object = create_recursion_constraints(builder, constraint, current_input_aggregation_object, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp index 8b154172a633..b457f9c5552c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.cpp @@ -53,20 +53,32 @@ std::array create_recurs std::vector dummy_proof = export_dummy_transcript_in_recursion_format(manifest, inner_proof_contains_recursive_proof); - // Remove the public inputs from the dummy proof - dummy_proof.erase(dummy_proof.begin(), - dummy_proof.begin() + static_cast(input.public_inputs.size())); - for (size_t i = 0; i < input.proof.size(); ++i) { - const auto proof_field_idx = input.proof[i]; + for (size_t i = 0; i < input.public_inputs.size(); ++i) { + const auto public_input_idx = input.public_inputs[i]; // if we do NOT have a witness assignment (i.e. are just building the proving/verification keys), - // we add our dummy proof values as Builder variables. + // we add our dummy public input values as Builder variables. // if we DO have a valid witness assignment, we use the real witness assignment - bb::fr dummy_field = has_valid_witness_assignments ? builder.get_variable(proof_field_idx) : dummy_proof[i]; + bb::fr dummy_field = + has_valid_witness_assignments ? builder.get_variable(public_input_idx) : dummy_proof[i]; // Create a copy constraint between our dummy field and the witness index provided by RecursionConstraint. // This will make the RecursionConstraint idx equal to `dummy_field`. // In the case of a valid witness assignment, this does nothing (as dummy_field = real value) // In the case of no valid witness assignment, this makes sure that the RecursionConstraint witness indices // will not trigger basic errors (check inputs are on-curve, check we are not inverting 0) + // + // Failing to do these copy constraints on public inputs will trigger these basic errors + // in the case of a nested proof, as an aggregation object is expected to be two G1 points even + // in the case of no valid witness assignments. + builder.assert_equal(builder.add_variable(dummy_field), public_input_idx); + } + // Remove the public inputs from the dummy proof + // The proof supplied to the recursion constraint will already be stripped of public inputs + // while the barretenberg API works with public inputs prepended to the proof. + dummy_proof.erase(dummy_proof.begin(), + dummy_proof.begin() + static_cast(input.public_inputs.size())); + for (size_t i = 0; i < input.proof.size(); ++i) { + const auto proof_field_idx = input.proof[i]; + bb::fr dummy_field = has_valid_witness_assignments ? builder.get_variable(proof_field_idx) : dummy_proof[i]; builder.assert_equal(builder.add_variable(dummy_field), proof_field_idx); } for (size_t i = 0; i < input.key.size(); ++i) { @@ -329,7 +341,12 @@ std::vector export_dummy_transcript_in_recursion_format(const transcript // is composed of two valid G1 points on the curve. Without this conditional we will get a // runtime error that we are attempting to invert 0. if (contains_recursive_proof) { - ASSERT(num_public_inputs == RecursionConstraint::AGGREGATION_OBJECT_SIZE); + // When setting up the ACIR we emplace back the nested aggregation object + // fetched from the proof onto the public inputs. Thus, we can expect the + // nested aggregation object to always be at the end of the public inputs. + for (size_t k = 0; k < num_public_inputs - RecursionConstraint::AGGREGATION_OBJECT_SIZE; ++k) { + fields.emplace_back(0); + } for (size_t k = 0; k < RecursionConstraint::NUM_AGGREGATION_ELEMENTS; ++k) { auto scalar = bb::fr::random_element(); const auto group_element = bb::g1::affine_element(bb::g1::one * scalar); diff --git a/noir/test_programs/execution_success/double_verify_nested_proof/Nargo.toml b/noir/test_programs/execution_success/double_verify_nested_proof/Nargo.toml new file mode 100644 index 000000000000..3ead649c8793 --- /dev/null +++ b/noir/test_programs/execution_success/double_verify_nested_proof/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "double_verify_nested_proof" +type = "bin" +authors = [""] +compiler_version = ">=0.24.0" + +[dependencies] \ No newline at end of file diff --git a/noir/test_programs/execution_success/double_verify_nested_proof/Prover.toml b/noir/test_programs/execution_success/double_verify_nested_proof/Prover.toml new file mode 100644 index 000000000000..2a2b4b335861 --- /dev/null +++ b/noir/test_programs/execution_success/double_verify_nested_proof/Prover.toml @@ -0,0 +1,5 @@ +key_hash = "0x13fd5b632ce9e9d12c9ac56c150ed09413df3edf40d1b7ab8ced9f262ec61b29" +proof_b = ["0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf","0x00000000000000000000000000000000000000000000000b75c020998797da78","0x0000000000000000000000000000000000000000000000005a107acb64952eca","0x000000000000000000000000000000000000000000000000000031e97a575e9d","0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4","0x00000000000000000000000000000000000000000000000c410db10a01750aeb","0x00000000000000000000000000000000000000000000000d722669117f9758a4","0x000000000000000000000000000000000000000000000000000178cbf4206471","0x000000000000000000000000000000000000000000000000e91b8a11e7842c38","0x000000000000000000000000000000000000000000000007fd51009034b3357f","0x000000000000000000000000000000000000000000000009889939f81e9c7402","0x0000000000000000000000000000000000000000000000000000f94656a2ca48","0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f","0x0000000000000000000000000000000000000000000000093fe27776f50224bd","0x000000000000000000000000000000000000000000000004a0c80c0da527a081","0x0000000000000000000000000000000000000000000000000001b52c2020d746","0x0000000000000000000000000000004bdfb9b586a637ceebd99ff26dcd3af427","0x0000000000000000000000000000000000265c2a5caf8e033e32d192807f5353","0x000000000000000000000000000000c0ab1db6ea40ac087cdc82c4a61ab00c86","0x0000000000000000000000000000000000010800ea8010f4bd3dd432d1cc11ed","0x000000000000000000000000000000eb3db3c41e3e636d686fd2903b1b913a01","0x000000000000000000000000000000000009bbab6b90377114c9e33d2a302226","0x000000000000000000000000000000758726e60ef4b211cf1c965fe08293365b","0x0000000000000000000000000000000000290ec193bc7f4f9006b9cea136bff5","0x0000000000000000000000000000005a2a389cd1702b3aa37f30ed974147d343","0x00000000000000000000000000000000001d83087d6efe0db3f482730b8d5e32","0x000000000000000000000000000000ad015051ed84c11d061e63eddbc3c0417a","0x0000000000000000000000000000000000155011c8b0167ff694740c48d67683","0x00000000000000000000000000000010c638a3b13dba3e77be3f10a3d096927c","0x00000000000000000000000000000000002372b9853214a1f76e5636dc26f146","0x00000000000000000000000000000005d9ca201c07bd4216689677feb9227715","0x000000000000000000000000000000000001dcf09921797dffb8eb21abef187b","0x00000000000000000000000000000070af16c9644b777dcf84d69e820e1ed895","0x00000000000000000000000000000000002d5e8f7eb7a4e20964dd94dc141534","0x0000000000000000000000000000003636871dbe453b366c3351be6e84144683","0x0000000000000000000000000000000000206464e290e4f4764365038ac77edf","0x000000000000000000000000000000175c20da35cc833dd542af57de9b62a2da","0x00000000000000000000000000000000001d2e31de3715e05ff6278f88e5a0db","0x000000000000000000000000000000328610e4eabb48be78d3c75f7c159205c5","0x000000000000000000000000000000000026720634b8076fee0a17b358b04653","0x0000000000000000000000000000000e5f48906892ffbff91e8b58ceabba0949","0x000000000000000000000000000000000013c349df687926ccb712622fc72a36","0x000000000000000000000000000000a4b8c9046c7e7e4cc19bbf9a367668eac7","0x00000000000000000000000000000000002a81128e53672c33bb0dae0ff18f41","0x000000000000000000000000000000edb79df57c4a2303ed1e5c2d7ed1e1bdaf","0x000000000000000000000000000000000018d3cea4ce204eafd70c0ded024650","0x000000000000000000000000000000e5f82856854fe0a2d587f6a9ae8555f321","0x0000000000000000000000000000000000235480ec2adc05f04261054345e568","0x00000000000000000000000000000083607465f60b70b092f606853f4d9e96eb","0x000000000000000000000000000000000006569e3a3174bcb71efe46f7fb7e0f","0x000000000000000000000000000000cb4d5fc546f20f63e3b7cf60341956f36f","0x00000000000000000000000000000000000e14b1932630bf606a637eabb7c80f","0x000000000000000000000000000000786f31c2e082aa7e398e6323bb48a27472","0x00000000000000000000000000000000002dd72746f5e5a4a438def122ae6bba","0x000000000000000000000000000000d007be60a28b744e49279fab277c8bd623","0x00000000000000000000000000000000000e52e2b940b9cd8d001209cc40f7c8","0x000000000000000000000000000000dd4357e24a1bda0b5a6c5eee657cfe9091","0x0000000000000000000000000000000000047bb24b20feb0b66089a96671c901","0x0000000000000000000000000000003fe7f42f34e3360ef0fa8bd9c17e6190a3","0x0000000000000000000000000000000000161d17a3848118e91b435b553d34e9","0x216fa2905e105e0c767687f9b5e81c2e4ce03abe2993ac8dcd9e8d89e088966f","0x1288ba942d41c7f4b048e125454253bc7d7ffc0875365c0b8f75a2bb3ea90b42","0x1ad706f84cffcc62fa030f1bc57cb478a687aa74c1019beeda9bab4e40d35373","0x03050c8016b8041a557a46840ab4166a9c2531eb7c3985a447996a334e0caf5f","0x2b3c485da75bdaef8cec120bd08bc21e3ff717740114d13d3811006215a1fb24","0x008fc8c76c4d8cbba8653bf0919c047d379941be60c7afc7250bc6bfc5f29ad5","0x1993ae2a0da54e5e643533fdefbf54a0df21115b2ee79a63a7f477c2c9c4a5d5","0x22520fa7fde2d72b9776c07c9b897ef7ce48f8a7937ec0cacb01d3e23f72b78a","0x259b7b9c1dbfe88d613102f0e8548f0c770a1c83876b26a5cb4b6790740cb487","0x043006102e519b8011d089f51811337fbdedc856a73842f7c8197be176b08d38","0x2222bd509df909ce38b67b3172b24c8ce1e0e1dd0d811f4fae6957e3418415ac","0x1b1204474652fa85979f0274145680718bed80466f4c91ad58f37df1b4fe2395","0x08d57251b42c0697535617ae239d7f3ef9d1558c1bb71fa01c68e7b5fd266139","0x04ca7f21f1d0ba50ecf00c615d18bf8f7291bb04f513cbef78fb6d03ed9b0cb2","0x070ae1119c80846863a4cd971e535ff87fe34473eb5730b14e5b30212b7b78a1","0x1128027ded5032cc265c96ff81d76e2ce06420702fd4e5bc4e24fda695961651","0x1ef7a9e5885b934eee2b44335157309de2f60519e50a8471e5e24495dff2a9fe","0x2d0dad89e5633da796c0c897804575879bc5dc7ad3805b44260943101ac9609e","0x287edcbd60e9d636ba1cd1c9ff3ec2b71b694112c65876525f5e2f8209cd747f","0x24b1157a1cb5bdbd2829de066b8c5573584f9b8638bf9bad476a1fe1172da4b9","0x1f9825731638cd1c43f7cf035b808a1704f122453318cb88fe3b1164f034e170","0x07003a6552f3a6ab1ad3e0717be0af049767b554ff88986c4e48224632523405","0x288002c2ff29874077b2c216a35cb61ecc97d12750a3a86574d50acd42607095","0x0a12fc37918ce7dcbd0d354a05bdbb409a8e4530d86f3d8ce07231240590f65c","0x2ec631b05fc693b07286eecf6b6ac1aef0d073cdced8e050244ec7cf4e8f6e42","0x107bc98da225efe7749d51b9966c3edd6c245f2e5cf183a924ba982817e4525a","0x2ca603f77ea0ca42b6f38cd43bc3cc09442906373a2f197fdc976533066ac343","0x138ace5653809375aa9d95240fa9b6508860a471aed70bcc8b7dd52ae34809f3","0x21e1eb924951881c3d0ce5657d2e26a3e5150ce8f49c9e4d0476c5fdf1e43a54","0x2e2daec93f5e94f6784ce569883cf285da12244b38fb001b94bfb99bb4de060c","0x186a8d30c973bef6286115865a690a2528adbeea8376e5221fffeb6a135d9904","0x1e0d9d90628be31ebc16ef1d85d5f9e6fb8cb57e6a74e576f958cf21db45042e","0x124ceb5e1d9da6d0fe163e961643bb0423c926ef4e0c583eaba9e32d99ec6c7c","0x2db34cc38a50bfea50750830710c13b4d80f4ec0e8df8f186047ee36f338eeeb","0x0b174aa403b42235d5bdde8e9f5bb6c52ae62fec2884334cbe3e53418bd2463d","0x1571ebd9c3854c2f63418f206c6937495450ab9238a238b9c63fbf5867378c5b","0x24f92d1ab27e5810e5b7f4b31254526822f866602922258135c5eb5a2b21ca04","0x20cc7f5ba8df67d9c95642e2662654eb2305c6a280ce1747aec88a581ee50647","0x24112b99f63bbda7487709396dff22aae89ae809263021b65503ff7f809c7e38","0x06805c80f64efd1fa7f08382c9981aad9cecad78808da670477566674141bc48","0x146d4801d6f5898051ee0d7c95375a65ea0e6deeac6ffee1d9b9cf64da72dc3e","0x000000000000000000000000000000425b99a5c96b22ba0286d9ebeecf8e4559","0x0000000000000000000000000000000000110be4b8fe46a96303c205d3a1d61d","0x000000000000000000000000000000d9ff7ae757f2f0c91d1f1e71fac1b27b74","0x000000000000000000000000000000000009b0c285f6c221f6eba93b1e330ac4","0x0000000000000000000000000000004055cd5738a25ab1860a1e35555962dc19","0x00000000000000000000000000000000001a8726ccf54e17cf1b005e3e04879a","0x0000000000000000000000000000007be4dc343e9c2e0d4a9156f1ef9769f65a","0x00000000000000000000000000000000002b0e96f68f6509615ca0544dfa3107"] +public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] +verification_key = ["0x2260e724844bca5251829353968e4915305258418357473a5c1d597f613f6cbd","0x0000000000000000000000000000000000000000000000000000000000080000","0x0000000000000000000000000000000000000000000000000000000000000005","0x0000000000000000000000000000000000000000000000000000000000080000","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000004","0x0000000000000000000000000000000000000000000000000000000000000005","0x0000000000000000000000000000000000000000000000000000000000000006","0x0000000000000000000000000000000000000000000000000000000000000007","0x0000000000000000000000000000000000000000000000000000000000000008","0x0000000000000000000000000000000000000000000000000000000000000009","0x000000000000000000000000000000000000000000000000000000000000000a","0x000000000000000000000000000000000000000000000000000000000000000b","0x000000000000000000000000000000000000000000000000000000000000000c","0x000000000000000000000000000000000000000000000000000000000000000d","0x000000000000000000000000000000000000000000000000000000000000000e","0x000000000000000000000000000000000000000000000000000000000000000f","0x0000000000000000000000000000000000000000000000000000000000000010","0x000000000000000000000000000000ba765ed919550454064328e0fd7c51ff4a","0x00000000000000000000000000000000000418b2f4104c289eb20cb95344c850","0x0000000000000000000000000000006defa500aab13c8cf3c00117db573bef2c","0x000000000000000000000000000000000026dea3ea8fb7e77b5bfa8443397dc7","0x0000000000000000000000000000009a5c33c4054817f3402e68aeca4728a405","0x00000000000000000000000000000000002abf5ea67ec384cb2e5998c7a48b3a","0x000000000000000000000000000000ee78817f7d959ea45abb27404e3371c708","0x0000000000000000000000000000000000260a979e8190a83b0bce1351b92d3c","0x000000000000000000000000000000ec447bd83a83883ce4c11573ce24845c74","0x000000000000000000000000000000000005b23c2076f50d10baa061a67b9200","0x00000000000000000000000000000058ffc16cfb64ec06a56a2b1a9047fb8f0c","0x000000000000000000000000000000000011d2f5833d720e1d0a02749471e7ad","0x000000000000000000000000000000416dd6c8c0d1cbb185b3c3197eac767d0b","0x000000000000000000000000000000000023b9c5a4e525926d64247ec92e0baf","0x000000000000000000000000000000a55f5f52ebc8936a58e413a1068d94d376","0x00000000000000000000000000000000000be3f377ccc88a6cb5df6f230da95e","0x00000000000000000000000000000070a162a08d4d4800f450af94888f8f3480","0x0000000000000000000000000000000000085883b02590372a7b36a1c57db4c3","0x00000000000000000000000000000045b0b661ea73930ee3327ccff8a0ca9ce1","0x00000000000000000000000000000000002854cab8629792eb07e9ef81bc46ee","0x00000000000000000000000000000067f365021e0e42117c43a39419d1d9cc73","0x000000000000000000000000000000000022c370b38f0a97eb3d718146f2284b","0x00000000000000000000000000000016de6670aba605233072b8eecfa9069b06","0x000000000000000000000000000000000002c29c49d66457bcbd4fa5bf6096fd","0x000000000000000000000000000000e32e8ce4f18ba30ce53245044d0c60508a","0x00000000000000000000000000000000001170220489121b8eedd58a4b5599df","0x000000000000000000000000000000139ed828b410380d053ec0f056656f5703","0x0000000000000000000000000000000000072aebdce25ba333c86769adec1362","0x000000000000000000000000000000aa352ee565f91fc2b73323fc824bc14636","0x00000000000000000000000000000000001f3e272a192808ec9283ee3bb4df4b","0x00000000000000000000000000000005c72c8c88be0259ae226ccb0488452b4b","0x00000000000000000000000000000000001c68407d694502b929b77cbbab8374","0x0000000000000000000000000000003716bda8267f29931ed0aa811e4607f1c6","0x000000000000000000000000000000000007d888936af2141bb2f6823a587e81","0x0000000000000000000000000000004cf1a4f39c5363f70ecc9e433d751ea529","0x00000000000000000000000000000000002e8a81232ec84e48032178f1ee6edb","0x000000000000000000000000000000388e8265061fa0c92c96fc85d99bac7891","0x00000000000000000000000000000000002e3c516222565332e6e7362400bc5f","0x0000000000000000000000000000003a68d13661a0906e5828fe8271a336bf64","0x00000000000000000000000000000000001412d3e67497c98e5ec2aaee8779f5","0x000000000000000000000000000000b5d123498733b5279d8bcbade0d8345ef7","0x00000000000000000000000000000000000fa572890537089a5fb36953e7a1ca","0x0000000000000000000000000000004d8ff057fc9936a693035266c80c6ea57d","0x00000000000000000000000000000000001907a614968d777fcc506f639799f6","0x00000000000000000000000000000010769533212d3cafbf6ac378c8055c33a2","0x00000000000000000000000000000000000eac32851272327acdc0890792dfb7","0x000000000000000000000000000000e3e32f343643d319a977beb0c2b0ab9b31","0x00000000000000000000000000000000000c10c4c9dce6ff648ef70f54d45ba6","0x00000000000000000000000000000025721304165b9b313b94cf2c77b61dc1ef","0x000000000000000000000000000000000024b8083b0f323c2703a7255caa7078","0x0000000000000000000000000000002b860372c65049c88f6532cbd360917b11","0x000000000000000000000000000000000011ee2ac2bc36cdfdc107eca47369f3","0x0000000000000000000000000000001c1b0233882acb5a78a977642e4dce91d5","0x000000000000000000000000000000000020922a70853993b3516eeb01d7c8a4","0x0000000000000000000000000000001f90b5fade69a55a2da8d2db3c62b62d7c","0x0000000000000000000000000000000000173312bb89c6722b548ff87a7487a2","0x0000000000000000000000000000009d618ffd933cf58a8a0953dc76f97cf108","0x00000000000000000000000000000000000ddc3b6d8e59cf0996ca71ad4132ca","0x000000000000000000000000000000ec4c6a253f431d3f3fc06aa0e5b0448b8c","0x0000000000000000000000000000000000153193287060386695f4f2d0d3525d","0x0000000000000000000000000000004bd25585edb9319128045c005d48491b1e","0x00000000000000000000000000000000001170f0ece62f8c572bca96b141d27f","0x0000000000000000000000000000003dd2e37b8edb1f56b785809d7710bf1c88","0x0000000000000000000000000000000000246cd041690f653f88ed0c56ad282a","0x00000000000000000000000000000034bc8a00ce9d452888e5fc2b5a7e14fed7","0x000000000000000000000000000000000026153c937447356a0c6d6be09d85eb","0x000000000000000000000000000000555388ad9364679246b07992f84b4e91b2","0x0000000000000000000000000000000000189da022421fbd8dfd7973084d978e","0x000000000000000000000000000000e8c0f9753e2a5a35acec051fafe2cecce5","0x0000000000000000000000000000000000285311c5e9a4cbb56a3f04f29d5443","0x00000000000000000000000000000092d2d0ac76a1be7f1fad96cbd997175312","0x00000000000000000000000000000000002436400260c9d3180beedd0bf49fec","0x000000000000000000000000000000887d86d95387bbb29616cc5c41ee4a2669","0x0000000000000000000000000000000000063bf32f8addf7a3e1cf6cd223cb71","0x000000000000000000000000000000d841dc7d9da6cc699e8377b2a04723fea0","0x00000000000000000000000000000000002ce091428268c212a2bcfea0edb338","0x00000000000000000000000000000012fe4771092fa47e4d6050701527133f09","0x00000000000000000000000000000000002f36672865c5ae4976486fdaf2d81d","0x0000000000000000000000000000008e6bced56a3d94dfe9d476da3a424b8eff","0x00000000000000000000000000000000002d6303cf28aa721f4e5348a0d83642","0x0000000000000000000000000000008c5807dace05b2079d200f7f71caffdaf7","0x000000000000000000000000000000000008f7beb50cb16f3b6210aff1bdb05d","0x0000000000000000000000000000004f9ee08a49536eb54a238b982c4dfd5446","0x000000000000000000000000000000000014f55e7065eabacf1a7d6cbf1f6765","0x00000000000000000000000000000021150153ec654b02a66d9bea056185877e","0x00000000000000000000000000000000000e7bf50a142b21057bcfd340a5e77c","0x00000000000000000000000000000038110629263a662f10464b375f988cccda","0x00000000000000000000000000000000001964a0ab814f71282cd159df492710","0x000000000000000000000000000000b9310dd49ea52ba735b9654ebced7bc67b","0x000000000000000000000000000000000019ad72f92554ce44921ca3f420f995","0x000000000000000000000000000000d67d7e81fa6e1cdfae6d84510a8cb7e257","0x00000000000000000000000000000000000a6ec9d85c10a85e8f31eaedb4e459"] +proof = ["0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf","0x00000000000000000000000000000000000000000000000b75c020998797da78","0x0000000000000000000000000000000000000000000000005a107acb64952eca","0x000000000000000000000000000000000000000000000000000031e97a575e9d","0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4","0x00000000000000000000000000000000000000000000000c410db10a01750aeb","0x00000000000000000000000000000000000000000000000d722669117f9758a4","0x000000000000000000000000000000000000000000000000000178cbf4206471","0x000000000000000000000000000000000000000000000000e91b8a11e7842c38","0x000000000000000000000000000000000000000000000007fd51009034b3357f","0x000000000000000000000000000000000000000000000009889939f81e9c7402","0x0000000000000000000000000000000000000000000000000000f94656a2ca48","0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f","0x0000000000000000000000000000000000000000000000093fe27776f50224bd","0x000000000000000000000000000000000000000000000004a0c80c0da527a081","0x0000000000000000000000000000000000000000000000000001b52c2020d746","0x00000000000000000000000000000063cb03b1d83ae3942e11ca8ec63055898b","0x00000000000000000000000000000000001edaf70d547a857fbed6a9ff8a38c9","0x000000000000000000000000000000097fb881332193ff4489e213f600e6a007","0x00000000000000000000000000000000001f2903742639c3595d22b96d4d9c21","0x000000000000000000000000000000bca7215bb1bcdde52ed9cf845b7e54072d","0x0000000000000000000000000000000000188bd12b19073eb01e8be5bda41b3e","0x0000000000000000000000000000007d1a114656606c391bfb286ea4e14062a5","0x000000000000000000000000000000000026d8a3b8821da41b6b1d6b85872260","0x000000000000000000000000000000c49078b857741b82cba39d8a394c1876c1","0x00000000000000000000000000000000002f9b9f76f80a4ff456e60c024f8d03","0x0000000000000000000000000000004bab3e60680935219213ea32be70ec5100","0x00000000000000000000000000000000002c45bda56f0115cfde2678889694ab","0x0000000000000000000000000000006434e56313172088d5a6b10fdd1b94b4ca","0x000000000000000000000000000000000007ad41e7980534fc2f89e8ad7366ad","0x00000000000000000000000000000023d769c68ef65f0b4f06a01e655fb265e7","0x0000000000000000000000000000000000008d3b5d5b201ed6773c369fe20d10","0x0000000000000000000000000000005eacdd2121ba4b1cf0df09632df6991fcf","0x0000000000000000000000000000000000005e98e857c8c1eb16cef913e44f90","0x0000000000000000000000000000003449da35dc7c0b67b0c3e99ced603ea381","0x000000000000000000000000000000000022347c8daec6739b183413a787fd13","0x000000000000000000000000000000df23d8f1ac4ddfced428737db15e63f603","0x000000000000000000000000000000000015e03670ba72d84269d764d8f8e725","0x000000000000000000000000000000457a7f854dbab545c8c94ccdb8e4b9ad45","0x00000000000000000000000000000000000a268fc41b7031912cec59dc0a7078","0x00000000000000000000000000000022fcb55824b67af33225f8f2e614fbbdb4","0x0000000000000000000000000000000000235f698e6aee7bf8ca94f4a44db006","0x000000000000000000000000000000a327da390bd3e01e4a7b639605fdfd9c42","0x0000000000000000000000000000000000210196c4fb53d660a3824867b2b1c5","0x000000000000000000000000000000728fb44750fa2b956221bd441fa61e32d6","0x0000000000000000000000000000000000073db9e2cafdf0fe22b5090855533e","0x0000000000000000000000000000004fe310e93730876891eebab46db9496dbc","0x000000000000000000000000000000000007d3574fe79c87011abdbd51a46670","0x000000000000000000000000000000adc522f42e085c51403fc50c83f35904b9","0x00000000000000000000000000000000000d2d9ef8fc0031b4568842a99b34eb","0x00000000000000000000000000000098586d928c8abc7cc56d571c8eded52168","0x000000000000000000000000000000000024279c001a40e94d3d149ec01a468a","0x00000000000000000000000000000066122aaf47d9d5060a2ce1d17cc5201be0","0x00000000000000000000000000000000001c21031d83d52e27867a611229d2ca","0x000000000000000000000000000000838dfc066499f7715682f755b42f3a4869","0x00000000000000000000000000000000001f816d2c5b2e903496f1443cb91de3","0x0000000000000000000000000000007ef917b6df805f430f8a0833942a7c3094","0x00000000000000000000000000000000000a9cefe716f31dbe37485179d60f0e","0x00000000000000000000000000000028adb1040bd0c07448de51d5cac9fd0495","0x00000000000000000000000000000000000c66b25a22c8b3ba82ec09ab4bdef3","0x2cc791d253f03f47cc88f7f0aeae481762f4aa6426712772544aaeca72466cb7","0x14197950f448f679eeff75c4e83dac9f0ebd5aa194709ea3875fb4e4b15bc2f2","0x1a92022c2ed8f8a41e3f392e22f1875f6916543bbb22c3aaf50d703de649c381","0x2ee77a26e78d5e1093dabd3612beee4b515a4f159992138e13ecd3f0afcfba18","0x2c280cba627b147142a2d333ee856000298708f9b5df0cc8d23c26d0936d6869","0x1b2569bb6f6b60b6f743ff892a39a490770d4ad40a961a06149d4968b0487a40","0x2f80351e43621d69b7e620338b2822e15dec9e6a2de16e8d04bb559153cd53a3","0x15a78b8ae9b3be431b609250b69c7cb746c6a689b2122150f258c6f7d67409fc","0x1334c47f273be542576813933e89a9130a342846272b39a2eab3ab7fc022d5fe","0x1031bdcafc5c0dad81c8b6c4931c9b442cd0c8a0bb9a729cc2f6bf0a18dc1b82","0x177f92f0cef76c5c45f55d16fa2be426354cdd4af6ac9aaad479c9b47f88656d","0x0064c0e0ec8984d612189e5287d59eedc1a6de52fc78bf72028f744350c27a0e","0x2c06222cf0d415c976e6904f1706b77cf438636ada3222e1c31c4957d6877dac","0x173da534b7001f44f19bb3e3f8601ac94fbf90b2e39b7d4079d8fac2d65102ea","0x012909bcdbd1167010cf0084028e851f3448f58946f4951b1b8d544d86b138c8","0x2975c3987f110c06bd8ced1d8bb0d398ac72c6f196ea639bdde58fa4b899d4a0","0x05c196fb2f6ccfd92a38ae526af85bccc3695ea0e2561e7a211c60360187602d","0x18a288590dd0cbfe5b7652458c9caddc9eac2f08e5822b64141ed1b4e805bda3","0x0cd08c41605b22a7ae31c3961486f645a32bff0ccaef63b6d661ef356db78560","0x05d5e48184693259f722f84ea48f9b84667d1e9db19e1381b2279fe24b01484b","0x2187a6f6a2398e5f0137880a983ff6b682b5a7c2b62e4bdfff6ff6becd0d53ab","0x1d4764ca9346e8ac48675320521e0daba651f480efe932302e8a9673580fc0d8","0x00cfcb920adeb0293acf26e63aeac4489622e4c806b93f1c72f8491cba3d0196","0x1bcd6a556800b8385ba1250afd69999fe2bb5518a6ba2cc461a4afba21ffbedb","0x11a15b3c8ef0e4ac0ff151fba72b922f6c005519151a4f88557352265944aeea","0x063d550a154f2ce80b08fb169d137fa96dcea6a6c489e98e1390aa9a5db18928","0x25da993132041b9f667de044194f5c6b0cdae961cdea5f6dbbda8595f213ac08","0x22fcecc2e3794814bbb84700031cd75ec9817201c8c88df2e86407a14412f902","0x01583d25d2f91d646da02a520d3dbf758b0a0590a533bd1417a717fd0cd18915","0x18ebacffdc81e15547232dfc1a0e31ec2848a1e5b9c8509a92432c2549d93091","0x20a3d15aa70d04a841802fe1d990f56c6b9e6eadc17da2c0dfd2a817e6cf0430","0x0b497cc2e54412ce07c52effdce6c01de2c1a0e1d095a2a37f5351232400c0a1","0x14419bb69d02675b8d58e60ce88a2f4b6a43674461e4015e2e302285a42c5784","0x0c84db03ff77d0729bb68eab2d6d697b7caebd4ea3db781499492a6f0ef67765","0x1a676b1c6b0ab1c85b31af681e05751296c3d0a1a883668f5fe971827ce86fc9","0x08da949bf7603bfe20f3c152abe727051c6306cff322197e8fa56b390f565b5b","0x1fd77e041239f94e907dc3ae3069a70cbff726b9d8b3a368a4910c8a070a9c9a","0x03755d83a4f0fdfbb4fd1b2b465842e1bb707a419c2952a2ca9faba50d4be379","0x0ee90c8166adcb238d85c72a85db2248353610c55390a2ed54e59dd1c35c12d2","0x170bcd78efaa1b19bcfd065c2ec60b48aa1e62465df73e62f3bd291115315144","0x015d60e5cc5c7d67853993261bd9e3c6e56f95dee8724ce79c7601ee10c1a731","0x000000000000000000000000000000f0a8b99d65fc1555bafb688233a6489aea","0x0000000000000000000000000000000000043849f038ec96c8c1c6e242351361","0x0000000000000000000000000000001ad41d3dfebb280623d5b325f0a7aa38f7","0x00000000000000000000000000000000002e5f2119536daa9e6d1f9b82b797dd","0x000000000000000000000000000000e5570c2b6e74d0994e2fc8be1a9dab4160","0x00000000000000000000000000000000002ed426a78ed52d4c13f2c651a6d4ec","0x000000000000000000000000000000aba14637487e4d3ca30dc397416696c85c","0x000000000000000000000000000000000005ae1eb3eee0cdf5e5c7bb0ac9be07"] diff --git a/noir/test_programs/execution_success/double_verify_nested_proof/src/main.nr b/noir/test_programs/execution_success/double_verify_nested_proof/src/main.nr new file mode 100644 index 000000000000..0466f2a226d9 --- /dev/null +++ b/noir/test_programs/execution_success/double_verify_nested_proof/src/main.nr @@ -0,0 +1,28 @@ +use dep::std; + +fn main( + verification_key: [Field; 114], + // This is the proof without public inputs attached. + // + // This means: the size of this does not change with the number of public inputs. + proof: [Field; 109], + public_inputs: pub [Field; 1], + // This is currently not public. It is fine given that the vk is a part of the circuit definition. + // I believe we want to eventually make it public too though. + key_hash: Field, + proof_b: [Field; 109] +) { + std::verify_proof( + verification_key.as_slice(), + proof.as_slice(), + public_inputs.as_slice(), + key_hash + ); + + std::verify_proof( + verification_key.as_slice(), + proof_b.as_slice(), + public_inputs.as_slice(), + key_hash + ); +} diff --git a/noir/test_programs/execution_success/double_verify_proof/src/main.nr b/noir/test_programs/execution_success/double_verify_proof/src/main.nr index ce087dc4e61f..e4c6926efbc6 100644 --- a/noir/test_programs/execution_success/double_verify_proof/src/main.nr +++ b/noir/test_programs/execution_success/double_verify_proof/src/main.nr @@ -1,12 +1,13 @@ use dep::std; +#[recursive] fn main( verification_key: [Field; 114], // This is the proof without public inputs attached. // // This means: the size of this does not change with the number of public inputs. proof: [Field; 93], - public_inputs: [Field; 1], + public_inputs: pub [Field; 1], // This is currently not public. It is fine given that the vk is a part of the circuit definition. // I believe we want to eventually make it public too though. key_hash: Field, From c04d72fd363b32743cf906bfe986f82c5d5901fc Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:36:48 +0000 Subject: [PATCH 02/10] feat: non revertible effects and tx phases (#4629) There are 3 primary changes in this PR. 1. Within the private kernel tail, split the side effects that have been accumulated during private execution into `end`, and `end_non_revertible` based on their side effect counters compared with `min_revertible_side_effect_counter`. 2. Examine those structs on the sequencer and run circuits for setup, app logic, and teardown accordingly. 3. Recombine `end` and `end_non_revertible` at the beginning of the rollup base. To accomplish this, new structs are introduced. `CombinedAccumulatedData` is unchanged, and holds side effects that are both revertible and non-revertible. For this reason, it is part of `PrivateKernelInnerCircuitPublicInputs`, and `RollupKernelCircuitPublicInputs`. `PrivateKernelTailCircuitPublicInputs` has been updated to hold ``` end_non_revertible: PrivateAccumulatedNonRevertibleData, end: PrivateAccumulatedRevertibleData, ``` and `PublicKernelCircuitPublicInputs` has been updated to hold ``` end_non_revertible: PublicAccumulatedNonRevertibleData, end: PublicAccumulatedRevertibleData, ``` The difference between `PrivateAccumulated` and `PublicAccumulated` is that the `Private` flavors cannot hold `public_data_update_requests` or `public_data_reads`. Additionally, for the types of side effects that can be non-revertible (which at present are commitments, nullifiers, public data updates, public data reads), there are new constants defined, e.g. `MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX` and `MAX_REVERTIBLE_COMMITMENTS_PER_TX`. These two sizes must sum to `MAX_NEW_COMMITMENTS_PER_TX`, and similarly for the other types. Thus, the bulk of the added work done by circuits is performed in `combined_accumulated_data.nr`. We expect there are significant optimizations that can be made to our initial implementation of splitting and recombining. Note, the decision was made to recombine in the base rollup to reduce conditional logic and reuse existing machinery that wants to look at a single `CombinedAccumulatedData`. Further, it made architectural sense in that the rollup should not need to know/care that certain e.g. nullifiers submitted were `nonRevertible`: it received the nullifiers, thus they must not have reverted. The recombine could have been performed by the public kernel, but we didn't want to add an obligatory circuit for the sequencer if, e.g. they were submitted a fully private transaction (since they would always be obliged to recombine the TX nullifier which is now part of the non-revertible side effects). To handle the non revertible side effects, we repurposed the public kernel circuits to correspond with the "phases" of a transaction: 1. setup 2. app logic 3. teardown In order to ensure that the phases are correctly followed, we introduce 3 more members to `PrivateKernelTailCircuitPublicInputs` and `PublicKernelCircuitPublicInputs`: ``` needs_setup: bool, // true if there is more than 1 enqueued non-revertible public call needs_app_logic: bool, // true if there is more than 0 enqueued revertible public calls needs_teardown: bool, // true if there is more than 0 enqueued non-revertible public calls ``` The semantic is that for enqueued non-revertible public calls, the call that is enqueued last is for teardown (e.g. pay the fee), and all other are for setup (e.g. engage with some fee payment contract). See `AbstractPhaseManager.extractEnqueuedPublicCallsByPhase`. Note further that we haven't added new e2e tests here, as the interface for using this is sitting in [this PR](https://github.com/AztecProtocol/aztec-packages/pull/4543) Co-authored-by: Alex Gherghisan --- l1-contracts/slither_output.md | 4 +- .../src/core/libraries/ConstantsGen.sol | 15 +- noir-projects/aztec-nr/authwit/src/account.nr | 2 +- .../aztec/src/context/private_context.nr | 29 +- .../noir-protocol-circuits/package.json | 4 +- .../noir-protocol-circuits/src/Nargo.toml | 2 + .../crates/private-kernel-lib/src/common.nr | 1 + .../src/private_kernel_init.nr | 2 +- .../src/private_kernel_inner.nr | 2 +- .../src/private_kernel_tail.nr | 173 +- .../crates/public-kernel-lib/src/common.nr | 141 +- .../src/crates/public-kernel-lib/src/lib.nr | 2 + .../src/public_kernel_app_logic.nr | 113 +- .../src/public_kernel_setup.nr | 156 +- .../src/public_kernel_teardown.nr | 402 ++ .../Nargo.toml | 9 + .../src/main.nr | 6 + .../crates/public-kernel-teardown/Nargo.toml | 9 + .../crates/public-kernel-teardown/src/main.nr | 6 + .../rollup-lib/src/base/base_rollup_inputs.nr | 90 +- .../src/abis/combined_accumulated_data.nr | 441 +- .../src/abis/kernel_circuit_public_inputs.nr | 76 +- .../src/crates/types/src/abis/kernel_data.nr | 3 +- .../src/abis/private_circuit_public_inputs.nr | 6 +- .../src/crates/types/src/constants.nr | 22 +- .../src/crates/types/src/lib.nr | 2 +- .../types/src/tests/kernel_data_builder.nr | 102 +- .../private_circuit_public_inputs_builder.nr | 4 +- .../src/crates/types/src/traits.nr | 2 +- .../src/crates/types/src/utils/arrays.nr | 28 +- .../aztec-node/src/aztec-node/server.ts | 6 +- yarn-project/aztec.js/src/contract/sent_tx.ts | 4 +- .../circuit-types/src/contract_data.ts | 15 +- yarn-project/circuit-types/src/mocks.ts | 18 +- yarn-project/circuit-types/src/stats/stats.ts | 5 +- yarn-project/circuit-types/src/tx/tx.ts | 37 +- yarn-project/circuits.js/src/constants.gen.ts | 15 +- .../circuits.js/src/structs/call_request.ts | 4 + .../kernel/combined_accumulated_data.test.ts | 4 +- .../kernel/combined_accumulated_data.ts | 382 +- ...vate_kernel_inner_circuit_public_inputs.ts | 4 +- ...ivate_kernel_tail_circuit_public_inputs.ts | 34 +- .../public_kernel_circuit_public_inputs.ts | 47 +- .../src/structs/private_call_stack_item.ts | 9 +- .../structs/private_circuit_public_inputs.ts | 6 +- .../src/structs/public_call_request.ts | 8 +- .../structs/rollup/public_data_leaf/index.ts | 4 + .../circuits.js/src/structs/side_effects.ts | 20 +- .../circuits.js/src/tests/factories.ts | 97 +- yarn-project/end-to-end/jest.config.ts | 12 + yarn-project/end-to-end/package.json | 8 - .../end-to-end/src/e2e_ordering.test.ts | 4 + .../src/integration_l1_publisher.test.ts | 34 +- .../foundation/src/aztec-address/index.ts | 18 +- yarn-project/foundation/src/fields/fields.ts | 2 +- .../src/__snapshots__/index.test.ts.snap | 4012 ++++------------- .../nested-call-private-kernel-init.hex | 2 +- .../nested-call-private-kernel-inner.hex | 2 +- .../nested-call-private-kernel-ordering.hex | 2 +- .../noir-protocol-circuits-types/src/index.ts | 82 +- .../src/scripts/generate_ts_from_abi.ts | 1 + .../src/type_conversion.ts | 227 +- .../p2p/src/service/libp2p_service.ts | 6 +- .../p2p/src/tx_pool/memory_tx_pool.ts | 5 +- .../p2p/src/tx_pool/tx_pool_test_suite.ts | 12 +- .../src/kernel_prover/kernel_prover.test.ts | 3 +- .../pxe/src/pxe_service/pxe_service.ts | 57 +- .../block_builder/solo_block_builder.test.ts | 73 +- .../src/block_builder/solo_block_builder.ts | 33 +- .../src/sequencer/abstract_phase_manager.ts | 273 +- .../src/sequencer/app_logic_phase_manager.ts | 72 + .../application_logic_phase_manager.ts | 107 - .../fee_preparation_phase_manager.ts | 79 - .../src/sequencer/phase_manager_factory.ts | 122 + .../src/sequencer/processed_tx.ts | 25 +- .../src/sequencer/public_processor.test.ts | 151 +- .../src/sequencer/public_processor.ts | 41 +- .../src/sequencer/sequencer.test.ts | 14 +- .../src/sequencer/sequencer.ts | 25 +- .../src/sequencer/setup_phase_manager.test.ts | 79 + ...hase_manager.ts => setup_phase_manager.ts} | 48 +- .../src/sequencer/teardown_phase_manager.ts | 67 + .../sequencer-client/src/simulator/index.ts | 16 +- .../src/simulator/public_kernel.ts | 52 +- 84 files changed, 4358 insertions(+), 3981 deletions(-) create mode 100644 noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_teardown.nr create mode 100644 noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/Nargo.toml create mode 100644 noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/src/main.nr create mode 100644 noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/Nargo.toml create mode 100644 noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/src/main.nr create mode 100644 yarn-project/end-to-end/jest.config.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts delete mode 100644 yarn-project/sequencer-client/src/sequencer/application_logic_phase_manager.ts delete mode 100644 yarn-project/sequencer-client/src/sequencer/fee_preparation_phase_manager.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts create mode 100644 yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts rename yarn-project/sequencer-client/src/sequencer/{fee_distribution_phase_manager.ts => setup_phase_manager.ts} (53%) create mode 100644 yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts diff --git a/l1-contracts/slither_output.md b/l1-contracts/slither_output.md index bb1d199cf783..81c96c9ab12b 100644 --- a/l1-contracts/slither_output.md +++ b/l1-contracts/slither_output.md @@ -353,9 +353,9 @@ src/core/messagebridge/Inbox.sol#L148-L153 Impact: Informational Confidence: Medium - [ ] ID-41 -Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L96) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L97) +Variable [Constants.L1_TO_L2_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L103) is too similar to [Constants.L2_TO_L1_MESSAGE_LENGTH](src/core/libraries/ConstantsGen.sol#L104) -src/core/libraries/ConstantsGen.sol#L96 +src/core/libraries/ConstantsGen.sol#L103 - [ ] ID-42 diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index a5682884a4ad..b0393fbafd0f 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -26,20 +26,27 @@ library Constants { uint256 internal constant MAX_READ_REQUESTS_PER_CALL = 32; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; uint256 internal constant MAX_NEW_COMMITMENTS_PER_TX = 64; + uint256 internal constant MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; + uint256 internal constant MAX_REVERTIBLE_COMMITMENTS_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_NEW_L2_TO_L1_MSGS_PER_TX = 2; + 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 = 16; + uint256 internal constant MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 1; + uint256 internal constant MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 15; uint256 internal constant MAX_PUBLIC_DATA_READS_PER_TX = 16; + uint256 internal constant MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX = 1; + uint256 internal constant MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX = 15; + uint256 internal constant MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2; uint256 internal constant MAX_NEW_CONTRACTS_PER_TX = 1; uint256 internal constant MAX_READ_REQUESTS_PER_TX = 128; uint256 internal constant MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX = 4; uint256 internal constant NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; uint256 internal constant NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; - uint256 internal constant MAX_NEW_COMMITMENTS_PER_TX_META = 8; - uint256 internal constant MAX_NEW_NULLIFIERS_PER_TX_META = 8; - uint256 internal constant MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META = 2; uint256 internal constant NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; uint256 internal constant VK_TREE_HEIGHT = 3; uint256 internal constant FUNCTION_TREE_HEIGHT = 5; diff --git a/noir-projects/aztec-nr/authwit/src/account.nr b/noir-projects/aztec-nr/authwit/src/account.nr index dc343eace0c4..5d82902efc49 100644 --- a/noir-projects/aztec-nr/authwit/src/account.nr +++ b/noir-projects/aztec-nr/authwit/src/account.nr @@ -61,7 +61,7 @@ impl AccountActions { let fee_hash = fee_payload.hash(); assert(valid_fn(private_context, fee_hash)); fee_payload.execute_calls(private_context); - private_context.capture_max_non_revertible_side_effect_counter(); + private_context.capture_min_revertible_side_effect_counter(); let app_hash = app_payload.hash(); assert(valid_fn(private_context, app_hash)); diff --git a/noir-projects/aztec-nr/aztec/src/context/private_context.nr b/noir-projects/aztec-nr/aztec/src/context/private_context.nr index d763b608056b..04e5dcb9c9b2 100644 --- a/noir-projects/aztec-nr/aztec/src/context/private_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/private_context.nr @@ -4,7 +4,8 @@ use crate::{ oracle::{ arguments, call_private_function::call_private_function_internal, enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address, - header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair} + header::get_header_at, nullifier_key::{get_nullifier_key_pair, NullifierKeyPair}, + debug_log::debug_log } }; use dep::protocol_types::{ @@ -40,7 +41,7 @@ struct PrivateContext { inputs: PrivateContextInputs, side_effect_counter: u32, - max_non_revertible_side_effect_counter: u32, + min_revertible_side_effect_counter: u32, args_hash : Field, return_values : BoundedVec, @@ -68,10 +69,16 @@ struct PrivateContext { impl PrivateContext { pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext { + let side_effect_counter = inputs.call_context.start_side_effect_counter; + let mut min_revertible_side_effect_counter = 0; + // Note. The side effect counter is 2 when this is the initial call + if (side_effect_counter == 2) { + min_revertible_side_effect_counter = side_effect_counter; + } PrivateContext { inputs, - side_effect_counter: inputs.call_context.start_side_effect_counter, - max_non_revertible_side_effect_counter: 0, + side_effect_counter, + min_revertible_side_effect_counter, args_hash, return_values: BoundedVec::new(0), read_requests: BoundedVec::new(SideEffect::empty()), @@ -136,7 +143,12 @@ impl PrivateContext { call_context: self.inputs.call_context, args_hash: self.args_hash, return_values: self.return_values.storage, - max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter, + // TODO(fees): start this from 0 and test the following: + // - in the private circuit init that it gets set correctly + // - in the private circuit inner that it remains 0 + // I've had to initialize the counter here so that it would work for contract deployments + // the above checks should be doable after we figure out fee payments for contract deployments + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_commitments: self.new_commitments.storage, @@ -157,11 +169,8 @@ impl PrivateContext { priv_circuit_pub_inputs } - pub fn capture_max_non_revertible_side_effect_counter(&mut self) { - assert( - self.max_non_revertible_side_effect_counter == 0, "Already captured the non-revertible side effect counter" - ); - self.max_non_revertible_side_effect_counter = self.side_effect_counter; + pub fn capture_min_revertible_side_effect_counter(&mut self) { + self.min_revertible_side_effect_counter = self.side_effect_counter; } pub fn push_read_request(&mut self, read_request: Field) { diff --git a/noir-projects/noir-protocol-circuits/package.json b/noir-projects/noir-protocol-circuits/package.json index d957434c438a..a3b4f9b70885 100644 --- a/noir-projects/noir-protocol-circuits/package.json +++ b/noir-projects/noir-protocol-circuits/package.json @@ -11,10 +11,10 @@ "build": "yarn clean && yarn noir:build", "clean": "rm -rf ./dest src/target", "noir:build": "cd src && ../../../noir/target/release/nargo compile --silence-warnings", - "test": "cd src && ../../../noir/target/release/nargo test" + "test": "cd src && ../../../noir/target/release/nargo test --silence-warnings" }, "files": [ "dest", "src" ] -} \ No newline at end of file +} diff --git a/noir-projects/noir-protocol-circuits/src/Nargo.toml b/noir-projects/noir-protocol-circuits/src/Nargo.toml index 073a36cd0be3..749f1ecda0f0 100644 --- a/noir-projects/noir-protocol-circuits/src/Nargo.toml +++ b/noir-projects/noir-protocol-circuits/src/Nargo.toml @@ -13,6 +13,8 @@ members = [ "crates/public-kernel-setup-simulated", "crates/public-kernel-app-logic", "crates/public-kernel-app-logic-simulated", + "crates/public-kernel-teardown", + "crates/public-kernel-teardown-simulated", "crates/rollup-lib", "crates/rollup-merge", "crates/rollup-base", diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index ac5ab83885cd..90a8c50c715e 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -86,6 +86,7 @@ pub fn initialize_end_values( public_inputs: &mut PrivateKernelCircuitPublicInputsBuilder ) { public_inputs.constants = previous_kernel.public_inputs.constants; + public_inputs.min_revertible_side_effect_counter = previous_kernel.public_inputs.min_revertible_side_effect_counter; // Ensure the arrays are the same as previously, before we start pushing more data onto them in other // functions within this circuit: diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr index 363be67a85f1..5758d7550b57 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr @@ -26,7 +26,7 @@ impl PrivateKernelInitCircuitPrivateInputs { historical_header: self.private_call.call_stack_item.public_inputs.historical_header, tx_context: self.tx_request.tx_context, }; - public_inputs.max_non_revertible_side_effect_counter = self.private_call.call_stack_item.public_inputs.max_non_revertible_side_effect_counter; + public_inputs.min_revertible_side_effect_counter = self.private_call.call_stack_item.public_inputs.min_revertible_side_effect_counter; } // Confirm that the TxRequest (user's intent) diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index cd1e987b38f3..d91407955f99 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -103,7 +103,7 @@ mod tests { impl PrivateKernelInnerInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(); + let previous_kernel = PreviousKernelDataBuilder::new(false); let private_call = PrivateCallDataBuilder::new(false); PrivateKernelInnerInputsBuilder { previous_kernel, private_call } diff --git a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr index 250902c28194..1569820df9ab 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_tail.nr @@ -2,8 +2,7 @@ use crate::common; use dep::std::{cmp::Eq, option::Option, unsafe}; use dep::types::{ abis::{ - call_request::CallRequest, combined_accumulated_data::AccumulatedNonRevertibleData, - nullifier_key_validation_request::NullifierKeyValidationRequestContext, + call_request::CallRequest, nullifier_key_validation_request::NullifierKeyValidationRequestContext, kernel_data::{PrivateKernelInnerData, PrivateKernelTailData}, kernel_circuit_public_inputs::{PrivateKernelCircuitPublicInputsBuilder, PrivateKernelTailCircuitPublicInputs}, side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered} @@ -221,17 +220,17 @@ impl PrivateKernelTailCircuitPrivateInputs { PrivateKernelTailCircuitPrivateInputs::apply_commitment_nonces(&mut public_inputs); - // TODO(fees) populate this - let end_non_revertible : AccumulatedNonRevertibleData = unsafe::zeroed(); - - public_inputs.to_tail(end_non_revertible) + public_inputs.to_tail() } } mod tests { use dep::std::cmp::Eq; use crate::private_kernel_tail::PrivateKernelTailCircuitPrivateInputs; - use dep::types::constants::{MAX_READ_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX}; + use dep::types::constants::{ + MAX_READ_REQUESTS_PER_TX, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX + }; use dep::types::{ abis::{ kernel_circuit_public_inputs::PrivateKernelTailCircuitPublicInputs, @@ -250,7 +249,7 @@ mod tests { impl PrivateKernelOrderingInputsBuilder { pub fn new() -> Self { PrivateKernelOrderingInputsBuilder { - previous_kernel: PreviousKernelDataBuilder::new(), + previous_kernel: PreviousKernelDataBuilder::new(false), read_commitment_hints: [0; MAX_READ_REQUESTS_PER_TX], nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX] } @@ -286,7 +285,7 @@ mod tests { } pub fn append_nullifiers(&mut self, num_nullifiers: Field) { - self.previous_kernel.append_new_nullifiers(num_nullifiers); + self.previous_kernel.append_new_nullifiers_from_private(num_nullifiers); } pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { @@ -321,7 +320,7 @@ mod tests { (sorted_sideffects, reverse_map) } - pub fn execute(self) -> PrivateKernelTailCircuitPublicInputs { + pub fn execute(&mut self) -> PrivateKernelTailCircuitPublicInputs { let (sorted_new_commitments, sorted_new_commitments_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); let mut sorted_read_commitment_hints = [0; MAX_READ_REQUESTS_PER_TX]; for i in 0..sorted_read_commitment_hints.len() { @@ -332,6 +331,7 @@ mod tests { for i in 0..sorted_nullifier_commitment_hints.len() { sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]] as Field; } + let kernel = PrivateKernelTailCircuitPrivateInputs { previous_kernel: self.previous_kernel.to_private_kernel_inner_data(), sorted_new_commitments, @@ -345,11 +345,19 @@ mod tests { kernel.native_private_kernel_circuit_ordering() } - pub fn failed(self) { + pub fn failed(&mut self) { let _ = self.execute(); } } + #[test] + unconstrained fn splits_tx_nullifier_to_non_revertible() { + let mut builder = PrivateKernelOrderingInputsBuilder::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 = PrivateKernelOrderingInputsBuilder::new(); @@ -368,15 +376,20 @@ mod tests { unconstrained fn native_matching_some_read_requests_to_commitments_works() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); + // prepare for the split: first MAX_NON_REVERTIBLE_COMMITMENTS_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_commitments.get(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX).counter; // Read the commitment at index 1; builder.add_transient_read(1); // Read the commitment at index 3; builder.add_transient_read(3); let unique_siloed_commitments = builder.get_unique_siloed_commitments(); let public_inputs = builder.execute(); - assert_eq(array_length(public_inputs.end.new_commitments), MAX_NEW_COMMITMENTS_PER_TX); - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { - assert(public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[i])); + assert_eq(array_length(public_inputs.end.new_commitments), MAX_REVERTIBLE_COMMITMENTS_PER_TX); + for i in 0..MAX_REVERTIBLE_COMMITMENTS_PER_TX { + assert( + public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX + i]) + ); } } @@ -403,8 +416,14 @@ mod tests { assert(is_empty_array(public_inputs.end.new_commitments)); // The nullifier at index 1 is chopped. - let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; - assert(array_eq(public_inputs.end.new_nullifiers, expected_new_nullifiers)); + 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]] + ) + ); } #[test] @@ -426,13 +445,20 @@ mod tests { ) ); // The nullifier at index 1 is chopped. - let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; - assert(array_eq(public_inputs.end.new_nullifiers, expected_new_nullifiers)); + 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]] + ) + ); } #[test] unconstrained fn native_squash_two_of_two_transient_matches_works() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(2); builder.append_nullifiers(2); // The nullifier at index 1 is nullifying the commitment at index 1; @@ -441,8 +467,18 @@ mod tests { builder.nullify_transient_commitment(2, 0); let new_nullifiers = builder.get_new_nullifiers(); let public_inputs = builder.execute(); + + // app logic will be completely empty after squashing assert(is_empty_array(public_inputs.end.new_commitments)); - assert(array_eq(public_inputs.end.new_nullifiers, [new_nullifiers[0]])); + 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]] + ) + ); } #[test] @@ -453,8 +489,8 @@ mod tests { let mut sorted_new_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; for i in 0..10 { - sorted_new_commitments[i] = SideEffect { value: (i + 1) as Field, counter: i + 1 }; - sorted_new_nullifiers[i] = SideEffectLinkedToNoteHash { value: (i + 11) as Field, counter: i + 11, note_hash: 0 }; + sorted_new_commitments[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 }; } for i in 0..10 { @@ -465,14 +501,14 @@ mod tests { let public_inputs = builder.execute(); let sorted_unique_commitments = compute_unique_siloed_commitments( - public_inputs.end.new_nullifiers[0].value, + // tx nullifier is part of non revertible accumulated data + public_inputs.end_non_revertible.new_nullifiers[0].value, sorted_new_commitments ); for i in 0..10 { assert(public_inputs.end.new_commitments[i].eq(sorted_unique_commitments[i])); - // +1 due to the 0th nullifier being the tx hash - assert(public_inputs.end.new_nullifiers[i + 1].eq(sorted_new_nullifiers[i])); + assert(public_inputs.end.new_nullifiers[i].eq(sorted_new_nullifiers[i])); } } @@ -483,7 +519,8 @@ mod tests { builder.append_nullifiers(2); let public_inputs = builder.execute(); assert_eq(array_length(public_inputs.end.new_commitments), 2); - assert_eq(array_length(public_inputs.end.new_nullifiers), 3); + assert_eq(array_length(public_inputs.end.new_nullifiers), 2); + assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } // same as previous test, but this time there are 0 commitments! // (Do we really need this test?) @@ -494,7 +531,8 @@ mod tests { builder.append_nullifiers(2); let public_inputs = builder.execute(); assert(array_length(public_inputs.end.new_commitments) == 0); - assert(array_length(public_inputs.end.new_nullifiers) == 3); + assert(array_length(public_inputs.end.new_nullifiers) == 2); + assert_eq(array_length(public_inputs.end_non_revertible.new_nullifiers), 1); } #[test(should_fail)] @@ -536,4 +574,87 @@ mod tests { builder.previous_kernel.end.new_nullifiers = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); builder.failed(); } + + #[test] + unconstrained fn split_nullifiers_into_non_revertible() { + let mut builder = PrivateKernelOrderingInputsBuilder::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 = PrivateKernelOrderingInputsBuilder::new(); + + // expect 2 non-revertible commitments + builder.previous_kernel.append_new_commitments(2); + builder.previous_kernel.capture_min_revertible_side_effect_counter(); + + // expect 2 revertible commitments + builder.previous_kernel.append_new_commitments(2); + + let new_commitments = builder.previous_kernel.end.new_commitments.storage; + let public_inputs = builder.execute(); + + let unique_commitments = compute_unique_siloed_commitments( + // tx nullifier is part of non revertible accumulated data + public_inputs.end_non_revertible.new_nullifiers[0].value, + new_commitments + ); + + assert( + array_eq( + public_inputs.end_non_revertible.new_commitments, + [unique_commitments[0], unique_commitments[1]] + ) + ); + + assert( + array_eq( + public_inputs.end.new_commitments, + [unique_commitments[2], unique_commitments[3]] + ) + ); + } + + #[test] + unconstrained fn split_side_effect_squashing() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + + // add one commitment in non-revertible part + builder.previous_kernel.append_new_commitments(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_commitments)); + assert(is_empty_array(public_inputs.end.new_commitments)); + assert(is_empty_array(public_inputs.end.new_nullifiers)); + } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr index dda7f0ba5b19..837d6ee54fd9 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/common.nr @@ -13,7 +13,9 @@ use dep::types::{ constants::{ MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, - MAX_PUBLIC_DATA_READS_PER_CALL, NUM_FIELDS_PER_SHA256 + MAX_PUBLIC_DATA_READS_PER_CALL, NUM_FIELDS_PER_SHA256, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX }, hash::{silo_commitment, silo_nullifier, compute_l2_to_l1_hash, accumulate_sha256}, utils::{arrays::{array_length, array_to_bounded_vec}}, traits::{is_empty, is_empty_array} @@ -66,6 +68,14 @@ pub fn initialize_end_values( circuit_outputs.end.encrypted_log_preimages_length = start.encrypted_log_preimages_length; circuit_outputs.end.new_contracts = array_to_bounded_vec(previous_kernel.public_inputs.end.new_contracts); + + let start_non_revertible = previous_kernel.public_inputs.end_non_revertible; + circuit_outputs.end_non_revertible.new_commitments = array_to_bounded_vec(start_non_revertible.new_commitments); + circuit_outputs.end_non_revertible.new_nullifiers = array_to_bounded_vec(start_non_revertible.new_nullifiers); + circuit_outputs.end_non_revertible.public_call_stack = array_to_bounded_vec(start_non_revertible.public_call_stack); + + 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.public_data_reads = array_to_bounded_vec(start_non_revertible.public_data_reads); } fn perform_static_call_checks(public_call: PublicCallData) { @@ -122,9 +132,31 @@ fn validate_call_requests( } } +pub fn update_public_end_non_revertible_values( + public_call: PublicCallData, + circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder +) { + // Updates the circuit outputs with new state changes, call stack etc + + // If this call is a static call, certain operations are disallowed, such as creating new state. + perform_static_call_checks(public_call); + + // Update public call stack. + let public_call_requests = array_to_bounded_vec(public_call.public_call_stack); + let hashes = public_call.call_stack_item.public_inputs.public_call_stack_hashes; + validate_call_requests(public_call_requests, hashes, public_call); + circuit_outputs.end_non_revertible.public_call_stack.extend_from_bounded_vec(public_call_requests); + + propagate_new_nullifiers_non_revertible(public_call, circuit_outputs); + propagate_new_commitments_non_revertible(public_call, circuit_outputs); + propagate_valid_non_revertible_public_data_update_requests(public_call, circuit_outputs); + propagate_valid_non_revertible_public_data_reads(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) { // Updates the circuit outputs with new state changes, call stack etc - circuit_outputs.is_private = false; // If this call is a static call, certain operations are disallowed, such as creating new state. perform_static_call_checks(public_call); @@ -152,9 +184,10 @@ 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; - let mut public_data_update_requests : BoundedVec = BoundedVec::new(PublicDataUpdateRequest::empty()); + // TODO(fees) should we have a MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + let mut public_data_update_requests : BoundedVec = BoundedVec::new(PublicDataUpdateRequest::empty()); - for i in 0..MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + for i in 0..MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { let update_request = update_requests[i]; if (!update_request.is_empty()) { let public_data_update_request = PublicDataUpdateRequest { @@ -168,13 +201,38 @@ fn propagate_valid_public_data_update_requests( circuit_outputs.end.public_data_update_requests.extend_from_bounded_vec(public_data_update_requests); } +fn propagate_valid_non_revertible_public_data_update_requests( + public_call: PublicCallData, + circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder +) { + 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(PublicDataUpdateRequest::empty()); + + for i in 0..MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX { + let update_request = update_requests[i]; + if (!update_request.is_empty()) { + let public_data_update_request = PublicDataUpdateRequest { + leaf_slot: compute_public_data_tree_index(contract_address, update_request.storage_slot), + new_value: compute_public_data_tree_value(update_request.new_value) + }; + + public_data_update_requests.push(public_data_update_request); + } + } + circuit_outputs.end_non_revertible.public_data_update_requests.extend_from_bounded_vec(public_data_update_requests); +} + fn propagate_valid_public_data_reads(public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder) { let contract_address = public_call.call_stack_item.public_inputs.call_context.storage_contract_address; let read_requests = public_call.call_stack_item.public_inputs.contract_storage_reads; - let mut public_data_reads : BoundedVec = BoundedVec::new(PublicDataRead::empty()); + // TODO(fees) should we have a MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_CALL + let mut public_data_reads : BoundedVec = BoundedVec::new(PublicDataRead::empty()); - for i in 0..MAX_PUBLIC_DATA_READS_PER_CALL { + for i in 0..MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX { let read_request: StorageRead = read_requests[i]; if !read_request.is_empty() { let public_data_read = PublicDataRead { @@ -187,6 +245,49 @@ fn propagate_valid_public_data_reads(public_call: PublicCallData, circuit_output circuit_outputs.end.public_data_reads.extend_from_bounded_vec(public_data_reads); } +fn propagate_valid_non_revertible_public_data_reads( + public_call: PublicCallData, + circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder +) { + let contract_address = public_call.call_stack_item.contract_address; + let read_requests = public_call.call_stack_item.public_inputs.contract_storage_reads; + + // TODO(fees) should we have a MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_CALL + let mut public_data_reads : BoundedVec = BoundedVec::new(PublicDataRead::empty()); + + for i in 0..MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX { + let read_request: StorageRead = read_requests[i]; + if !read_request.is_empty() { + let public_data_read = PublicDataRead { + leaf_slot: compute_public_data_tree_index(contract_address, read_request.storage_slot), + value: compute_public_data_tree_value(read_request.current_value) + }; + public_data_reads.push(public_data_read); + } + } + circuit_outputs.end_non_revertible.public_data_reads.extend_from_bounded_vec(public_data_reads); +} + +fn propagate_new_commitments_non_revertible( + public_call: PublicCallData, + circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder +) { + let public_call_public_inputs = public_call.call_stack_item.public_inputs; + + let new_commitments = public_call.call_stack_item.public_inputs.new_commitments; + let storage_contract_address = public_call_public_inputs.call_context.storage_contract_address; + + let mut siloed_new_commitments : BoundedVec = BoundedVec::new(SideEffect::empty()); + for i in 0..MAX_NEW_COMMITMENTS_PER_CALL { + let new_commitment = new_commitments[i].value; + if new_commitment != 0 { + let siloed_new_commitment = silo_commitment(storage_contract_address, new_commitment); + siloed_new_commitments.push(SideEffect { value: siloed_new_commitment, counter: new_commitments[i].counter }); + } + } + circuit_outputs.end_non_revertible.new_commitments.extend_from_bounded_vec(siloed_new_commitments); +} + fn propagate_new_commitments( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder @@ -207,6 +308,32 @@ fn propagate_new_commitments( circuit_outputs.end.new_commitments.extend_from_bounded_vec(siloed_new_commitments); } +fn propagate_new_nullifiers_non_revertible( + public_call: PublicCallData, + circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder +) { + let new_nullifiers = public_call.call_stack_item.public_inputs.new_nullifiers; + let storage_contract_address = public_call.call_stack_item.public_inputs.call_context.storage_contract_address; + + // Enhance commitments and nullifiers with domain separation whereby domain is the contract. + let mut siloed_new_nullifiers : BoundedVec = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); + for i in 0..MAX_NEW_NULLIFIERS_PER_CALL { + let new_nullifier = new_nullifiers[i].value; + if new_nullifier != 0 { + let siloed_new_nullifier = silo_nullifier(storage_contract_address, new_nullifier); + siloed_new_nullifiers.push( + SideEffectLinkedToNoteHash { + value: siloed_new_nullifier, + counter: new_nullifiers[i].counter, + note_hash: new_nullifiers[i].note_hash + } + ); + } + } + + circuit_outputs.end_non_revertible.new_nullifiers.extend_from_bounded_vec(siloed_new_nullifiers); +} + fn propagate_new_nullifiers( public_call: PublicCallData, circuit_outputs: &mut PublicKernelCircuitPublicInputsBuilder @@ -275,7 +402,7 @@ pub fn accumulate_unencrypted_logs( let current_unencrypted_logs_hash = public_call_public_inputs.unencrypted_logs_hash; public_inputs.end.unencrypted_logs_hash = accumulate_sha256([ - U128::from_integer(previous_unencrypted_logs_hash[0]), + U128::from_integer(previous_unencrypted_logs_hash[0]), U128::from_integer(previous_unencrypted_logs_hash[1]), U128::from_integer(current_unencrypted_logs_hash[0]), U128::from_integer(current_unencrypted_logs_hash[1]) diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/lib.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/lib.nr index 05c3572eedab..4373405f5812 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/lib.nr @@ -6,6 +6,8 @@ mod utils; mod public_kernel_setup; mod public_kernel_app_logic; +mod public_kernel_teardown; use public_kernel_setup::PublicKernelSetupCircuitPrivateInputs; use public_kernel_app_logic::PublicKernelAppLogicCircuitPrivateInputs; +use public_kernel_teardown::PublicKernelTeardownCircuitPrivateInputs; diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr index d338980b9121..47a1b941a940 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_app_logic.nr @@ -12,12 +12,11 @@ struct PublicKernelAppLogicCircuitPrivateInputs { impl PublicKernelAppLogicCircuitPrivateInputs { - // this is the only difference between the two PublicKernels' logic: fn validate_inputs(self) { - let previous_call_is_private = self.previous_kernel.public_inputs.is_private; - assert( - previous_call_is_private == false, "Previous kernel must be public when in this public kernel version" - ); + 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; + assert(needs_app_logic == true, "Cannot run unnecessary app logic circuit"); } fn public_kernel_app_logic(self) -> PublicKernelCircuitPublicInputs { @@ -54,16 +53,19 @@ mod tests { use crate::{ public_kernel_app_logic::PublicKernelAppLogicCircuitPrivateInputs, utils::{ - assert_eq_public_data_reads, assert_eq_public_data_update_requests, compute_public_data_reads, + assert_eq_call_requests, assert_eq_new_contracts, assert_eq_public_data_reads, + assert_eq_public_data_update_requests, compute_public_data_reads, compute_public_data_update_requests } }; use dep::types::{ abis::{ + new_contract_data::NewContractData, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, side_effect::{SideEffect, SideEffectLinkedToNoteHash} }, + address::{AztecAddress, EthAddress}, contract_class::ContractClassId, hash::{compute_l2_to_l1_hash, compute_logs_hash, silo_commitment, silo_nullifier}, messaging::l2_to_l1_message::L2ToL1Message, tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, @@ -78,7 +80,7 @@ mod tests { impl PublicKernelAppLogicCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new().is_public(); + let previous_kernel = PreviousKernelDataBuilder::new(true).is_public(); let public_call = PublicCallDataBuilder::new(); PublicKernelAppLogicCircuitPrivateInputsBuilder { previous_kernel, public_call } @@ -144,12 +146,22 @@ mod tests { // let _ = kernel.public_kernel_app_logic(); // } - #[test(should_fail_with="Previous kernel must be public when in this public kernel version")] + #[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(); + builder.previous_kernel = PreviousKernelDataBuilder::new(true); + let public_call = builder.public_call.finish(); - builder.failed(); + // the key difference in this test versus those that use builder.execute() + // is that we do not add a public call request to the previous kernel. + // 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 kernel = PublicKernelAppLogicCircuitPrivateInputs { previous_kernel, public_call }; + + let _ = kernel.public_kernel_app_logic(); } #[test] @@ -218,12 +230,12 @@ mod tests { let contract_address = builder.public_call.contract_address; // Setup 2 new nullifiers on the previous kernel. - builder.previous_kernel.append_new_nullifiers(2); + builder.previous_kernel.append_new_nullifiers_from_public(2); let previous = builder.previous_kernel.end.new_nullifiers.storage; // Setup 2 new commitments on the current public inputs. let current = [ - SideEffectLinkedToNoteHash { value: previous[2].value + 1, note_hash: 0, counter: 3 }, SideEffectLinkedToNoteHash { value: previous[2].value + 2, note_hash: 0, counter: 4 } + SideEffectLinkedToNoteHash { value: previous[1].value + 1, note_hash: 0, counter: 4 }, SideEffectLinkedToNoteHash { value: previous[1].value + 2, note_hash: 0, counter: 5 } ]; let siloed = current.map( @@ -232,8 +244,9 @@ mod tests { ); builder.public_call.public_inputs.new_nullifiers.extend_from_array(current); - // There are 3 nullifiers in the previous kernel. The first one is the tx nullifier. - let new_nullifiers = [previous[0], previous[1], previous[2], siloed[0], siloed[1]]; + // There are 2 revertible nullifiers in the previous kernel. + // The tx nullifier is part of the non-revertible nullifiers. + let new_nullifiers = [previous[0], previous[1], siloed[0], siloed[1]]; let public_inputs = builder.execute(); @@ -330,4 +343,76 @@ mod tests { builder.failed(); } + + #[test(should_fail_with="call stack storage address does not match expected contract address for delegate calls")] + fn public_kernel_circuit_fails_on_incorrect_storage_contract_in_delegate_call() { + let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new().is_delegate_call(); + + // Set the storage contract address to be the contract address. + builder.public_call.public_inputs.call_context.storage_contract_address = builder.public_call.contract_address; + + builder.failed(); + } + + #[test(should_fail_with = "call requests length does not match the expected length")] + fn incorrect_call_requests_length_fails() { + let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); + + builder.public_call.append_public_call_requests(2, false); + // Remove one call request. + let _ = builder.public_call.public_call_stack.pop(); + + builder.failed(); + } + + #[test] + fn only_valid_update_requests_should_be_propagated() { + let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); + builder.public_call.append_update_requests(1); + builder.public_call.append_empty_update_requests(1); + builder.public_call.append_update_requests(1); + let public_data_update_requests = builder.get_current_public_data_update_requests(); + + let public_inputs = builder.execute(); + + // Only the 2 valid reads should have been propagated. + let expected = [public_data_update_requests[0], public_data_update_requests[2]]; + assert_eq_public_data_update_requests(public_inputs.end.public_data_update_requests, expected); + } + + #[test] + fn circuit_outputs_should_be_correctly_populated_with_previous_private_kernel() { + let mut builder = PublicKernelAppLogicCircuitPrivateInputsBuilder::new(); + let new_contracts = [ + NewContractData { + contract_address: AztecAddress::from_field(123), + portal_contract_address: EthAddress::from_field(456), + contract_class_id: ContractClassId::from_field(78) + } + ]; + builder.previous_kernel.end.new_contracts.extend_from_array(new_contracts); + + builder.public_call.append_public_call_requests_for_regular_calls(2); + let storage = builder.public_call.public_call_stack.storage; + let public_call_stack = [storage[0], storage[1]]; + + builder.public_call.append_update_requests(2); + let storage = builder.get_current_public_data_update_requests(); + let update_requests = [storage[0], storage[1]]; + + builder.public_call.append_read_requests(3); + let storage = builder.get_current_public_data_reads(); + let read_requests = [storage[0], storage[1], storage[2]]; + + let public_inputs = builder.execute(); + + assert_eq_new_contracts(public_inputs.end.new_contracts, new_contracts); + 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, + update_requests + ); + assert_eq_public_data_reads(public_inputs.end.public_data_reads, read_requests); + } } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_setup.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_setup.nr index 50e991a414b6..7dfedb0d237c 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_setup.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_setup.nr @@ -31,10 +31,8 @@ impl PublicKernelSetupCircuitPrivateInputs { ); } - let previous_call_is_private = self.previous_kernel.public_inputs.is_private; - assert( - previous_call_is_private == true, "Previous kernel must be private when in this public kernel version" - ); + let needs_setup = self.previous_kernel.public_inputs.needs_setup; + assert(needs_setup == true, "Cannot run unnecessary setup circuit"); } fn public_kernel_setup(self) -> PublicKernelCircuitPublicInputs { @@ -51,10 +49,10 @@ impl PublicKernelSetupCircuitPrivateInputs { self.validate_inputs(); // Pops the item from the call stack and validates it against the current execution. - let call_request = public_inputs.end.public_call_stack.pop(); + let call_request = public_inputs.end_non_revertible.public_call_stack.pop(); common::validate_call_against_request(self.public_call, call_request); - common::update_public_end_values(self.public_call, &mut public_inputs); + common::update_public_end_non_revertible_values(self.public_call, &mut public_inputs); common::accumulate_unencrypted_logs( self.public_call, @@ -81,7 +79,7 @@ mod tests { call_request::CallRequest, function_selector::FunctionSelector, kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, new_contract_data::NewContractData, public_data_read::PublicDataRead, - public_data_update_request::PublicDataUpdateRequest + public_data_update_request::PublicDataUpdateRequest, public_call_data::PublicCallData }, address::{AztecAddress, EthAddress}, contract_class::ContractClassId, contrakt::storage_read::StorageRead, hash::compute_logs_hash, @@ -100,12 +98,26 @@ mod tests { impl PublicKernelSetupCircuitPrivateInputsBuilder { pub fn new() -> Self { - let previous_kernel = PreviousKernelDataBuilder::new(); + let previous_kernel = PreviousKernelDataBuilder::new(true); let public_call = PublicCallDataBuilder::new(); PublicKernelSetupCircuitPrivateInputsBuilder { previous_kernel, public_call } } + pub fn stub_teardown_call(&mut self) { + let teardown_call = PublicCallDataBuilder::new(); + 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); + } + + 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); + } + pub fn is_delegate_call(&mut self) -> Self { let _ = self.public_call.is_delegate_call(); *self @@ -130,14 +142,19 @@ mod tests { } pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { - let public_call = self.public_call.finish(); - // 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(hash, is_delegate_call); + // In order to run the setup circuit, we must have an enqueued public call for setup. + // In order to have an enqueued public call for setup, we must have an enqueued public call for teardown. + + // The teardown call is at the bottom of the call stack. + self.stub_teardown_call(); + + // 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 kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call }; + // Run the kernel on the setup call + let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: setup_call }; kernel.public_kernel_setup() } @@ -157,29 +174,30 @@ mod tests { builder.public_call.append_read_requests(1); builder.public_call.append_empty_read_requests(1); builder.public_call.append_read_requests(1); - let public_data_reads = builder.get_current_public_data_reads(); - - let public_inputs = builder.execute(); + let _ = builder.get_current_public_data_reads(); + let _ = builder.execute(); + // TODO(fees) we don't yet handle non-revertible reads // Only the 2 valid reads should have been propagated. - let expected = [public_data_reads[0], public_data_reads[2]]; - assert_eq_public_data_reads(public_inputs.end.public_data_reads, expected); + // let expected = [public_data_reads[0], public_data_reads[2]]; + // assert_eq_public_data_reads(public_inputs.end.public_data_reads, expected); } - #[test] - fn only_valid_update_requests_should_be_propagated() { - let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); - builder.public_call.append_update_requests(1); - builder.public_call.append_empty_update_requests(1); - builder.public_call.append_update_requests(1); - let public_data_update_requests = builder.get_current_public_data_update_requests(); + // TODO(fees) we don't yet handle non-revertible update requests + // #[test] + // fn only_valid_update_requests_should_be_propagated() { + // let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); + // builder.public_call.append_update_requests(1); + // builder.public_call.append_empty_update_requests(1); + // builder.public_call.append_update_requests(1); + // let public_data_update_requests = builder.get_current_public_data_update_requests(); - let public_inputs = builder.execute(); + // let public_inputs = builder.execute(); - // Only the 2 valid reads should have been propagated. - let expected = [public_data_update_requests[0], public_data_update_requests[2]]; - assert_eq_public_data_update_requests(public_inputs.end.public_data_update_requests, expected); - } + // // Only the 2 valid reads should have been propagated. + // let expected = [public_data_update_requests[0], public_data_update_requests[2]]; + // assert_eq_public_data_update_requests(public_inputs.end.public_data_update_requests, expected); + // } #[test(should_fail_with="Constructors cannot be public functions")] fn constructor_should_fail() { @@ -250,11 +268,12 @@ mod tests { #[test(should_fail_with="calculated public_kernel_inputs_hash does not match provided public_kernel_inputs_hash at the top of the call stack")] fn inconsistent_call_hash_should_fail() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); + builder.stub_teardown_call(); let public_call = builder.public_call.finish(); let hash = public_call.call_stack_item.hash(); // Tweak the call stack item hash. - builder.previous_kernel.push_public_call_request(hash + 1, false); + builder.previous_kernel.push_public_call_request_non_revertible(hash + 1, false); let previous_kernel = builder.previous_kernel.to_public_kernel_data(); let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call }; @@ -291,12 +310,14 @@ mod tests { #[test(should_fail_with="caller context cannot be empty for delegate calls")] fn empty_caller_context_for_delegate_calls_fails() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new().is_delegate_call(); + builder.stub_teardown_call(); + let public_call = builder.public_call.finish(); 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(hash, is_delegate_call); + builder.previous_kernel.push_public_call_request_non_revertible(hash, is_delegate_call); let previous_kernel = builder.previous_kernel.to_public_kernel_data(); let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call }; @@ -314,16 +335,6 @@ mod tests { builder.failed(); } - #[test(should_fail_with="call stack storage address does not match expected contract address for delegate calls")] - fn public_kernel_circuit_fails_on_incorrect_storage_contract_in_delegate_call() { - let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new().is_delegate_call(); - - // Set the storage contract address to be the contract address. - builder.public_call.public_inputs.call_context.storage_contract_address = builder.public_call.contract_address; - - builder.failed(); - } - #[test(should_fail_with="curent contract address must not match storage contract address for delegate calls")] fn previous_private_kernel_fails_if_incorrect_storage_contract_on_delegate_call() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new().is_delegate_call(); @@ -333,17 +344,6 @@ mod tests { builder.failed(); } - #[test(should_fail_with = "call requests length does not match the expected length")] - fn incorrect_call_requests_length_fails() { - let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); - - builder.public_call.append_public_call_requests(2, false); - // Remove one call request. - let _ = builder.public_call.public_call_stack.pop(); - - builder.failed(); - } - #[test(should_fail_with = "call stack hash does not match call request hash")] fn incorrect_call_request_hash_fails() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); @@ -403,7 +403,12 @@ mod tests { builder.public_call.append_public_call_requests_for_regular_calls(2); let storage = builder.public_call.public_call_stack.storage; - let public_call_stack = [storage[0], storage[1]]; + + builder.stub_teardown_call(); + let non_revertible_call_stack = [ + builder.previous_kernel.end_non_revertible.public_call_stack.get(0), + storage[0], storage[1] + ]; builder.public_call.append_update_requests(2); let storage = builder.get_current_public_data_update_requests(); @@ -413,16 +418,28 @@ mod tests { let storage = builder.get_current_public_data_reads(); let read_requests = [storage[0], storage[1], storage[2]]; - let public_inputs = builder.execute(); + // 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(); + + // Run the kernel on the setup call + let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: setup_call }; + + let public_inputs = kernel.public_kernel_setup(); assert_eq_new_contracts(public_inputs.end.new_contracts, new_contracts); 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, - update_requests + assert_eq_call_requests( + public_inputs.end_non_revertible.public_call_stack, + non_revertible_call_stack ); - assert_eq_public_data_reads(public_inputs.end.public_data_reads, read_requests); + // TODO(fees) we don't yet handle non-revertible update requests + // assert_eq_public_data_update_requests( + // public_inputs.end.public_data_update_requests, + // update_requests + // ); + // 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")] @@ -447,12 +464,21 @@ mod tests { // let _ = kernel.public_kernel_setup(); // } - #[test(should_fail_with="Previous kernel must be private when in this public kernel version")] - fn private_previous_kernel_non_private_previous_kernel_should_fail() { + #[test(should_fail_with="Cannot run unnecessary setup circuit")] + fn unnecessary_public_kernel_setup_with_teardown_should_fail() { let mut builder = PublicKernelSetupCircuitPrivateInputsBuilder::new(); - builder.previous_kernel.is_private = false; - builder.failed(); + // in this case, we only push a single call, which is interpreted as the teardown call + 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(); + + // Run the kernel on the setup call + let kernel = PublicKernelSetupCircuitPrivateInputs { previous_kernel, public_call: teardown_call }; + + let _ = kernel.public_kernel_setup(); } #[test(should_fail_with="No contract storage update requests are allowed for static calls")] diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_teardown.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_teardown.nr new file mode 100644 index 000000000000..56fd70fcf307 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-lib/src/public_kernel_teardown.nr @@ -0,0 +1,402 @@ +use crate::common; +use dep::types::abis::{ + kernel_circuit_public_inputs::{ + PrivateKernelTailCircuitPublicInputs, PublicKernelCircuitPublicInputs, + PublicKernelCircuitPublicInputsBuilder +}, + kernel_data::PublicKernelData, public_call_data::PublicCallData +}; +use dep::std::unsafe; + +struct PublicKernelTeardownCircuitPrivateInputs { + previous_kernel: PublicKernelData, + public_call: PublicCallData, +} + +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; + assert(needs_app_logic == false, "Cannot run teardown circuit before app logic circuit"); + let needs_teardown = self.previous_kernel.public_inputs.needs_teardown; + assert(needs_teardown == true, "Cannot run unnecessary teardown circuit"); + } + + fn public_kernel_teardown(self) -> PublicKernelCircuitPublicInputs { + // construct the circuit outputs + let mut public_inputs: PublicKernelCircuitPublicInputsBuilder = unsafe::zeroed(); + + // initialise the end state with our provided previous kernel state + common::initialize_end_values(self.previous_kernel, &mut public_inputs); + + // validate the inputs common to all invocation circumstances + common::validate_inputs(self.public_call); + + // validate the inputs unique to having a previous private kernel + self.validate_inputs(); + + // Pops the item from the call stack and validates it against the current execution. + let call_request = public_inputs.end_non_revertible.public_call_stack.pop(); + common::validate_call_against_request(self.public_call, call_request); + + common::update_public_end_non_revertible_values(self.public_call, &mut public_inputs); + + common::accumulate_unencrypted_logs( + self.public_call, + self.previous_kernel.public_inputs.end.unencrypted_logs_hash, + self.previous_kernel.public_inputs.end.unencrypted_log_preimages_length, + &mut public_inputs + ); + + public_inputs.to_inner() + } +} + +mod tests { + use crate::{ + public_kernel_teardown::PublicKernelTeardownCircuitPrivateInputs, + utils::{ + assert_eq_call_requests, assert_eq_new_contracts, assert_eq_public_data_reads, + assert_eq_public_data_update_requests, compute_public_data_reads, + compute_public_data_update_requests + } + }; + use dep::types::{ + abis::{ + call_request::CallRequest, function_selector::FunctionSelector, + kernel_circuit_public_inputs::PublicKernelCircuitPublicInputs, + new_contract_data::NewContractData, public_data_read::PublicDataRead, + public_data_update_request::PublicDataUpdateRequest + }, + address::{AztecAddress, EthAddress}, contract_class::ContractClassId, + contrakt::storage_read::StorageRead, hash::compute_logs_hash, + tests::{kernel_data_builder::PreviousKernelDataBuilder, public_call_data_builder::PublicCallDataBuilder}, + utils::{arrays::{array_eq, array_length}} + }; + use dep::types::constants::{ + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + }; + + struct PublicKernelTeardownCircuitPrivateInputsBuilder { + previous_kernel: PreviousKernelDataBuilder, + public_call: PublicCallDataBuilder, + } + + impl PublicKernelTeardownCircuitPrivateInputsBuilder { + pub fn new() -> Self { + let previous_kernel = PreviousKernelDataBuilder::new(true); + let public_call = PublicCallDataBuilder::new(); + + PublicKernelTeardownCircuitPrivateInputsBuilder { previous_kernel, public_call } + } + + pub fn is_delegate_call(&mut self) -> Self { + let _ = self.public_call.is_delegate_call(); + *self + } + + pub fn is_internal_call(&mut self) -> Self { + let _ = self.public_call.is_internal_call(); + self.previous_kernel.contract_address = self.public_call.contract_address; + *self + } + + pub fn get_current_public_data_reads(self) -> [PublicDataRead; MAX_PUBLIC_DATA_READS_PER_CALL] { + let read_requests = self.public_call.public_inputs.contract_storage_reads.storage; + compute_public_data_reads(self.public_call.contract_address, read_requests) + } + + pub fn get_current_public_data_update_requests(self) -> [PublicDataUpdateRequest; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL] { + compute_public_data_update_requests( + self.public_call.contract_address, + self.public_call.public_inputs.contract_storage_update_requests.storage + ) + } + + pub fn execute(&mut self) -> PublicKernelCircuitPublicInputs { + let public_call = self.public_call.finish(); + // 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(); + + let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; + + kernel.public_kernel_teardown() + } + + pub fn succeeded(&mut self) { + let _ = self.execute(); + } + + pub fn failed(&mut self) { + let _ = self.execute(); + } + } + + #[test(should_fail_with="Constructors cannot be public functions")] + fn constructor_should_fail() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.function_data.is_constructor = true; + + builder.failed(); + } + + #[test(should_fail_with="Contract deployment cannot be a public function")] + fn constructor_should_fail_2() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.public_inputs.call_context.is_contract_deployment = true; + + builder.failed(); + } + + #[test(should_fail_with="Bytecode hash cannot be zero")] + fn no_bytecode_hash_should_fail() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.bytecode_hash = 0; + + builder.failed(); + } + + #[test] + fn internal_call_succeeds() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_internal_call(); + builder.succeeded(); + } + + #[test(should_fail_with="msg_sender must be self for internal calls")] + fn invalid_is_internal() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_internal_call(); + + // Tweak the (storage) contract_address to be different to msg_sender. + let msg_sender = builder.public_call.public_inputs.call_context.msg_sender.to_field(); + builder.public_call.contract_address = AztecAddress::from_field(msg_sender + 1); + builder.public_call.public_inputs.call_context.storage_contract_address = AztecAddress::from_field(msg_sender + 1); + + builder.failed(); + } + + #[test(should_fail_with="Contract address cannot be zero")] + fn contract_address_must_be_valid() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.contract_address = AztecAddress::zero(); + + builder.failed(); + } + + #[test(should_fail_with="Function signature cannot be zero")] + fn function_selector_must_be_valid() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.function_data.selector = FunctionSelector::zero(); + + builder.failed(); + } + + #[test(should_fail_with="Cannot execute a private function with the public kernel circuit")] + fn private_call_should_fail() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.function_data.is_private = true; + + builder.failed(); + } + + #[test(should_fail_with="calculated public_kernel_inputs_hash does not match provided public_kernel_inputs_hash at the top of the call stack")] + fn inconsistent_call_hash_should_fail() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + let public_call = builder.public_call.finish(); + + 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(); + + let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; + + let _ = kernel.public_kernel_teardown(); + } + + #[test(should_fail_with="call stack msg_sender does not match caller contract address")] + fn incorrect_msg_sender_fails_for_regular_calls() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + // Set the msg_sender to a wrong value. + builder.public_call.public_inputs.call_context.msg_sender.inner += 1; + + builder.failed(); + } + + #[test(should_fail_with="call stack storage address does not match expected contract address")] + fn incorrect_storage_contract_address_fails_for_regular_calls() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + // Set the storage contract address to a wrong value. + builder.public_call.public_inputs.call_context.storage_contract_address.inner += 1; + + builder.failed(); + } + + #[test] + fn delegate_call_succeeds() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_delegate_call(); + builder.succeeded(); + } + + #[test(should_fail_with="caller context cannot be empty for delegate calls")] + fn empty_caller_context_for_delegate_calls_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_delegate_call(); + let public_call = builder.public_call.finish(); + + 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(); + + let kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; + + let _ = kernel.public_kernel_teardown(); + } + + #[test(should_fail_with="call stack msg_sender does not match expected msg_sender for delegate calls")] + fn incorrect_msg_sender_for_delegate_calls_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_delegate_call(); + + // Set the msg_sender to be the caller contract. + builder.public_call.public_inputs.call_context.msg_sender = builder.previous_kernel.contract_address; + + builder.failed(); + } + + #[test(should_fail_with="call stack storage address does not match expected contract address for delegate calls")] + fn public_kernel_circuit_fails_on_incorrect_storage_contract_in_delegate_call() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_delegate_call(); + + // Set the storage contract address to be the contract address. + builder.public_call.public_inputs.call_context.storage_contract_address = builder.public_call.contract_address; + + builder.failed(); + } + + #[test(should_fail_with="curent contract address must not match storage contract address for delegate calls")] + fn previous_private_kernel_fails_if_incorrect_storage_contract_on_delegate_call() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new().is_delegate_call(); + + builder.public_call.contract_address = builder.public_call.public_inputs.call_context.storage_contract_address; + + builder.failed(); + } + + #[test(should_fail_with = "call requests length does not match the expected length")] + fn incorrect_call_requests_length_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + builder.public_call.append_public_call_requests(2, false); + // Remove one call request. + let _ = builder.public_call.public_call_stack.pop(); + + builder.failed(); + } + + #[test(should_fail_with = "call stack hash does not match call request hash")] + fn incorrect_call_request_hash_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + builder.public_call.append_public_call_requests(2, false); + let mut call_request = builder.public_call.public_call_stack.pop(); + // Change the hash to be a different value. + call_request.hash += 1; + builder.public_call.public_call_stack.push(call_request); + + builder.failed(); + } + + #[test(should_fail_with = "invalid caller")] + fn incorrect_caller_address_for_call_request_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + builder.public_call.append_public_call_requests(1, false); + let mut call_request = builder.public_call.public_call_stack.pop(); + // Change the caller contract address to be a different value. + call_request.caller_contract_address.inner += 1; + builder.public_call.public_call_stack.push(call_request); + + builder.failed(); + } + + #[test(should_fail_with = "invalid caller")] + fn incorrect_caller_context_for_delegate_call_request_fails() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + builder.public_call.append_public_call_requests(1, true); + let mut call_request = builder.public_call.public_call_stack.pop(); + // Change the storage contract to be a different value. + call_request.caller_context.storage_contract_address.inner += 1; + builder.public_call.public_call_stack.push(call_request); + + builder.failed(); + } + + #[test] + fn public_kernel_circuit_teardown_with_no_setup_and_no_app_logic_succeeds() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.succeeded(); + } + + #[test(should_fail_with="Cannot run unnecessary teardown circuit")] + fn private_previous_kernel_non_empty_private_call_stack_should_fail() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + 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 kernel = PublicKernelTeardownCircuitPrivateInputs { previous_kernel, public_call }; + + let _ = kernel.public_kernel_teardown(); + } + + #[test(should_fail_with="No contract storage update requests are allowed for static calls")] + fn previous_private_kernel_fails_if_contract_storage_update_requests_on_static_call() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + builder.public_call.public_inputs.call_context.is_static_call = true; + builder.public_call.append_update_requests(1); + + builder.failed(); + } + + #[test] + fn logs_are_handled_as_expected() { + let mut builder = PublicKernelTeardownCircuitPrivateInputsBuilder::new(); + + // Logs for the current call stack. + let unencrypted_logs_hash = [26, 47]; + let unencrypted_log_preimages_length = 50; + builder.public_call.set_unencrypted_logs(unencrypted_logs_hash, unencrypted_log_preimages_length); + + // Logs for the previous call stack. + let prev_encrypted_logs_hash = [80, 429]; + let prev_encrypted_log_preimages_length = 13; + let prev_unencrypted_logs_hash = [956, 112]; + 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( + prev_unencrypted_logs_hash, + prev_unencrypted_log_preimages_length + ); + + let public_inputs = builder.execute(); + + assert_eq(public_inputs.end.encrypted_log_preimages_length, prev_encrypted_log_preimages_length); + assert_eq( + public_inputs.end.unencrypted_log_preimages_length, unencrypted_log_preimages_length + prev_unencrypted_log_preimages_length + ); + + assert_eq(public_inputs.end.encrypted_logs_hash, prev_encrypted_logs_hash); + + let expected_unencrypted_logs_hash = compute_logs_hash(prev_unencrypted_logs_hash, unencrypted_logs_hash); + assert_eq(public_inputs.end.unencrypted_logs_hash, expected_unencrypted_logs_hash); + } +} diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/Nargo.toml b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/Nargo.toml new file mode 100644 index 000000000000..698657b684db --- /dev/null +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "public_kernel_teardown_simulated" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +types = { path = "../types" } +public_kernel_lib = { path = "../public-kernel-lib" } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/src/main.nr new file mode 100644 index 000000000000..f37b6755f924 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown-simulated/src/main.nr @@ -0,0 +1,6 @@ +use dep::public_kernel_lib::PublicKernelTeardownCircuitPrivateInputs; +use dep::types::PublicKernelCircuitPublicInputs; + +unconstrained fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { + input.public_kernel_teardown() +} diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/Nargo.toml b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/Nargo.toml new file mode 100644 index 000000000000..a481c24ff38d --- /dev/null +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/Nargo.toml @@ -0,0 +1,9 @@ +[package] +name = "public_kernel_teardown" +type = "bin" +authors = [""] +compiler_version = ">=0.18.0" + +[dependencies] +types = { path = "../types" } +public_kernel_lib = { path = "../public-kernel-lib" } diff --git a/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/src/main.nr b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/src/main.nr new file mode 100644 index 000000000000..2b21ec6847d3 --- /dev/null +++ b/noir-projects/noir-protocol-circuits/src/crates/public-kernel-teardown/src/main.nr @@ -0,0 +1,6 @@ +use dep::public_kernel_lib::PublicKernelTeardownCircuitPrivateInputs; +use dep::types::PublicKernelCircuitPublicInputs; + +fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { + input.public_kernel_teardown() +} diff --git a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 1e88f81ca521..250fca454d2c 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -15,7 +15,8 @@ use dep::types::{ }, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_update_request::PublicDataUpdateRequest, public_data_read::PublicDataRead, kernel_data::PublicKernelData, - side_effect::{SideEffect, SideEffectLinkedToNoteHash} + side_effect::{SideEffect, SideEffectLinkedToNoteHash}, + combined_accumulated_data::CombinedAccumulatedData }, constants::{ NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, @@ -24,7 +25,11 @@ use dep::types::{ MAX_NEW_COMMITMENTS_PER_TX, 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 + 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_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX }, mocked::{AggregationObject, Proof}, partial_state_reference::PartialStateReference, public_data_tree_leaf::PublicDataTreeLeaf, @@ -48,7 +53,7 @@ struct BaseRollupInputs { public_data_reads_witnesses: [PublicDataMembershipWitness; MAX_PUBLIC_DATA_READS_PER_TX], archive_root_membership_witness: ArchiveRootMembershipWitness, - + constants: ConstantRollupData, } @@ -66,12 +71,19 @@ impl BaseRollupInputs { self.kernel_data.public_inputs.constants.tx_context.version == self.constants.global_variables.version, "kernel version does not match the rollup version" ); + + // recombine the accumulated data + let combined = CombinedAccumulatedData::recombine( + self.kernel_data.public_inputs.end_non_revertible, + self.kernel_data.public_inputs.end + ); + // First we compute the contract tree leaves - let contract_leaves = self.calculate_contract_leaves(); + let contract_leaves = self.calculate_contract_leaves(combined); let contracts_tree_subroot = self.calculate_contract_subtree_root(contract_leaves); - let commitments_tree_subroot = self.calculate_commitments_subtree(); + let commitments_tree_subroot = self.calculate_commitments_subtree(combined); let empty_commitments_subtree_root = calculate_empty_tree_root(NOTE_HASH_SUBTREE_HEIGHT); @@ -94,13 +106,13 @@ impl BaseRollupInputs { ); // Insert nullifiers: - let end_nullifier_tree_snapshot = self.check_nullifier_tree_non_membership_and_insert_to_tree(); + let end_nullifier_tree_snapshot = self.check_nullifier_tree_non_membership_and_insert_to_tree(combined); // Validate public public data reads and public data update requests, and update public data tree - let end_public_data_tree_snapshot = self.validate_and_process_public_state(); + let end_public_data_tree_snapshot = self.validate_and_process_public_state(combined); // Calculate the overall calldata hash - let calldata_hash = BaseRollupInputs::components_compute_kernel_calldata_hash(self.kernel_data); + let calldata_hash = BaseRollupInputs::components_compute_kernel_calldata_hash(combined); // Perform membership checks that the notes provided exist within the historical trees data self.perform_archive_membership_checks(); @@ -123,9 +135,9 @@ impl BaseRollupInputs { } } - fn calculate_contract_leaves(self) -> [Field; MAX_NEW_CONTRACTS_PER_TX] { + fn calculate_contract_leaves(self, combined: CombinedAccumulatedData) -> [Field; MAX_NEW_CONTRACTS_PER_TX] { let mut contract_leaves = [0; MAX_NEW_CONTRACTS_PER_TX]; - let new_contracts = self.kernel_data.public_inputs.end.new_contracts; + let new_contracts = combined.new_contracts; // loop over the new contracts for i in 0..new_contracts.len() { @@ -152,14 +164,14 @@ impl BaseRollupInputs { // TODO(Kev): This should say calculate_commitments_subtree_root // Cpp code says calculate_commitments_subtree, so I'm leaving it as is for now - fn calculate_commitments_subtree(self) -> Field { - calculate_subtree(self.kernel_data.public_inputs.end.new_commitments.map(|c: SideEffect| c.value)) + fn calculate_commitments_subtree(self, combined: CombinedAccumulatedData) -> Field { + calculate_subtree(combined.new_commitments.map(|c: SideEffect| c.value)) } - fn check_nullifier_tree_non_membership_and_insert_to_tree(self) -> AppendOnlyTreeSnapshot { + fn check_nullifier_tree_non_membership_and_insert_to_tree(self, combined: CombinedAccumulatedData) -> AppendOnlyTreeSnapshot { crate::indexed_tree::batch_insert( self.start.nullifier_tree, - self.kernel_data.public_inputs.end.new_nullifiers.map(|nullifier: SideEffectLinkedToNoteHash| nullifier.value), + combined.new_nullifiers.map(|nullifier: SideEffectLinkedToNoteHash| nullifier.value), self.state_diff_hints.sorted_nullifiers, self.state_diff_hints.sorted_nullifier_indexes, self.state_diff_hints.nullifier_subtree_sibling_path, @@ -180,7 +192,7 @@ impl BaseRollupInputs { let is_next_greater_than = full_field_less_than(nullifier, low_leaf.next_nullifier); (!low_leaf.is_empty()) & is_less_than_nullifier & ( - is_next_greater_than | + is_next_greater_than | ((low_leaf.next_index == 0) & (low_leaf.next_nullifier == 0)) ) }, @@ -188,7 +200,7 @@ impl BaseRollupInputs { NullifierLeafPreimage{ nullifier : low_leaf.nullifier, next_nullifier : nullifier, - next_index : nullifier_index, + next_index : nullifier_index, } }, |nullifier: Field, low_leaf: NullifierLeafPreimage| { // Build insertion leaf @@ -207,7 +219,7 @@ impl BaseRollupInputs { calculate_subtree(leaves.map(|leaf:NullifierLeafPreimage| leaf.hash())) } - fn validate_and_process_public_state(self) -> AppendOnlyTreeSnapshot { + fn validate_and_process_public_state(self, combined: CombinedAccumulatedData) -> AppendOnlyTreeSnapshot { // TODO(#2521) - data read validation should happen against the current state of the tx and not the start state. // Blocks all interesting usecases that read and write to the same public state in the same tx. // https://aztecprotocol.slack.com/archives/C02M7VC7TN0/p1695809629015719?thread_ts=1695653252.007339&cid=C02M7VC7TN0 @@ -221,7 +233,7 @@ impl BaseRollupInputs { let end_public_data_tree_snapshot = insert_public_data_update_requests( self.start.public_data_tree, - self.kernel_data.public_inputs.end.public_data_update_requests.map( + combined.public_data_update_requests.map( |request: PublicDataUpdateRequest| { PublicDataTreeLeaf { slot: request.leaf_slot, @@ -242,9 +254,9 @@ impl BaseRollupInputs { // Computes the calldata hash for a base rollup // TODO(Kev): move this into components module // TODO(Alvaro): This is too slow for brillig without the array optimization - fn components_compute_kernel_calldata_hash(kernel_data: PublicKernelData) -> [Field; NUM_FIELDS_PER_SHA256] { + fn components_compute_kernel_calldata_hash(combined: CombinedAccumulatedData) -> [Field; NUM_FIELDS_PER_SHA256] { // Compute calldata hashes - // Consist of + // Consist of // MAX_NEW_COMMITMENTS_PER_TX fields for commitments // MAX_NEW_NULLIFIERS_PER_TX fields for nullifiers // 16 public data update requests -> 32 fields @@ -254,12 +266,12 @@ impl BaseRollupInputs { // 1 unencrypted logs hashes -> 2 fields --> 2 sha256 hashes --> 64 bytes let mut calldata_hash_inputs = [0; CALLDATA_HASH_INPUT_SIZE]; - let new_commitments = kernel_data.public_inputs.end.new_commitments; - let new_nullifiers = kernel_data.public_inputs.end.new_nullifiers; - let public_data_update_requests = kernel_data.public_inputs.end.public_data_update_requests; - let newL2ToL1msgs = kernel_data.public_inputs.end.new_l2_to_l1_msgs; - let encryptedLogsHash = kernel_data.public_inputs.end.encrypted_logs_hash; - let unencryptedLogsHash = kernel_data.public_inputs.end.unencrypted_logs_hash; + let new_commitments = combined.new_commitments; + let new_nullifiers = combined.new_nullifiers; + let public_data_update_requests = combined.public_data_update_requests; + let newL2ToL1msgs = combined.new_l2_to_l1_msgs; + let encryptedLogsHash = combined.encrypted_logs_hash; + let unencryptedLogsHash = combined.unencrypted_logs_hash; let mut offset = 0; @@ -286,12 +298,12 @@ impl BaseRollupInputs { } offset += MAX_NEW_L2_TO_L1_MSGS_PER_TX; - let contract_leaf = kernel_data.public_inputs.end.new_contracts[0]; + let contract_leaf = combined.new_contracts[0]; calldata_hash_inputs[offset] = contract_leaf.hash(); offset += MAX_NEW_CONTRACTS_PER_TX; - let new_contracts = kernel_data.public_inputs.end.new_contracts; + let new_contracts = combined.new_contracts; calldata_hash_inputs[offset] = new_contracts[0].contract_address.to_field(); // TODO(#3938): make portal address 20 bytes here when updating the hashing calldata_hash_inputs[offset + 1] = new_contracts[0].portal_contract_address.to_field(); @@ -362,7 +374,7 @@ impl BaseRollupInputs { fn verify_kernel_proof(_proof: Proof) -> bool { // TODO: Just return true as we are mocking out the proof verification // and aggregation. - // TODO(Kev): It may make sense to move all of these methods into a + // TODO(Kev): It may make sense to move all of these methods into a // separate module. true } @@ -401,7 +413,7 @@ fn insert_public_data_update_requests( let is_less_than_slot = full_field_less_than(low_preimage.slot, write.slot); let is_next_greater_than = full_field_less_than(write.slot, low_preimage.next_slot); let is_in_range = is_less_than_slot & ( - is_next_greater_than | + is_next_greater_than | ((low_preimage.next_index == 0) & (low_preimage.next_slot == 0))); (!is_low_empty) & (is_update | is_in_range) @@ -413,14 +425,14 @@ fn insert_public_data_update_requests( slot : low_preimage.slot, value: write.value, next_slot : low_preimage.next_slot, - next_index : low_preimage.next_index, + next_index : low_preimage.next_index, } } else { PublicDataTreeLeafPreimage{ slot : low_preimage.slot, value: low_preimage.value, next_slot : write.slot, - next_index : write_index, + next_index : write_index, } } }, @@ -556,7 +568,8 @@ mod tests { membership_witness::{ArchiveRootMembershipWitness, NullifierMembershipWitness, PublicDataMembershipWitness}, new_contract_data::NewContractData, nullifier_leaf_preimage::NullifierLeafPreimage, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, - kernel_data::PublicKernelData, side_effect::SideEffect + kernel_data::PublicKernelData, side_effect::SideEffect, + combined_accumulated_data::CombinedAccumulatedData }, address::{AztecAddress, EthAddress}, constants::{ @@ -706,8 +719,8 @@ mod tests { inputs.constants.global_variables.chain_id = 1; inputs.constants.global_variables.version = 0; - let mut builder = PreviousKernelDataBuilder::new(); - let _nullifier = builder.end.new_nullifiers.pop(); + 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(); @@ -788,6 +801,11 @@ mod tests { fn build_inputs(mut self) -> BaseRollupInputs { let mut kernel_data = self.kernel_data.to_public_kernel_data(); + let combined = CombinedAccumulatedData::recombine( + kernel_data.public_inputs.end_non_revertible, + kernel_data.public_inputs.end + ); + let start_note_hash_tree = NonEmptyMerkleTree::new( self.pre_existing_notes, [0; NOTE_HASH_TREE_HEIGHT], @@ -853,7 +871,7 @@ mod tests { }; let ( - nullifier_predecessor_preimages, + nullifier_predecessor_preimages, nullifier_predecessor_membership_witnesses, sorted_nullifiers, sorted_nullifier_indexes diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/combined_accumulated_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/combined_accumulated_data.nr index e60d27afdc83..870b4b325056 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/combined_accumulated_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/combined_accumulated_data.nr @@ -11,10 +11,18 @@ use crate::constants::{ 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_CONTRACTS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, NUM_FIELDS_PER_SHA256, - MAX_NEW_COMMITMENTS_PER_TX_META, MAX_NEW_NULLIFIERS_PER_TX_META, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_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 CombinedAccumulatedData { read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], @@ -41,12 +49,50 @@ struct CombinedAccumulatedData { public_data_reads: [PublicDataRead; MAX_PUBLIC_DATA_READS_PER_TX], } -struct FinalAccumulatedData { - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], +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 { + CombinedAccumulatedData { + read_requests: revertible.read_requests, + nullifier_key_validation_requests: revertible.nullifier_key_validation_requests, + new_commitments: array_concat(non_revertible.new_commitments, revertible.new_commitments), + 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_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, + new_contracts: revertible.new_contracts, + public_data_update_requests: array_concat( + non_revertible.public_data_update_requests, + revertible.public_data_update_requests + ), + public_data_reads: array_concat( + non_revertible.public_data_reads, + revertible.public_data_reads + ) + } + } +} + +struct PrivateAccumulatedRevertibleData { + new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_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_PUBLIC_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; NUM_FIELDS_PER_SHA256], @@ -60,10 +106,175 @@ struct FinalAccumulatedData { new_contracts: [NewContractData; MAX_NEW_CONTRACTS_PER_TX], } -struct AccumulatedNonRevertibleData { - new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX_META], - new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX_META], - public_call_stack: [CallRequest; MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META], +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() + } +} + +struct PublicAccumulatedRevertibleData { + read_requests: [SideEffect; MAX_READ_REQUESTS_PER_TX], + nullifier_key_validation_requests: [NullifierKeyValidationRequestContext; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX], + + new_commitments: [SideEffect; MAX_REVERTIBLE_COMMITMENTS_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; NUM_FIELDS_PER_SHA256], + unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], + + // 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, + + new_contracts: [NewContractData; MAX_NEW_CONTRACTS_PER_TX], + + public_data_update_requests: [PublicDataUpdateRequest; MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX], + public_data_reads: [PublicDataRead; MAX_REVERTIBLE_PUBLIC_DATA_READS_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() + } +} + +struct AccumulatedRevertibleDataBuilder { + read_requests: BoundedVec, + nullifier_key_validation_requests: BoundedVec, + + new_commitments: BoundedVec, + new_nullifiers: BoundedVec, + + private_call_stack: BoundedVec, + public_call_stack: BoundedVec, + new_l2_to_l1_msgs: BoundedVec, + + encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], + unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], + + // 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, + + new_contracts: BoundedVec, + + public_data_update_requests: BoundedVec, + public_data_reads: BoundedVec, +} + +impl AccumulatedRevertibleDataBuilder { + pub fn to_private(self) -> PrivateAccumulatedRevertibleData { + PrivateAccumulatedRevertibleData { + new_commitments: self.new_commitments.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, + new_contracts: self.new_contracts.storage + } + } + + pub fn to_public(self) -> PublicAccumulatedRevertibleData { + PublicAccumulatedRevertibleData { + read_requests: self.read_requests.storage, + new_commitments: self.new_commitments.storage, + nullifier_key_validation_requests: self.nullifier_key_validation_requests.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, + new_contracts: self.new_contracts.storage, + public_data_update_requests: self.public_data_update_requests.storage, + public_data_reads: self.public_data_reads.storage + } + } +} + +struct PrivateAccumulatedNonRevertibleData { + new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_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() + } +} + +struct PublicAccumulatedNonRevertibleData { + new_commitments: [SideEffect; MAX_NON_REVERTIBLE_COMMITMENTS_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], + public_data_reads: [PublicDataRead; MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_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() + } +} + +struct AccumulatedNonRevertibleDataBuilder { + new_commitments: BoundedVec, + new_nullifiers: BoundedVec, + public_call_stack: BoundedVec, + public_data_update_requests: BoundedVec, + public_data_reads: BoundedVec, +} + +impl AccumulatedNonRevertibleDataBuilder { + pub fn to_private(self) -> PrivateAccumulatedNonRevertibleData { + PrivateAccumulatedNonRevertibleData { + new_commitments: self.new_commitments.storage, + new_nullifiers: self.new_nullifiers.storage, + public_call_stack: self.public_call_stack.storage + } + } + pub fn to_public(self) -> PublicAccumulatedNonRevertibleData { + PublicAccumulatedNonRevertibleData { + new_commitments: self.new_commitments.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, + public_data_reads: self.public_data_reads.storage + } + } } struct CombinedAccumulatedDataBuilder { @@ -93,6 +304,43 @@ struct CombinedAccumulatedDataBuilder { } impl CombinedAccumulatedDataBuilder { + pub fn recombine( + non_revertible: PublicAccumulatedNonRevertibleData, + revertible: PublicAccumulatedRevertibleData + ) -> CombinedAccumulatedDataBuilder { + CombinedAccumulatedDataBuilder { + read_requests: array_to_bounded_vec(revertible.read_requests), + nullifier_key_validation_requests: array_to_bounded_vec(revertible.nullifier_key_validation_requests), + new_commitments: array_to_bounded_vec(array_concat(non_revertible.new_commitments, revertible.new_commitments)), + 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, + new_contracts: array_to_bounded_vec(revertible.new_contracts), + public_data_update_requests: array_to_bounded_vec( + array_concat( + non_revertible.public_data_update_requests, + revertible.public_data_update_requests + ) + ), + public_data_reads: array_to_bounded_vec( + array_concat( + non_revertible.public_data_reads, + revertible.public_data_reads + ) + ) + } + } + pub fn finish(self) -> CombinedAccumulatedData { CombinedAccumulatedData { read_requests: self.read_requests.storage, @@ -112,21 +360,12 @@ impl CombinedAccumulatedDataBuilder { } } - pub fn to_final(self) -> FinalAccumulatedData { - assert_eq(self.read_requests.len, 0, "Final accumulated data: read requests not empty"); - assert_eq( - self.nullifier_key_validation_requests.len, 0, "Final accumulated data: nullifier key validation requests not empty" - ); - assert_eq( - self.public_data_update_requests.len, 0, "Final accumulated data: public data update requests not empty" - ); - assert_eq(self.public_data_reads.len, 0, "Final accumulated data: public data reads not empty"); - - FinalAccumulatedData { - new_commitments: self.new_commitments.storage, - new_nullifiers: self.new_nullifiers.storage, + pub fn to_private_accumulated_revertible_data(self) -> PrivateAccumulatedRevertibleData { + PrivateAccumulatedRevertibleData { + new_commitments: array_cp(self.new_commitments.storage), + new_nullifiers: array_cp(self.new_nullifiers.storage), private_call_stack: self.private_call_stack.storage, - public_call_stack: self.public_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, @@ -135,5 +374,159 @@ impl CombinedAccumulatedDataBuilder { new_contracts: self.new_contracts.storage } } + + pub fn to_public_accumulated_revertible_data(self) -> PublicAccumulatedRevertibleData { + PublicAccumulatedRevertibleData { + read_requests: self.read_requests.storage, + nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, + new_commitments: array_cp(self.new_commitments.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, + new_contracts: self.new_contracts.storage, + public_data_update_requests: array_cp(self.public_data_update_requests.storage), + public_data_reads: array_cp(self.public_data_reads.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_COMMITMENTS_PER_TX { + let commitment = self.new_commitments.storage[i]; + // TODO(fees) we shouldn't need to check is_empty here, + // but we do because new_commitments is bounded to MAX_REVERTIBLE_COMMITMENTS_PER_TX + if !is_empty(commitment) { + if commitment.counter < min_revertible_side_effect_counter { + non_revertible_builder.new_commitments.push(commitment); + } else { + revertible_builder.new_commitments.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; + revertible_builder.new_contracts = self.new_contracts; + + (non_revertible_builder.to_private(), revertible_builder.to_private()) + } } +mod tests { + use crate::abis::{ + combined_accumulated_data::CombinedAccumulatedDataBuilder, + call_request::{CallRequest, CallerContext}, new_contract_data::NewContractData, + nullifier_key_validation_request::NullifierKeyValidationRequestContext, + public_data_read::PublicDataRead, 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_commitments.extend_from_array(non_revertible_commitments); + builder.new_commitments.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_commitments, 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_commitments, 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/src/crates/types/src/abis/kernel_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_circuit_public_inputs.nr index 9996c28a33bb..59764ef6be1f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_circuit_public_inputs.nr @@ -1,39 +1,65 @@ use crate::abis::{ combined_accumulated_data::{ - CombinedAccumulatedData, FinalAccumulatedData, AccumulatedNonRevertibleData, - CombinedAccumulatedDataBuilder + CombinedAccumulatedData, PrivateAccumulatedRevertibleData, PrivateAccumulatedNonRevertibleData, + CombinedAccumulatedDataBuilder, PublicAccumulatedNonRevertibleData, PublicAccumulatedRevertibleData, + AccumulatedNonRevertibleDataBuilder, AccumulatedRevertibleDataBuilder }, combined_constant_data::CombinedConstantData }; +use dep::std::{unsafe}; +use crate::constants::{MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX}; + use crate::mocked::AggregationObject; struct PrivateKernelInnerCircuitPublicInputs { aggregation_object: AggregationObject, - max_non_revertible_side_effect_counter: u32, + min_revertible_side_effect_counter: u32, end: CombinedAccumulatedData, constants: CombinedConstantData, - is_private: bool, + is_private: bool, // TODO can we remove this? } struct PrivateKernelTailCircuitPublicInputs { aggregation_object: AggregationObject, - end_non_revertible: AccumulatedNonRevertibleData, - end: FinalAccumulatedData, + end_non_revertible: PrivateAccumulatedNonRevertibleData, + end: PrivateAccumulatedRevertibleData, constants: CombinedConstantData, - is_private: bool, + needs_setup: bool, + needs_app_logic: bool, + needs_teardown: bool, } struct PublicKernelCircuitPublicInputs { aggregation_object: AggregationObject, - end_non_revertible: AccumulatedNonRevertibleData, + end_non_revertible: PublicAccumulatedNonRevertibleData, + end: PublicAccumulatedRevertibleData, + constants: CombinedConstantData, + needs_setup: bool, + needs_app_logic: bool, + needs_teardown: bool, +} + +struct RollupKernelCircuitPublicInputs { + aggregation_object: AggregationObject, end: CombinedAccumulatedData, constants: CombinedConstantData, - is_private: bool, +} + +struct RollupKernelCircuitPublicInputsBuilder { + aggregation_object: AggregationObject, + end: CombinedAccumulatedDataBuilder, + constants: CombinedConstantData, +} + +impl RollupKernelCircuitPublicInputsBuilder { + pub fn finish(self) -> RollupKernelCircuitPublicInputs { + RollupKernelCircuitPublicInputs { aggregation_object: self.aggregation_object, end: self.end.finish(), constants: self.constants } + } } struct PrivateKernelCircuitPublicInputsBuilder { aggregation_object: AggregationObject, - max_non_revertible_side_effect_counter: u32, + min_revertible_side_effect_counter: u32, end: CombinedAccumulatedDataBuilder, constants: CombinedConstantData, is_private: bool, @@ -43,44 +69,46 @@ impl PrivateKernelCircuitPublicInputsBuilder { pub fn to_inner(self) -> PrivateKernelInnerCircuitPublicInputs { PrivateKernelInnerCircuitPublicInputs { aggregation_object: self.aggregation_object, - max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter, + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, end: self.end.finish(), constants: self.constants, is_private: self.is_private } } - pub fn to_tail( - self, - end_non_revertible: AccumulatedNonRevertibleData - ) -> PrivateKernelTailCircuitPublicInputs { + pub fn to_tail(self) -> PrivateKernelTailCircuitPublicInputs { + let (end_non_revertible, end) = self.end.split(self.min_revertible_side_effect_counter); PrivateKernelTailCircuitPublicInputs { aggregation_object: self.aggregation_object, end_non_revertible, - end: self.end.to_final(), + end, constants: self.constants, - is_private: self.is_private + needs_setup: end_non_revertible.needs_setup(), + needs_app_logic: end.needs_app_logic(), + needs_teardown: end_non_revertible.needs_teardown() } } } struct PublicKernelCircuitPublicInputsBuilder { aggregation_object: AggregationObject, - end_non_revertible: AccumulatedNonRevertibleData, - end: CombinedAccumulatedDataBuilder, + end_non_revertible: AccumulatedNonRevertibleDataBuilder, + end: AccumulatedRevertibleDataBuilder, constants: CombinedConstantData, - is_private: bool, } impl PublicKernelCircuitPublicInputsBuilder { pub fn to_inner(self) -> PublicKernelCircuitPublicInputs { + let end_non_revertible = self.end_non_revertible.to_public(); + let end = self.end.to_public(); PublicKernelCircuitPublicInputs { aggregation_object: self.aggregation_object, - end_non_revertible: self.end_non_revertible, - end: self.end.finish(), + end_non_revertible, + end, constants: self.constants, - is_private: self.is_private + needs_setup: end_non_revertible.needs_setup(), + needs_app_logic: end.needs_app_logic(), + needs_teardown: end_non_revertible.needs_teardown() } } } - diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_data.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_data.nr index 216f7f141c16..aa562c45ec9d 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_data.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/kernel_data.nr @@ -2,7 +2,7 @@ use crate::mocked::{Proof, VerificationKey}; use crate::constants::VK_TREE_HEIGHT; use crate::abis::kernel_circuit_public_inputs::{ PrivateKernelInnerCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, - PublicKernelCircuitPublicInputs + PublicKernelCircuitPublicInputs, RollupKernelCircuitPublicInputs }; struct PrivateKernelInnerData { @@ -42,3 +42,4 @@ struct PublicKernelData { vk_index : u32, vk_path : [Field; VK_TREE_HEIGHT], } + diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 53d6216ba697..692e4e30b2f1 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -21,7 +21,7 @@ struct PrivateCircuitPublicInputs { args_hash: Field, return_values: [Field; RETURN_VALUES_LENGTH], - max_non_revertible_side_effect_counter: u32, + min_revertible_side_effect_counter: u32, read_requests: [SideEffect; MAX_READ_REQUESTS_PER_CALL], nullifier_key_validation_requests: [NullifierKeyValidationRequest; MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL], @@ -84,7 +84,7 @@ impl Serialize for PrivateCircuitPublicInp fields.push(self.args_hash); fields.extend_from_array(self.return_values); - fields.push(self.max_non_revertible_side_effect_counter as Field); + fields.push(self.min_revertible_side_effect_counter as Field); for i in 0..MAX_READ_REQUESTS_PER_CALL{ fields.extend_from_array(self.read_requests[i].serialize()); @@ -127,7 +127,7 @@ impl Deserialize for PrivateCircuitPublicI call_context: reader.read_struct(CallContext::deserialize), args_hash: reader.read(), return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), - max_non_revertible_side_effect_counter: reader.read() as u32, + min_revertible_side_effect_counter: reader.read() as u32, read_requests: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_READ_REQUESTS_PER_CALL]), nullifier_key_validation_requests: reader.read_struct_array(NullifierKeyValidationRequest::deserialize, [NullifierKeyValidationRequest::empty(); MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL]), new_commitments: reader.read_struct_array(SideEffect::deserialize, [SideEffect::empty(); MAX_NEW_COMMITMENTS_PER_CALL]), diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr index 6d81837f76d6..a0cc48e627e9 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/constants.nr @@ -35,21 +35,33 @@ global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL: Field = 1; // "PER TRANSACTION" CONSTANTS global MAX_NEW_COMMITMENTS_PER_TX: Field = 64; +global MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX: Field = 8; +global MAX_REVERTIBLE_COMMITMENTS_PER_TX: Field = 56; + global MAX_NEW_NULLIFIERS_PER_TX: Field = 64; +global MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX: Field = 8; +global MAX_REVERTIBLE_NULLIFIERS_PER_TX: Field = 56; + global MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX: Field = 8; + global MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 8; -global MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2; +global MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 3; +global MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX: Field = 5; + global MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 16; +global MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 1; +global MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX: Field = 15; + global MAX_PUBLIC_DATA_READS_PER_TX: Field = 16; +global MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX: Field = 1; +global MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX: Field = 15; + +global MAX_NEW_L2_TO_L1_MSGS_PER_TX: Field = 2; global MAX_NEW_CONTRACTS_PER_TX: Field = 1; global MAX_READ_REQUESTS_PER_TX: Field = 128; global MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX: Field = 4; global NUM_ENCRYPTED_LOGS_HASHES_PER_TX: Field = 1; global NUM_UNENCRYPTED_LOGS_HASHES_PER_TX: Field = 1; - -global MAX_NEW_COMMITMENTS_PER_TX_META: Field = 8; -global MAX_NEW_NULLIFIERS_PER_TX_META: Field = 8; -global MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META: Field = 2; // docs:end:constants // ROLLUP CONTRACT CONSTANTS - constants used only in l1-contracts diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/lib.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/lib.nr index ea426fd768eb..6ed253e48101 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/lib.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/lib.nr @@ -29,5 +29,5 @@ mod public_data_tree_leaf_preimage; use abis::kernel_circuit_public_inputs::{ PrivateKernelInnerCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, - PublicKernelCircuitPublicInputs + PublicKernelCircuitPublicInputs, RollupKernelCircuitPublicInputs }; diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr index d99c83ba9d4b..eb78404ee860 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/kernel_data_builder.nr @@ -2,10 +2,10 @@ use crate::{ abis::{ call_context::CallContext, call_request::{CallerContext, CallRequest}, combined_constant_data::CombinedConstantData, - combined_accumulated_data::{CombinedAccumulatedDataBuilder, AccumulatedNonRevertibleData}, + combined_accumulated_data::{CombinedAccumulatedDataBuilder, AccumulatedNonRevertibleDataBuilder, AccumulatedRevertibleDataBuilder}, kernel_circuit_public_inputs::{ PrivateKernelInnerCircuitPublicInputs, PrivateKernelTailCircuitPublicInputs, - PublicKernelCircuitPublicInputs + PublicKernelCircuitPublicInputs, RollupKernelCircuitPublicInputs }, kernel_data::{PrivateKernelInnerData, PrivateKernelTailData, PublicKernelData}, public_data_read::PublicDataRead, public_data_update_request::PublicDataUpdateRequest, @@ -16,14 +16,16 @@ use crate::{ tests::{fixtures, testing_harness::build_tx_context}, transaction::tx_context::TxContext }; use crate::constants::{ - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_READS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUM_FIELDS_PER_SHA256, VK_TREE_HEIGHT + MAX_NEW_COMMITMENTS_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, NUM_FIELDS_PER_SHA256, + VK_TREE_HEIGHT }; struct PreviousKernelDataBuilder { contract_address: AztecAddress, portal_contract_address: EthAddress, end: CombinedAccumulatedDataBuilder, + end_non_revertible: AccumulatedNonRevertibleDataBuilder, historical_header: Header, tx_context: TxContext, is_private: bool, @@ -32,12 +34,23 @@ struct PreviousKernelDataBuilder { vk_index: u32, vk_path: [Field; VK_TREE_HEIGHT], sideffect_counter: u32, + min_revertible_side_effect_counter: u32 } impl PreviousKernelDataBuilder { - pub fn new() -> Self { + pub fn new(is_for_public: bool) -> Self { let mut end: CombinedAccumulatedDataBuilder = dep::std::unsafe::zeroed(); - end.new_nullifiers.push(SideEffectLinkedToNoteHash { value: 321, note_hash: 0, counter: 0 }); // 0th nullifier must be non-zero. + 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(false, 0); @@ -45,6 +58,7 @@ impl PreviousKernelDataBuilder { contract_address: fixtures::contracts::parent_contract.address, portal_contract_address: fixtures::contracts::parent_contract.portal_contract_address, end, + end_non_revertible, historical_header: fixtures::HEADER, tx_context, is_private: true, @@ -52,7 +66,8 @@ impl PreviousKernelDataBuilder { vk: VerificationKey {}, vk_index: 0, vk_path: [0; VK_TREE_HEIGHT], - sideffect_counter: 2 + sideffect_counter: 2, + min_revertible_side_effect_counter: 2 } } @@ -117,7 +132,10 @@ impl PreviousKernelDataBuilder { } } - pub fn append_new_nullifiers(&mut self, num_extra_nullifier: Field) { + pub fn append_new_nullifiers_from_private(&mut self, num_extra_nullifier: Field) { + // 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 first_nullifier = self.end.new_nullifiers.get(0); let mocked_value_offset = first_nullifier.value + self.end.new_nullifiers.len(); for i in 1..MAX_NEW_NULLIFIERS_PER_TX { @@ -134,6 +152,46 @@ impl PreviousKernelDataBuilder { } } + pub fn append_new_nullifiers_from_public(&mut self, num_extra_nullifier: Field) { + let first_nullifier = self.end_non_revertible.new_nullifiers.get(0); + let mocked_value_offset = first_nullifier.value + self.end.new_nullifiers.len(); + for i in 1..MAX_NEW_NULLIFIERS_PER_TX { + if i as u64 <= num_extra_nullifier as u64 { + // The default value is its index + the value of the first nullifier. + self.end.new_nullifiers.push( + SideEffectLinkedToNoteHash { + value: i + mocked_value_offset, + note_hash: first_nullifier.note_hash, + counter: self.next_sideffect_counter() + } + ); + } + } + } + + pub fn append_new_nullifiers_non_revertible(&mut self, num_extra_nullifier: Field) { + let first_nullifier = self.end_non_revertible.new_nullifiers.get(0); + let mocked_value_offset = first_nullifier.value + self.end_non_revertible.new_nullifiers.len(); + for i in 1..MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX { + if i as u64 <= num_extra_nullifier as u64 { + // The default value is its index + the value of the first nullifier. + self.end_non_revertible.new_nullifiers.push( + SideEffectLinkedToNoteHash { + value: i + mocked_value_offset, + note_hash: first_nullifier.note_hash, + counter: self.next_sideffect_counter() + } + ); + } + } + } + + // 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; NUM_FIELDS_PER_SHA256], preimages_length: Field) { self.end.encrypted_logs_hash = hash; self.end.encrypted_log_preimages_length = preimages_length; @@ -154,6 +212,11 @@ impl PreviousKernelDataBuilder { 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 { @@ -175,7 +238,7 @@ impl PreviousKernelDataBuilder { pub fn to_private_kernel_inner_data(self) -> PrivateKernelInnerData { let public_inputs = PrivateKernelInnerCircuitPublicInputs { aggregation_object: AggregationObject {}, - max_non_revertible_side_effect_counter: 0, + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, end: self.end.finish(), constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, is_private: self.is_private @@ -184,28 +247,33 @@ impl PreviousKernelDataBuilder { } pub fn to_private_kernel_tail_data(self) -> PrivateKernelTailData { - // TODO(fees) probably need to add this to the builder once it is implemented. - let end_non_revertible: AccumulatedNonRevertibleData = dep::std::unsafe::zeroed(); + let end_non_revertible = self.end_non_revertible.to_private(); + let end = self.end.to_private_accumulated_revertible_data(); let public_inputs = PrivateKernelTailCircuitPublicInputs { aggregation_object: AggregationObject {}, end_non_revertible, - end: self.end.to_final(), + // side effects are already paritioned by this builder + end, constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, - is_private: self.is_private + needs_setup: end_non_revertible.needs_setup(), + needs_app_logic: end.needs_app_logic(), + needs_teardown: end_non_revertible.needs_teardown() }; PrivateKernelTailData { 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 { - // TODO(fees) probably need to add this to the builder once it is implemented. - let end_non_revertible: AccumulatedNonRevertibleData = dep::std::unsafe::zeroed(); + 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: self.end.finish(), + end, constants: CombinedConstantData { historical_header: self.historical_header, tx_context: self.tx_context }, - is_private: self.is_private + 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 } diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr index ef6bc0fb58ab..d001cb9dfb4f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr @@ -23,7 +23,7 @@ struct PrivateCircuitPublicInputsBuilder { args_hash: Field, return_values: BoundedVec, - max_non_revertible_side_effect_counter: u32, + min_revertible_side_effect_counter: u32, read_requests: BoundedVec, nullifier_key_validation_requests: BoundedVec, @@ -106,7 +106,7 @@ impl PrivateCircuitPublicInputsBuilder { call_context: self.call_context, args_hash: self.args_hash, return_values: self.return_values.storage, - max_non_revertible_side_effect_counter: self.max_non_revertible_side_effect_counter, + min_revertible_side_effect_counter: self.min_revertible_side_effect_counter, read_requests: self.read_requests.storage, nullifier_key_validation_requests: self.nullifier_key_validation_requests.storage, new_commitments: self.new_commitments.storage, diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr index e4cd56320cc4..65d734c73c2f 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -55,4 +55,4 @@ trait Serialize { trait Deserialize { fn deserialize(fields: [Field; N]) -> Self; } -// docs:end:deserialize \ No newline at end of file +// docs:end:deserialize diff --git a/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/arrays.nr b/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/arrays.nr index 609071c4d847..7cfcfc011a58 100644 --- a/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/arrays.nr +++ b/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/arrays.nr @@ -33,7 +33,7 @@ pub fn validate_array(array: [T; N]) where T: Empty + Eq { assert((last_non_zero_pos as u64) <= (first_zero_pos as u64), "invalid array"); } -// Helper method to determine the number of non-zero/empty elements in a validated array (ie, validate_array(array) +// Helper method to determine the number of non-zero/empty elements in a validated array (ie, validate_array(array) // should be true). pub fn array_length(array: [T; N]) -> Field where T: Empty + Eq { let mut length = 0; @@ -57,6 +57,32 @@ pub fn array_eq(array: [T; N], expected: [T; S]) -> bool where T: Empty eq } +pub fn array_cp(array: [T; N]) -> [T; S] where T: Empty { + let mut result: [T; S] = [T::empty(); S]; + for i in 0..S { + result[i] = array[i]; + } + result +} + +pub fn array_concat(array1: [T; N], array2: [T; S]) -> [T; M] where T: Empty + Eq { + 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 +} + #[test] fn smoke_validate_array() { let valid_array = []; diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 6ab4ac345357..4d182caaa5ef 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -280,7 +280,7 @@ export class AztecNodeService implements AztecNode { * @param tx - The transaction to be submitted. */ public async sendTx(tx: Tx) { - this.log.info(`Received tx ${await tx.getTxHash()}`); + this.log.info(`Received tx ${tx.getTxHash()}`); await this.p2pClient!.sendTx(tx); } @@ -560,7 +560,7 @@ export class AztecNodeService implements AztecNode { * @param tx - The transaction to simulate. **/ public async simulatePublicCalls(tx: Tx) { - this.log.info(`Simulating tx ${await tx.getTxHash()}`); + this.log.info(`Simulating tx ${tx.getTxHash()}`); const blockNumber = (await this.blockSource.getBlockNumber()) + 1; // If sequencer is not initialized, we just set these values to zero for simulation. @@ -589,7 +589,7 @@ export class AztecNodeService implements AztecNode { if (failedTxs.length) { throw failedTxs[0].error; } - this.log.info(`Simulated tx ${await tx.getTxHash()} succeeds`); + this.log.info(`Simulated tx ${tx.getTxHash()} succeeds`); } public setConfig(config: Partial): Promise { diff --git a/yarn-project/aztec.js/src/contract/sent_tx.ts b/yarn-project/aztec.js/src/contract/sent_tx.ts index 25f646be0213..e40b65b3a006 100644 --- a/yarn-project/aztec.js/src/contract/sent_tx.ts +++ b/yarn-project/aztec.js/src/contract/sent_tx.ts @@ -37,8 +37,8 @@ export class SentTx { * * @returns A promise that resolves to the transaction hash of the SentTx instance. */ - public async getTxHash() { - return await this.txHashPromise; + public getTxHash(): Promise { + return this.txHashPromise; } /** diff --git a/yarn-project/circuit-types/src/contract_data.ts b/yarn-project/circuit-types/src/contract_data.ts index 43cec7a3e6c3..7770cd81fd9f 100644 --- a/yarn-project/circuit-types/src/contract_data.ts +++ b/yarn-project/circuit-types/src/contract_data.ts @@ -192,12 +192,17 @@ export class ExtendedContractData { /** True if this represents an empty instance. */ public isEmpty(): boolean { + return ExtendedContractData.isEmpty(this); + } + + /** True if the passed instance is empty . */ + public static isEmpty(obj: ExtendedContractData): boolean { return ( - this.contractData.isEmpty() && - this.publicFunctions.length === 0 && - this.contractClassId.isZero() && - this.publicKeyHash.isZero() && - this.saltedInitializationHash.isZero() + obj.contractData.isEmpty() && + obj.publicFunctions.length === 0 && + obj.contractClassId.isZero() && + obj.publicKeyHash.isZero() && + obj.saltedInitializationHash.isZero() ); } diff --git a/yarn-project/circuit-types/src/mocks.ts b/yarn-project/circuit-types/src/mocks.ts index 30da4aa900c3..0cb2baaea777 100644 --- a/yarn-project/circuit-types/src/mocks.ts +++ b/yarn-project/circuit-types/src/mocks.ts @@ -1,12 +1,15 @@ import { AztecAddress, + CallRequest, Fr, MAX_NEW_CONTRACTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, Proof, } from '@aztec/circuits.js'; import { makePrivateKernelTailCircuitPublicInputs, makePublicCallRequest } from '@aztec/circuits.js/factories'; import { ContractArtifact } from '@aztec/foundation/abi'; +import { makeTuple } from '@aztec/foundation/array'; import { times } from '@aztec/foundation/collection'; import { randomBytes } from '@aztec/foundation/crypto'; import { Tuple } from '@aztec/foundation/serialize'; @@ -29,7 +32,7 @@ export function makeEmptyLogs(): TxL2Logs { export const randomTxHash = (): TxHash => new TxHash(randomBytes(32)); export const mockTx = (seed = 1) => { - return new Tx( + const tx = new Tx( makePrivateKernelTailCircuitPublicInputs(seed), new Proof(Buffer.alloc(0)), TxL2Logs.random(8, 3), // 8 priv function invocations creating 3 encrypted logs each @@ -40,6 +43,19 @@ export const mockTx = (seed = 1) => { typeof MAX_NEW_CONTRACTS_PER_TX >, ); + + 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; + + return tx; }; export const randomContractArtifact = (): ContractArtifact => ({ diff --git a/yarn-project/circuit-types/src/stats/stats.ts b/yarn-project/circuit-types/src/stats/stats.ts index 74ca04d4005f..8f87e3339053 100644 --- a/yarn-project/circuit-types/src/stats/stats.ts +++ b/yarn-project/circuit-types/src/stats/stats.ts @@ -60,8 +60,9 @@ export type CircuitSimulationStats = { | 'root-rollup' | 'merge-rollup' | 'private-kernel-inner' - | 'public-kernel-private-input' - | 'public-kernel-non-first-iteration'; + | 'public-kernel-setup' + | 'public-kernel-app-logic' + | 'public-kernel-teardown'; /** Duration in ms. */ duration: number; /** Size in bytes of circuit inputs. */ diff --git a/yarn-project/circuit-types/src/tx/tx.ts b/yarn-project/circuit-types/src/tx/tx.ts index 10f53c4dc65d..23a2d232209a 100644 --- a/yarn-project/circuit-types/src/tx/tx.ts +++ b/yarn-project/circuit-types/src/tx/tx.ts @@ -3,6 +3,8 @@ import { PrivateKernelTailCircuitPublicInputs, Proof, PublicCallRequest, + SideEffect, + SideEffectLinkedToNoteHash, } from '@aztec/circuits.js'; import { arrayNonEmptyLength } from '@aztec/foundation/collection'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; @@ -121,8 +123,8 @@ export class Tx { * @param logsSource - An instance of `L2LogsSource` which can be used to obtain the logs. * @returns The requested logs. */ - public async getUnencryptedLogs(logsSource: L2LogsSource): Promise { - return logsSource.getUnencryptedLogs({ txHash: await this.getTxHash() }); + public getUnencryptedLogs(logsSource: L2LogsSource): Promise { + return logsSource.getUnencryptedLogs({ txHash: this.getTxHash() }); } /** @@ -153,27 +155,34 @@ export class Tx { * Construct & return transaction hash. * @returns The transaction's hash. */ - getTxHash(): Promise { + 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?.end.newNullifiers[0]; - if (!firstNullifier) { + const firstNullifier = this.data?.endNonRevertibleData.newNullifiers[0]; + if (!firstNullifier || firstNullifier.isEmpty()) { throw new Error(`Cannot get tx hash since first nullifier is missing`); } - return Promise.resolve(new TxHash(firstNullifier.value.toBuffer())); + return new TxHash(firstNullifier.value.toBuffer()); } /** Returns stats about this tx. */ getStats(): TxStats { return { - txHash: this.data!.end.newNullifiers[0].toString(), + txHash: this.getTxHash().toString(), encryptedLogCount: this.encryptedLogs.getTotalLogCount(), unencryptedLogCount: this.unencryptedLogs.getTotalLogCount(), encryptedLogSize: this.encryptedLogs.getSerializedLength(), unencryptedLogSize: this.unencryptedLogs.getSerializedLength(), - newContractCount: this.newContracts.filter(c => !c.isEmpty()).length, + newContractCount: arrayNonEmptyLength(this.newContracts, ExtendedContractData.isEmpty), newContractDataSize: this.newContracts.map(c => c.toBuffer().length).reduce((a, b) => a + b, 0), - newCommitmentCount: this.data!.end.newCommitments.filter(c => !c.isEmpty()).length, - newNullifierCount: this.data!.end.newNullifiers.filter(c => !c.isEmpty()).length, + + newCommitmentCount: + arrayNonEmptyLength(this.data!.endNonRevertibleData.newCommitments, SideEffect.isEmpty) + + arrayNonEmptyLength(this.data!.end.newCommitments, SideEffect.isEmpty), + + newNullifierCount: + arrayNonEmptyLength(this.data!.endNonRevertibleData.newNullifiers, SideEffectLinkedToNoteHash.isEmpty) + + arrayNonEmptyLength(this.data!.end.newNullifiers, SideEffectLinkedToNoteHash.isEmpty), + proofSize: this.proof.buffer.length, size: this.toBuffer().length, }; @@ -184,9 +193,9 @@ export class Tx { * @param tx - Tx-like object. * @returns - The hash. */ - static getHash(tx: Tx | HasHash): Promise { + static getHash(tx: Tx | HasHash): TxHash { const hasHash = (tx: Tx | HasHash): tx is HasHash => (tx as HasHash).hash !== undefined; - return Promise.resolve(hasHash(tx) ? tx.hash : tx.getTxHash()); + return hasHash(tx) ? tx.hash : tx.getTxHash(); } /** @@ -194,8 +203,8 @@ export class Tx { * @param txs - The txs to get the hashes from. * @returns The corresponding array of hashes. */ - static async getHashes(txs: (Tx | HasHash)[]): Promise { - return await Promise.all(txs.map(tx => Tx.getHash(tx))); + static getHashes(txs: (Tx | HasHash)[]): TxHash[] { + return txs.map(tx => Tx.getHash(tx)); } /** diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index efcc47de6c14..75a9c19812f4 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -12,20 +12,27 @@ export const MAX_PUBLIC_DATA_READS_PER_CALL = 16; export const MAX_READ_REQUESTS_PER_CALL = 32; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL = 1; export const MAX_NEW_COMMITMENTS_PER_TX = 64; +export const MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX = 8; +export const MAX_REVERTIBLE_COMMITMENTS_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_NEW_L2_TO_L1_MSGS_PER_TX = 2; +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 = 16; +export const MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 1; +export const MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX = 15; export const MAX_PUBLIC_DATA_READS_PER_TX = 16; +export const MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX = 1; +export const MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX = 15; +export const MAX_NEW_L2_TO_L1_MSGS_PER_TX = 2; export const MAX_NEW_CONTRACTS_PER_TX = 1; export const MAX_READ_REQUESTS_PER_TX = 128; export const MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX = 4; export const NUM_ENCRYPTED_LOGS_HASHES_PER_TX = 1; export const NUM_UNENCRYPTED_LOGS_HASHES_PER_TX = 1; -export const MAX_NEW_COMMITMENTS_PER_TX_META = 8; -export const MAX_NEW_NULLIFIERS_PER_TX_META = 8; -export const MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META = 2; export const NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP = 16; export const VK_TREE_HEIGHT = 3; export const FUNCTION_TREE_HEIGHT = 5; diff --git a/yarn-project/circuits.js/src/structs/call_request.ts b/yarn-project/circuits.js/src/structs/call_request.ts index 08f9739d80cf..353cce504f4e 100644 --- a/yarn-project/circuits.js/src/structs/call_request.ts +++ b/yarn-project/circuits.js/src/structs/call_request.ts @@ -144,4 +144,8 @@ export class CallRequest { callRequest.endSideEffectCounter.equals(this.endSideEffectCounter) ); } + + toString() { + return `CallRequest(hash: ${this.hash.toString()}, callerContractAddress: ${this.callerContractAddress.toString()}, callerContext: ${this.callerContext.toString()}, startSideEffectCounter: ${this.startSideEffectCounter.toString()}, endSideEffectCounter: ${this.endSideEffectCounter.toString()})`; + } } 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 ed7561351564..a91075fa0510 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,5 +1,5 @@ import { makeAccumulatedData, makeFinalAccumulatedData } from '../../tests/factories.js'; -import { CombinedAccumulatedData, FinalAccumulatedData } from './combined_accumulated_data.js'; +import { CombinedAccumulatedData, PrivateAccumulatedRevertibleData } from './combined_accumulated_data.js'; describe('CombinedAccumulatedData', () => { it('Data after serialization and deserialization is equal to the original', () => { @@ -12,7 +12,7 @@ describe('CombinedAccumulatedData', () => { describe('FinalAccumulatedData', () => { it('Data after serialization and deserialization is equal to the original', () => { const original = makeFinalAccumulatedData(); - const afterSerialization = FinalAccumulatedData.fromBuffer(original.toBuffer()); + 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 dd7f9015a134..811685523c08 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,22 +1,30 @@ import { makeTuple } from '@aztec/foundation/array'; +import { padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize'; import { MAX_NEW_COMMITMENTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX_META, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NEW_NULLIFIERS_PER_TX_META, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUM_FIELDS_PER_SHA256, } from '../../constants.gen.js'; import { CallRequest } from '../call_request.js'; @@ -60,6 +68,10 @@ export class PublicDataRead { return serializeToBuffer(this.leafSlot, this.value); } + isEmpty() { + return this.leafSlot.isZero() && this.value.isZero(); + } + static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new PublicDataRead(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); @@ -110,6 +122,14 @@ export class PublicDataUpdateRequest { return serializeToBuffer(this.leafSlot, this.newValue); } + isEmpty() { + return this.leafSlot.isZero() && this.newValue.isZero(); + } + + equals(other: PublicDataUpdateRequest) { + return this.leafSlot.equals(other.leafSlot) && this.newValue.equals(other.newValue); + } + static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); return new PublicDataUpdateRequest(Fr.fromBuffer(reader), Fr.fromBuffer(reader)); @@ -240,22 +260,225 @@ export class CombinedAccumulatedData { ); } - static fromFinalAccumulatedData(finalData: FinalAccumulatedData): CombinedAccumulatedData { + /** + * Deserializes from a string, corresponding to a write in cpp. + * @param str - String to read from. + * @returns Deserialized object. + */ + static fromString(str: string) { + return CombinedAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + } + + static empty() { return new CombinedAccumulatedData( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - finalData.newCommitments, - finalData.newNullifiers, + makeTuple(MAX_NEW_COMMITMENTS_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), + makeTuple(2, Fr.zero), + makeTuple(2, Fr.zero), + Fr.zero(), + Fr.zero(), + makeTuple(MAX_NEW_CONTRACTS_PER_TX, NewContractData.empty), + makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataRead.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 { + const newCommitments = padArrayEnd( + [...nonRevertible.newCommitments, ...revertible.newCommitments].filter(x => !x.isEmpty()), + SideEffect.empty(), + MAX_NEW_COMMITMENTS_PER_TX, + ); + + const newNullifiers = padArrayEnd( + [...nonRevertible.newNullifiers, ...revertible.newNullifiers].filter(x => !x.isEmpty()), + 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 publicDataUpdateRequests = padArrayEnd( + [...nonRevertible.publicDataUpdateRequests, ...revertible.publicDataUpdateRequests].filter(x => !x.isEmpty()), + PublicDataUpdateRequest.empty(), + MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + ); + + const publicDataReads = padArrayEnd( + [...nonRevertible.publicDataReads, ...revertible.publicDataReads].filter(x => !x.isEmpty()), + PublicDataRead.empty(), + MAX_PUBLIC_DATA_READS_PER_TX, + ); + + return new CombinedAccumulatedData( + revertible.readRequests, + revertible.nullifierKeyValidationRequests, + newCommitments, + newNullifiers, + revertible.privateCallStack, + publicCallStack, + revertible.newL2ToL1Msgs, + revertible.encryptedLogsHash, + revertible.unencryptedLogsHash, + revertible.encryptedLogPreimagesLength, + revertible.unencryptedLogPreimagesLength, + revertible.newContracts, + publicDataUpdateRequests, + publicDataReads, + ); + } +} + +export class PublicAccumulatedRevertibleData { + constructor( + /** + * All the read requests made in this transaction. + */ + public readRequests: Tuple, + /** + * All the nullifier key validation requests made in this transaction. + */ + public nullifierKeyValidationRequests: Tuple< + NullifierKeyValidationRequestContext, + typeof MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX + >, + /** + * The new commitments made in this transaction. + */ + public newCommitments: 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: Represented as a tuple of 2 fields in order to fit in all of the 256 bits of sha256 hash. + */ + public encryptedLogsHash: Tuple, + /** + * 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: Tuple, + /** + * 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 new contracts deployed in this transaction. + */ + public newContracts: Tuple, + /** + * All the public data update requests made in this transaction. + */ + public publicDataUpdateRequests: Tuple< + PublicDataUpdateRequest, + typeof MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX + >, + /** + * All the public data reads made in this transaction. + */ + public publicDataReads: Tuple, + ) {} + + toBuffer() { + return serializeToBuffer( + this.readRequests, + this.nullifierKeyValidationRequests, + this.newCommitments, + this.newNullifiers, + this.privateCallStack, + this.publicCallStack, + this.newL2ToL1Msgs, + this.encryptedLogsHash, + this.unencryptedLogsHash, + this.encryptedLogPreimagesLength, + this.unencryptedLogPreimagesLength, + this.newContracts, + this.publicDataUpdateRequests, + this.publicDataReads, + ); + } + + 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) { + const reader = BufferReader.asReader(buffer); + return new this( + reader.readArray(MAX_READ_REQUESTS_PER_TX, SideEffect), + reader.readArray(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext), + reader.readArray(MAX_REVERTIBLE_COMMITMENTS_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), + reader.readArray(2, Fr), + reader.readArray(2, Fr), + Fr.fromBuffer(reader), + Fr.fromBuffer(reader), + reader.readArray(MAX_NEW_CONTRACTS_PER_TX, NewContractData), + reader.readArray(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest), + reader.readArray(MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead), + ); + } + + static fromPrivateAccumulatedRevertibleData(finalData: PrivateAccumulatedRevertibleData) { + return new this( + makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), + makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), + padArrayEnd(finalData.newCommitments, SideEffect.empty(), MAX_REVERTIBLE_COMMITMENTS_PER_TX), + padArrayEnd(finalData.newNullifiers, SideEffectLinkedToNoteHash.empty(), MAX_REVERTIBLE_NULLIFIERS_PER_TX), finalData.privateCallStack, - finalData.publicCallStack, + padArrayEnd(finalData.publicCallStack, CallRequest.empty(), MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX), finalData.newL2ToL1Msgs, finalData.encryptedLogsHash, finalData.unencryptedLogsHash, finalData.encryptedLogPreimagesLength, finalData.unencryptedLogPreimagesLength, finalData.newContracts, - makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty), + makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), + makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty), ); } @@ -265,25 +488,25 @@ export class CombinedAccumulatedData { * @returns Deserialized object. */ static fromString(str: string) { - return CombinedAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + return this.fromBuffer(Buffer.from(str, 'hex')); } static empty() { - return new CombinedAccumulatedData( + return new this( makeTuple(MAX_READ_REQUESTS_PER_TX, SideEffect.empty), makeTuple(MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, NullifierKeyValidationRequestContext.empty), - makeTuple(MAX_NEW_COMMITMENTS_PER_TX, SideEffect.empty), - makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), + makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_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_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), makeTuple(2, Fr.zero), makeTuple(2, Fr.zero), Fr.zero(), Fr.zero(), makeTuple(MAX_NEW_CONTRACTS_PER_TX, NewContractData.empty), - makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), - makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty), + makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), + makeTuple(MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty), ); } } @@ -292,16 +515,16 @@ export class CombinedAccumulatedData { * 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 FinalAccumulatedData { +export class PrivateAccumulatedRevertibleData { constructor( /** * The new commitments made in this transaction. */ - public newCommitments: Tuple, + public newCommitments: Tuple, /** * The new nullifiers made in this transaction. */ - public newNullifiers: Tuple, + public newNullifiers: Tuple, /** * Current private call stack. * TODO(#3417): Given this field must empty, should we just remove it? @@ -310,7 +533,7 @@ export class FinalAccumulatedData { /** * Current public call stack. */ - public publicCallStack: Tuple, + public publicCallStack: Tuple, /** * All the new L2 to L1 messages created in this transaction. */ @@ -363,13 +586,13 @@ export class FinalAccumulatedData { * @param buffer - Buffer or reader to read from. * @returns Deserialized object. */ - static fromBuffer(buffer: Buffer | BufferReader): FinalAccumulatedData { + static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedRevertibleData { const reader = BufferReader.asReader(buffer); - return new FinalAccumulatedData( - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX, SideEffect), - reader.readArray(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), + return new PrivateAccumulatedRevertibleData( + reader.readArray(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_REVERTIBLE_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_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), reader.readArray(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr), reader.readArray(2, Fr), reader.readArray(2, Fr), @@ -385,15 +608,15 @@ export class FinalAccumulatedData { * @returns Deserialized object. */ static fromString(str: string) { - return FinalAccumulatedData.fromBuffer(Buffer.from(str, 'hex')); + return PrivateAccumulatedRevertibleData.fromBuffer(Buffer.from(str, 'hex')); } static empty() { - return new FinalAccumulatedData( - makeTuple(MAX_NEW_COMMITMENTS_PER_TX, SideEffect.empty), - makeTuple(MAX_NEW_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash.empty), + return new PrivateAccumulatedRevertibleData( + makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect.empty), + makeTuple(MAX_REVERTIBLE_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_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty), makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, Fr.zero), makeTuple(2, Fr.zero), makeTuple(2, Fr.zero), @@ -404,32 +627,32 @@ export class FinalAccumulatedData { } } -export class AccumulatedNonRevertibleData { +export class PrivateAccumulatedNonRevertibleData { constructor( /** * The new non-revertible commitments made in this transaction. */ - public newCommitments: Tuple, + public newCommitments: Tuple, /** * The new non-revertible nullifiers made in this transaction. */ - public newNullifiers: Tuple, + public newNullifiers: Tuple, /** * Current public call stack that will produce non-revertible side effects. */ - public publicCallStack: Tuple, + public publicCallStack: Tuple, ) {} toBuffer() { return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); } - static fromBuffer(buffer: Buffer | BufferReader): AccumulatedNonRevertibleData { + static fromBuffer(buffer: Buffer | BufferReader): PrivateAccumulatedNonRevertibleData { const reader = BufferReader.asReader(buffer); - return new AccumulatedNonRevertibleData( - reader.readArray(MAX_NEW_COMMITMENTS_PER_TX_META, SideEffect), - reader.readArray(MAX_NEW_NULLIFIERS_PER_TX_META, SideEffectLinkedToNoteHash), - reader.readArray(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, CallRequest), + return new PrivateAccumulatedNonRevertibleData( + reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, SideEffect), + reader.readArray(MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, SideEffectLinkedToNoteHash), + reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest), ); } @@ -438,14 +661,85 @@ export class AccumulatedNonRevertibleData { } static fromString(str: string) { - return AccumulatedNonRevertibleData.fromBuffer(Buffer.from(str, 'hex')); + return PrivateAccumulatedNonRevertibleData.fromBuffer(Buffer.from(str, 'hex')); } static empty() { - return new AccumulatedNonRevertibleData( - makeTuple(MAX_NEW_COMMITMENTS_PER_TX_META, SideEffect.empty), - makeTuple(MAX_NEW_NULLIFIERS_PER_TX_META, SideEffectLinkedToNoteHash.empty), - makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, CallRequest.empty), + return new PrivateAccumulatedNonRevertibleData( + makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_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( + /** + * The new non-revertible commitments made in this transaction. + */ + public newCommitments: 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 + >, + /** + * All the public data reads made in this transaction. + */ + public publicDataReads: Tuple, + ) {} + + toBuffer() { + return serializeToBuffer(this.newCommitments, this.newNullifiers, this.publicCallStack); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new this( + reader.readArray(MAX_NON_REVERTIBLE_COMMITMENTS_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), + reader.readArray(MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead), + ); + } + + toString() { + return this.toBuffer().toString('hex'); + } + + static fromString(str: string) { + return this.fromBuffer(Buffer.from(str, 'hex')); + } + + static empty() { + return new this( + makeTuple(MAX_NON_REVERTIBLE_COMMITMENTS_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), + makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead.empty), + ); + } + + static fromPrivateAccumulatedNonRevertibleData(data: PrivateAccumulatedNonRevertibleData) { + return new this( + data.newCommitments, + data.newNullifiers, + data.publicCallStack, + makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, PublicDataUpdateRequest.empty), + makeTuple(MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, PublicDataRead.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_inner_circuit_public_inputs.ts index 510759d072ba..38aa7027b8b4 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_inner_circuit_public_inputs.ts @@ -17,7 +17,7 @@ export class PrivateKernelInnerCircuitPublicInputs { /** * The side effect counter that non-revertible side effects are all beneath. */ - public maxNonRevertibleSideEffectCounter: Fr, + public minRevertibleSideEffectCounter: Fr, /** * Data accumulated from both public and private circuits. */ @@ -35,7 +35,7 @@ export class PrivateKernelInnerCircuitPublicInputs { toBuffer() { return serializeToBuffer( this.aggregationObject, - this.maxNonRevertibleSideEffectCounter, + this.minRevertibleSideEffectCounter, this.end, this.constants, this.isPrivate, 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 55d852313f5a..cdbdf292d4a0 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,7 +1,7 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { AggregationObject } from '../aggregation_object.js'; -import { AccumulatedNonRevertibleData, FinalAccumulatedData } from './combined_accumulated_data.js'; +import { PrivateAccumulatedNonRevertibleData, PrivateAccumulatedRevertibleData } from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; /** @@ -16,19 +16,27 @@ export class PrivateKernelTailCircuitPublicInputs { /** * Accumulated side effects that are not revertible. */ - public endNonRevertibleData: AccumulatedNonRevertibleData, + public endNonRevertibleData: PrivateAccumulatedNonRevertibleData, /** * Data accumulated from both public and private circuits. */ - public end: FinalAccumulatedData, + public end: PrivateAccumulatedRevertibleData, /** * Data which is not modified by the circuits. */ public constants: CombinedConstantData, /** - * Indicates whether the input is for a private or public kernel. + * Indicates whether the setup kernel is needed. */ - public isPrivate: boolean, + public needsSetup: boolean, + /** + * Indicates whether the app logic kernel is needed. + */ + public needsAppLogic: boolean, + /** + * Indicates whether the teardown kernel is needed. + */ + public needsTeardown: boolean, ) {} toBuffer() { @@ -37,7 +45,9 @@ export class PrivateKernelTailCircuitPublicInputs { this.endNonRevertibleData, this.end, this.constants, - this.isPrivate, + this.needsSetup, + this.needsAppLogic, + this.needsTeardown, ); } @@ -50,20 +60,24 @@ export class PrivateKernelTailCircuitPublicInputs { const reader = BufferReader.asReader(buffer); return new PrivateKernelTailCircuitPublicInputs( reader.readObject(AggregationObject), - reader.readObject(AccumulatedNonRevertibleData), - reader.readObject(FinalAccumulatedData), + reader.readObject(PrivateAccumulatedNonRevertibleData), + reader.readObject(PrivateAccumulatedRevertibleData), reader.readObject(CombinedConstantData), reader.readBoolean(), + reader.readBoolean(), + reader.readBoolean(), ); } static empty() { return new PrivateKernelTailCircuitPublicInputs( AggregationObject.makeFake(), - AccumulatedNonRevertibleData.empty(), - FinalAccumulatedData.empty(), + PrivateAccumulatedNonRevertibleData.empty(), + PrivateAccumulatedRevertibleData.empty(), CombinedConstantData.empty(), true, + true, + true, ); } } 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 ded0fb6ace44..28cb85c063ff 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 @@ -1,7 +1,11 @@ import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { AggregationObject } from '../aggregation_object.js'; -import { AccumulatedNonRevertibleData, CombinedAccumulatedData } from './combined_accumulated_data.js'; +import { + CombinedAccumulatedData, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, +} from './combined_accumulated_data.js'; import { CombinedConstantData } from './combined_constant_data.js'; /** @@ -9,6 +13,8 @@ import { CombinedConstantData } from './combined_constant_data.js'; * 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. @@ -17,19 +23,27 @@ export class PublicKernelCircuitPublicInputs { /** * Accumulated side effects and enqueued calls that are not revertible. */ - public endNonRevertibleData: AccumulatedNonRevertibleData, + public endNonRevertibleData: PublicAccumulatedNonRevertibleData, /** * Data accumulated from both public and private circuits. */ - public end: CombinedAccumulatedData, + public end: PublicAccumulatedRevertibleData, /** * Data which is not modified by the circuits. */ public constants: CombinedConstantData, /** - * Indicates whether the input is for a private or public kernel. + * Indicates whether the setup kernel is needed. + */ + public needsSetup: boolean, + /** + * Indicates whether the app logic kernel is needed. */ - public isPrivate: boolean, + public needsAppLogic: boolean, + /** + * Indicates whether the teardown kernel is needed. + */ + public needsTeardown: boolean, ) {} toBuffer() { @@ -38,10 +52,19 @@ export class PublicKernelCircuitPublicInputs { this.endNonRevertibleData, this.end, this.constants, - this.isPrivate, + this.needsSetup, + this.needsAppLogic, + this.needsTeardown, ); } + get combinedData() { + if (!this.combined) { + this.combined = CombinedAccumulatedData.recombine(this.endNonRevertibleData, this.end); + } + return this.combined; + } + /** * Deserializes from a buffer or reader, corresponding to a write in cpp. * @param buffer - Buffer or reader to read from. @@ -51,20 +74,24 @@ export class PublicKernelCircuitPublicInputs { const reader = BufferReader.asReader(buffer); return new PublicKernelCircuitPublicInputs( reader.readObject(AggregationObject), - reader.readObject(AccumulatedNonRevertibleData), - reader.readObject(CombinedAccumulatedData), + reader.readObject(PublicAccumulatedNonRevertibleData), + reader.readObject(PublicAccumulatedRevertibleData), reader.readObject(CombinedConstantData), reader.readBoolean(), + reader.readBoolean(), + reader.readBoolean(), ); } static empty() { return new PublicKernelCircuitPublicInputs( AggregationObject.makeFake(), - AccumulatedNonRevertibleData.empty(), - CombinedAccumulatedData.empty(), + PublicAccumulatedNonRevertibleData.empty(), + PublicAccumulatedRevertibleData.empty(), CombinedConstantData.empty(), true, + true, + true, ); } } diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts index b35170259b1b..ec56ca3bc970 100644 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts @@ -112,7 +112,12 @@ export class PrivateCallStackItem { const callerContext = currentCallContext.isDelegateCall ? new CallerContext(parentCallContext.msgSender, parentCallContext.storageContractAddress) : CallerContext.empty(); - // todo: populate side effect counters correctly - return new CallRequest(this.hash(), parentCallContext.storageContractAddress, callerContext, Fr.ZERO, Fr.ZERO); + return new CallRequest( + this.hash(), + parentCallContext.storageContractAddress, + callerContext, + new Fr(this.publicInputs.callContext.startSideEffectCounter), + this.publicInputs.endSideEffectCounter, + ); } } diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 5415cab76fa5..99b263181d74 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -46,7 +46,7 @@ export class PrivateCircuitPublicInputs { /** * The side-effect counter under which all side effects are non-revertible. */ - public maxNonRevertibleSideEffectCounter: Fr, + public minRevertibleSideEffectCounter: Fr, /** * Read requests created by the corresponding function call. */ @@ -228,7 +228,7 @@ export class PrivateCircuitPublicInputs { this.callContext.isEmpty() && this.argsHash.isZero() && isZeroArray(this.returnValues) && - this.maxNonRevertibleSideEffectCounter.isZero() && + this.minRevertibleSideEffectCounter.isZero() && isEmptyArray(this.readRequests) && isEmptyArray(this.nullifierKeyValidationRequests) && isEmptyArray(this.newCommitments) && @@ -257,7 +257,7 @@ export class PrivateCircuitPublicInputs { fields.callContext, fields.argsHash, fields.returnValues, - fields.maxNonRevertibleSideEffectCounter, + fields.minRevertibleSideEffectCounter, fields.readRequests, fields.nullifierKeyValidationRequests, fields.newCommitments, diff --git a/yarn-project/circuits.js/src/structs/public_call_request.ts b/yarn-project/circuits.js/src/structs/public_call_request.ts index de26f627cbfc..d7dc04e45f72 100644 --- a/yarn-project/circuits.js/src/structs/public_call_request.ts +++ b/yarn-project/circuits.js/src/structs/public_call_request.ts @@ -116,7 +116,13 @@ export class PublicCallRequest { const callerContext = this.callContext.isDelegateCall ? new CallerContext(this.parentCallContext.msgSender, this.parentCallContext.storageContractAddress) : CallerContext.empty(); - return new CallRequest(item.hash(), this.parentCallContext.storageContractAddress, callerContext, Fr.ZERO, Fr.ZERO); + return new CallRequest( + item.hash(), + this.parentCallContext.storageContractAddress, + callerContext, + new Fr(this.callContext.startSideEffectCounter), + Fr.ZERO, + ); } /** diff --git a/yarn-project/circuits.js/src/structs/rollup/public_data_leaf/index.ts b/yarn-project/circuits.js/src/structs/rollup/public_data_leaf/index.ts index 7e36d112c48e..87743ba59a07 100644 --- a/yarn-project/circuits.js/src/structs/rollup/public_data_leaf/index.ts +++ b/yarn-project/circuits.js/src/structs/rollup/public_data_leaf/index.ts @@ -124,4 +124,8 @@ export class PublicDataTreeLeaf implements IndexedTreeLeaf { static buildDummy(key: bigint): PublicDataTreeLeaf { return new PublicDataTreeLeaf(new Fr(key), new Fr(0)); } + + static empty(): PublicDataTreeLeaf { + return new PublicDataTreeLeaf(Fr.ZERO, Fr.ZERO); + } } diff --git a/yarn-project/circuits.js/src/structs/side_effects.ts b/yarn-project/circuits.js/src/structs/side_effects.ts index 88ca402dd5e3..a39eb52420c8 100644 --- a/yarn-project/circuits.js/src/structs/side_effects.ts +++ b/yarn-project/circuits.js/src/structs/side_effects.ts @@ -59,7 +59,15 @@ export class SideEffect implements SideEffectType { * @returns True if the value and counter both are zero. */ isEmpty() { - return this.value.isZero() && this.counter.isZero(); + return SideEffect.isEmpty(this); + } + + /** + * Checks whether this instance of side-effect is empty. + * @returns True if the value and counter both are zero. + */ + static isEmpty(sideEffect: SideEffect) { + return sideEffect.value.isZero() && sideEffect.counter.isZero(); } /** @@ -127,7 +135,15 @@ export class SideEffectLinkedToNoteHash implements SideEffectType { * @returns True if the value, note hash and counter are all zero. */ isEmpty() { - return this.value.isZero() && this.noteHash.isZero() && this.counter.isZero(); + return SideEffectLinkedToNoteHash.isEmpty(this); + } + + /** + * Returns whether this instance of side-effect is empty. + * @returns True if the value, note hash and counter are all zero. + */ + static isEmpty(sideEffect: SideEffectLinkedToNoteHash) { + return sideEffect.value.isZero() && sideEffect.noteHash.isZero() && sideEffect.counter.isZero(); } /** diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index f0ae37e9a3cc..6e87936d6b57 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -9,7 +9,6 @@ import { SchnorrSignature } from '../barretenberg/index.js'; import { ARCHIVE_HEIGHT, ARGS_LENGTH, - AccumulatedNonRevertibleData, AggregationObject, AppendOnlyTreeSnapshot, BaseOrMergeRollupPublicInputs, @@ -26,7 +25,6 @@ import { ContractStorageRead, ContractStorageUpdateRequest, FUNCTION_TREE_HEIGHT, - FinalAccumulatedData, Fq, Fr, FunctionData, @@ -38,26 +36,33 @@ import { L2ToL1Message, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_COMMITMENTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX_META, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_CALL, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NEW_NULLIFIERS_PER_TX_META, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, MAX_PUBLIC_DATA_READS_PER_CALL, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_CALL, MAX_READ_REQUESTS_PER_TX, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, MergeRollupInputs, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, @@ -75,6 +80,8 @@ import { PartialStateReference, Point, PreviousRollupData, + PrivateAccumulatedNonRevertibleData, + PrivateAccumulatedRevertibleData, PrivateCallData, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -82,6 +89,8 @@ import { PrivateKernelInnerData, PrivateKernelTailCircuitPublicInputs, Proof, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, PublicCallData, PublicCallRequest, PublicCallStackItem, @@ -268,19 +277,49 @@ export function makeAccumulatedData(seed = 1, full = false): CombinedAccumulated ); } +/** + * Creates arbitrary accumulated data. + * @param seed - The seed to use for generating the accumulated data. + * @returns An accumulated data. + */ +export function makeCombinedAccumulatedRevertibleData(seed = 1, full = false): PublicAccumulatedRevertibleData { + const tupleGenerator = full ? makeTuple : makeHalfFullTuple; + + return new PublicAccumulatedRevertibleData( + tupleGenerator(MAX_READ_REQUESTS_PER_TX, sideEffectFromNumber, seed + 0x80), + tupleGenerator( + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, + makeNullifierKeyValidationRequestContext, + seed + 0x100, + ), + tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_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), + tupleGenerator(2, fr, seed + 0x700), // encrypted logs hash + tupleGenerator(2, fr, seed + 0x800), // unencrypted logs hash + fr(seed + 0x900), // encrypted_log_preimages_length + fr(seed + 0xa00), // unencrypted_log_preimages_length + tupleGenerator(MAX_NEW_CONTRACTS_PER_TX, makeNewContractData, seed + 0xb00), + tupleGenerator(MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, makePublicDataUpdateRequest, seed + 0xd00), + tupleGenerator(MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, makePublicDataRead, seed + 0xe00), + ); +} + /** * 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): FinalAccumulatedData { +export function makeFinalAccumulatedData(seed = 1, full = false): PrivateAccumulatedRevertibleData { const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - return new FinalAccumulatedData( - tupleGenerator(MAX_NEW_COMMITMENTS_PER_TX, sideEffectFromNumber, seed + 0x100), - tupleGenerator(MAX_NEW_NULLIFIERS_PER_TX, sideEffectLinkedFromNumber, seed + 0x200), + return new PrivateAccumulatedRevertibleData( + tupleGenerator(MAX_REVERTIBLE_COMMITMENTS_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_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), + tupleGenerator(MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, makeCallRequest, seed + 0x500), tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x600), tupleGenerator(2, fr, seed + 0x700), // encrypted logs hash tupleGenerator(2, fr, seed + 0x800), // unencrypted logs hash @@ -295,13 +334,25 @@ export function makeFinalAccumulatedData(seed = 1, full = false): FinalAccumulat * @param seed - The seed to use for generating the data. * @returns An instance of AccumulatedNonRevertibleData. */ -export function makeAccumulatedNonRevertibleData(seed = 1, full = false): AccumulatedNonRevertibleData { +export function makeAccumulatedNonRevertibleData(seed = 1, full = false): PrivateAccumulatedNonRevertibleData { const tupleGenerator = full ? makeTuple : makeHalfFullTuple; - return new AccumulatedNonRevertibleData( - tupleGenerator(MAX_NEW_COMMITMENTS_PER_TX_META, sideEffectFromNumber, seed + 0x101), - tupleGenerator(MAX_NEW_NULLIFIERS_PER_TX_META, sideEffectLinkedFromNumber, seed + 0x201), - tupleGenerator(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, makeCallRequest, seed + 0x501), + return new PrivateAccumulatedNonRevertibleData( + tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_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( + tupleGenerator(MAX_NON_REVERTIBLE_COMMITMENTS_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_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, makePublicDataRead, seed + 0x701), ); } @@ -388,10 +439,12 @@ export function makePublicKernelCircuitPublicInputs( ): PublicKernelCircuitPublicInputs { return new PublicKernelCircuitPublicInputs( makeAggregationObject(seed), - makeAccumulatedNonRevertibleData(seed, fullAccumulatedData), - makeAccumulatedData(seed, fullAccumulatedData), + makeCombinedAccumulatedNonRevertibleData(seed, fullAccumulatedData), + makeCombinedAccumulatedRevertibleData(seed, fullAccumulatedData), makeConstantData(seed + 0x100), true, + true, + true, ); } /** @@ -420,9 +473,11 @@ export function makePrivateKernelInnerCircuitPublicInputs( export function makePrivateKernelTailCircuitPublicInputs(seed = 1, full = true): PrivateKernelTailCircuitPublicInputs { return new PrivateKernelTailCircuitPublicInputs( makeAggregationObject(seed), - makeAccumulatedNonRevertibleData(seed, full), - makeFinalAccumulatedData(seed, full), - makeConstantData(seed + 0x100), + makeAccumulatedNonRevertibleData(seed + 0x100, full), + makeFinalAccumulatedData(seed + 0x200, full), + makeConstantData(seed + 0x300), + true, + true, true, ); } @@ -759,7 +814,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn ), argsHash: fr(seed + 0x100), returnValues: makeTuple(RETURN_VALUES_LENGTH, fr, seed + 0x200), - maxNonRevertibleSideEffectCounter: fr(0), + minRevertibleSideEffectCounter: fr(0), readRequests: makeTuple(MAX_READ_REQUESTS_PER_CALL, sideEffectFromNumber, seed + 0x300), nullifierKeyValidationRequests: makeTuple( MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_CALL, diff --git a/yarn-project/end-to-end/jest.config.ts b/yarn-project/end-to-end/jest.config.ts new file mode 100644 index 000000000000..83d85d85f9b7 --- /dev/null +++ b/yarn-project/end-to-end/jest.config.ts @@ -0,0 +1,12 @@ +import type { Config } from 'jest'; + +const config: Config = { + preset: 'ts-jest/presets/default-esm', + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.[cm]?js$': '$1', + }, + testRegex: './src/.*\\.test\\.(js|mjs|ts)$', + rootDir: './src', +}; + +export default config; diff --git a/yarn-project/end-to-end/package.json b/yarn-project/end-to-end/package.json index dbc05dadfcb6..439ef3f006d0 100644 --- a/yarn-project/end-to-end/package.json +++ b/yarn-project/end-to-end/package.json @@ -15,14 +15,6 @@ "test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test:integration:run\" \"anvil\"", "test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --runInBand --config jest.integration.config.json" }, - "jest": { - "preset": "ts-jest/presets/default-esm", - "moduleNameMapper": { - "^(\\.{1,2}/.*)\\.m?js$": "$1" - }, - "testRegex": "./src/.*\\.test\\.(ts|mjs)$", - "rootDir": "./src" - }, "dependencies": { "@aztec/accounts": "workspace:^", "@aztec/archiver": "workspace:^", 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 11b1f06b5ef6..14a1aa10195d 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -59,6 +59,10 @@ describe('e2e_ordering', () => { const expectedOrder = expectedOrders[method]; const action = parent.methods[method](child.address, pubSetValueSelector); const tx = await action.simulate(); + expect(tx.data.needsSetup).toBe(false); + expect(tx.data.needsAppLogic).toBe(true); + expect(tx.data.needsTeardown).toBe(false); + await action.send().wait(); // There are two enqueued calls 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 881f1ce6a4b0..c35e761f4c85 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 @@ -12,10 +12,11 @@ import { import { EthAddress, Header, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PublicDataUpdateRequest, PublicKernelCircuitPublicInputs, @@ -159,28 +160,28 @@ describe('L1Publisher integration', () => { prevHeader = await builderDb.buildInitialHeader(); }, 100_000); - const makeEmptyProcessedTx = async () => { - const tx = await makeEmptyProcessedTxFromHistoricalTreeRoots(prevHeader, new Fr(chainId), new Fr(config.version)); + const makeEmptyProcessedTx = () => { + const tx = makeEmptyProcessedTxFromHistoricalTreeRoots(prevHeader, new Fr(chainId), new Fr(config.version)); return tx; }; - const makeBloatedProcessedTx = async (seed = 0x1) => { + const makeBloatedProcessedTx = (seed = 0x1) => { const tx = mockTx(seed); const kernelOutput = PublicKernelCircuitPublicInputs.empty(); kernelOutput.constants.txContext.chainId = fr(chainId); kernelOutput.constants.txContext.version = fr(config.version); kernelOutput.constants.historicalHeader = prevHeader; kernelOutput.end.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(i + 10)), seed + 0x500, ); - const processedTx = await makeProcessedTx(tx, kernelOutput, makeProof()); + const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, makeNewSideEffect, seed + 0x100); + processedTx.data.end.newCommitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, makeNewSideEffect, seed + 0x100); processedTx.data.end.newNullifiers = makeTuple( - MAX_NEW_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, seed + 0x200, ); @@ -367,10 +368,10 @@ describe('L1Publisher integration', () => { // Ensure that each transaction has unique (non-intersecting nullifier values) const totalNullifiersPerBlock = 4 * MAX_NEW_NULLIFIERS_PER_TX; const txs = [ - await makeBloatedProcessedTx(totalNullifiersPerBlock * i + 1 * MAX_NEW_NULLIFIERS_PER_TX), - await makeBloatedProcessedTx(totalNullifiersPerBlock * i + 2 * MAX_NEW_NULLIFIERS_PER_TX), - await makeBloatedProcessedTx(totalNullifiersPerBlock * i + 3 * MAX_NEW_NULLIFIERS_PER_TX), - await makeBloatedProcessedTx(totalNullifiersPerBlock * i + 4 * MAX_NEW_NULLIFIERS_PER_TX), + makeBloatedProcessedTx(totalNullifiersPerBlock * i + 1 * MAX_NEW_NULLIFIERS_PER_TX), + makeBloatedProcessedTx(totalNullifiersPerBlock * i + 2 * MAX_NEW_NULLIFIERS_PER_TX), + makeBloatedProcessedTx(totalNullifiersPerBlock * i + 3 * MAX_NEW_NULLIFIERS_PER_TX), + makeBloatedProcessedTx(totalNullifiersPerBlock * i + 4 * MAX_NEW_NULLIFIERS_PER_TX), ]; const globalVariables = new GlobalVariables( @@ -450,12 +451,7 @@ describe('L1Publisher integration', () => { for (let i = 0; i < numberOfConsecutiveBlocks; i++) { const l1ToL2Messages = new Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)); - const txs = [ - await makeEmptyProcessedTx(), - await makeEmptyProcessedTx(), - await makeEmptyProcessedTx(), - await makeEmptyProcessedTx(), - ]; + const txs = [makeEmptyProcessedTx(), makeEmptyProcessedTx(), makeEmptyProcessedTx(), makeEmptyProcessedTx()]; const globalVariables = new GlobalVariables( new Fr(chainId), diff --git a/yarn-project/foundation/src/aztec-address/index.ts b/yarn-project/foundation/src/aztec-address/index.ts index bf1affc78846..665a509aa434 100644 --- a/yarn-project/foundation/src/aztec-address/index.ts +++ b/yarn-project/foundation/src/aztec-address/index.ts @@ -1,5 +1,5 @@ -import { Fr } from '../fields/index.js'; -import { FieldReader } from '../serialize/index.js'; +import { Fr, fromBuffer } from '../fields/index.js'; +import { BufferReader, FieldReader } from '../serialize/index.js'; /** * AztecAddress represents a 32-byte address in the Aztec Protocol. @@ -16,6 +16,16 @@ export class AztecAddress extends Fr { super(buffer); } + static ZERO = new AztecAddress(Buffer.alloc(32)); + + static zero(): AztecAddress { + return AztecAddress.ZERO; + } + + static fromBuffer(buffer: Buffer | BufferReader) { + return fromBuffer(buffer, AztecAddress); + } + static fromField(fr: Fr) { return new AztecAddress(fr.toBuffer()); } @@ -33,4 +43,8 @@ export class AztecAddress extends Fr { const buffer = Buffer.from(buf.replace(/^0x/i, ''), 'hex'); return new AztecAddress(buffer); } + + static random() { + return new AztecAddress(super.random().toBuffer()); + } } diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts index 1f23f5473f53..b8d2889394ba 100644 --- a/yarn-project/foundation/src/fields/fields.ts +++ b/yarn-project/foundation/src/fields/fields.ts @@ -137,7 +137,7 @@ abstract class BaseField { * Constructs a field from a Buffer of BufferReader. * It maybe not read the full 32 bytes if the Buffer is shorter, but it will padded in BaseField constructor. */ -function fromBuffer(buffer: Buffer | BufferReader, f: DerivedField) { +export function fromBuffer(buffer: Buffer | BufferReader, f: DerivedField) { const reader = BufferReader.asReader(buffer); return new f(reader.readBytes(BaseField.SIZE_IN_BYTES)); } 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 1453c66240cb..7d48571244b0 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 @@ -307,38 +307,38 @@ PrivateKernelInnerCircuitPublicInputs { }, "txsHash": { "data": [ - 127, - 68, - 156, - 248, - 136, - 121, - 60, - 103, - 107, - 155, - 13, - 60, - 48, - 171, - 39, - 215, - 135, - 22, - 172, - 186, - 205, - 226, - 60, - 4, - 101, 236, - 10, - 165, - 218, + 3, + 40, + 115, + 180, + 252, + 180, + 189, + 72, + 1, + 34, + 50, + 31, + 53, + 60, + 78, 241, - 169, - 169, + 53, + 192, + 197, + 230, + 248, + 122, + 253, + 158, + 219, + 31, + 138, + 120, + 159, + 205, + 80, ], "type": "Buffer", }, @@ -348,47 +348,47 @@ PrivateKernelInnerCircuitPublicInputs { "chainId": "0x0000000000000000000000000000000000000000000000000000000000007a69", "coinbase": "0x0000000000000000000000000000000000000000", "feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x0000000000000000000000000000000000000000000000000000000065ce39f9", + "timestamp": "0x0000000000000000000000000000000000000000000000000000000065cf686d", "version": "0x0000000000000000000000000000000000000000000000000000000000000001", }, "lastArchive": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 3, "root": Fr { - "asBigInt": 17115660199710410586602564107796716257714615299428647553586438331181005648572n, + "asBigInt": 3191694458688398827030160334619588911429761659912139897108797647195846141465n, "asBuffer": { "data": [ - 37, - 215, - 30, - 208, - 219, - 193, - 64, - 125, - 110, - 82, - 248, - 224, - 145, - 147, - 12, + 7, + 14, + 111, + 95, + 44, + 61, + 233, + 63, + 243, + 165, + 17, + 90, + 161, + 143, + 243, + 250, + 132, + 8, 232, - 10, - 162, - 207, - 77, - 192, - 214, - 181, - 202, - 50, - 245, - 108, - 178, - 155, - 89, - 178, - 188, + 220, + 95, + 43, + 169, + 139, + 225, + 57, + 230, + 15, + 92, + 78, + 230, + 25, ], "type": "Buffer", }, @@ -442,41 +442,41 @@ PrivateKernelInnerCircuitPublicInputs { "contractTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 6, "root": Fr { - "asBigInt": 3394956934880872720337221467761274343948219701992027503273572812342342019845n, + "asBigInt": 19879803462889094717689922635816884923593624253055813986768931299092005089884n, "asBuffer": { "data": [ - 7, - 129, - 122, - 63, - 113, - 25, - 46, - 105, - 149, - 61, - 222, - 21, + 43, 243, - 41, - 26, - 31, - 216, - 150, - 31, - 166, - 143, - 22, - 130, - 182, - 167, - 65, - 200, - 250, + 145, + 236, + 202, + 64, + 238, + 176, + 10, 133, - 69, - 107, - 5, + 12, + 103, + 97, + 176, + 206, + 148, + 67, + 17, + 35, + 209, + 158, + 34, + 103, + 87, + 211, + 156, + 18, + 216, + 11, + 219, + 114, + 92, ], "type": "Buffer", }, @@ -485,41 +485,41 @@ PrivateKernelInnerCircuitPublicInputs { "noteHashTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 384, "root": Fr { - "asBigInt": 12324180089219260903276888035459436817338444352369006929508757773319466544369n, + "asBigInt": 10212332784393348208757169379138640209714144078147939177550059809511932997990n, "asBuffer": { "data": [ - 27, - 63, - 61, - 29, - 228, - 32, - 34, - 232, - 146, - 241, - 245, - 211, - 31, - 52, 22, - 238, - 119, - 202, - 89, - 54, - 104, - 79, + 147, + 249, + 187, + 196, + 115, + 105, + 224, + 118, + 246, + 99, + 231, + 53, + 85, + 184, + 38, 73, - 203, - 31, - 226, - 60, - 202, - 242, - 34, + 38, + 19, + 84, + 139, + 237, + 198, + 80, + 113, + 97, + 170, + 237, + 249, 108, - 241, + 177, + 102, ], "type": "Buffer", }, @@ -528,41 +528,41 @@ PrivateKernelInnerCircuitPublicInputs { "nullifierTree": AppendOnlyTreeSnapshot { "nextAvailableLeafIndex": 512, "root": Fr { - "asBigInt": 14322226819626434480880701356706147172891363659154382350309030813254657125319n, + "asBigInt": 21598862378663535358411803362076977893277517684249043328346384835647907429886n, "asBuffer": { "data": [ - 31, - 170, - 23, - 214, - 27, - 230, - 149, - 52, - 195, - 189, - 208, - 18, - 36, - 91, - 196, - 43, - 183, - 9, - 216, - 88, - 157, - 239, - 99, - 64, - 64, - 36, + 47, + 192, + 133, + 219, + 211, + 241, + 54, + 15, + 87, + 244, + 110, + 190, + 238, + 10, + 233, + 179, + 90, + 254, + 121, + 114, + 235, 242, + 184, + 126, + 245, + 112, 247, - 226, - 170, - 43, + 93, 199, + 149, + 253, + 254, ], "type": "Buffer", }, @@ -6581,41 +6581,41 @@ PrivateKernelInnerCircuitPublicInputs { }, }, "value": Fr { - "asBigInt": 11129411464156243609075243086946674064914204346304566604535349066932751210923n, + "asBigInt": 10180848212623469218504863627736108057194547865828801844563507743979722674170n, "asBuffer": { "data": [ + 22, + 130, + 39, + 232, 24, - 155, - 6, - 14, + 67, + 130, + 158, + 220, + 73, + 145, + 1, + 225, + 82, + 145, + 180, + 186, + 179, + 51, + 122, + 194, 144, - 84, - 212, - 58, - 107, - 15, - 100, - 89, - 191, - 195, - 59, - 10, - 90, - 13, - 215, - 203, - 13, - 36, - 151, - 231, - 200, + 159, + 80, + 167, + 115, + 243, + 236, + 21, + 162, + 143, 250, - 122, - 58, - 170, - 244, - 153, - 171, ], "type": "Buffer", }, @@ -32160,8 +32160,8 @@ PrivateKernelInnerCircuitPublicInputs { ], }, "isPrivate": true, - "maxNonRevertibleSideEffectCounter": Fr { - "asBigInt": 0n, + "minRevertibleSideEffectCounter": Fr { + "asBigInt": 3n, "asBuffer": { "data": [ 0, @@ -32195,7 +32195,7 @@ PrivateKernelInnerCircuitPublicInputs { 0, 0, 0, - 0, + 3, ], "type": "Buffer", }, @@ -32860,41 +32860,41 @@ PrivateKernelTailCircuitPublicInputs { }, "contractDeploymentData": ContractDeploymentData { "contractAddressSalt": Fr { - "asBigInt": 16449655160940881004159092029040257549656271843508463611868355410696701098934n, + "asBigInt": 9953078929652437104409727219576914993733417944657919773690205897032392967704n, "asBuffer": { "data": [ - 36, - 94, - 44, - 196, - 255, - 25, - 248, - 7, - 239, - 65, - 75, - 80, - 165, - 163, - 122, - 53, - 85, - 137, - 245, - 219, - 66, - 231, - 72, - 16, - 144, + 22, + 1, + 62, + 55, + 215, + 104, + 189, + 148, + 3, + 228, + 97, + 214, + 107, + 168, 111, - 206, - 164, - 124, - 46, - 59, - 182, + 72, + 217, + 44, + 38, + 29, + 56, + 102, + 118, + 5, + 160, + 69, + 4, + 183, + 87, + 191, + 6, + 24, ], "type": "Buffer", }, @@ -32940,41 +32940,41 @@ PrivateKernelTailCircuitPublicInputs { }, }, "initializationHash": Fr { - "asBigInt": 9897941655918668326117354958048861857798978787215297876291649298962997189209n, + "asBigInt": 5199569776792506059242690538032118970505807265061384810858739766861112502725n, "asBuffer": { "data": [ - 21, - 226, - 9, - 84, - 177, - 90, - 136, - 21, - 114, 11, + 126, + 218, + 41, + 248, + 86, + 161, + 42, + 125, + 143, 166, - 192, 170, + 174, + 242, + 167, 49, - 171, - 157, - 182, - 111, - 51, - 92, - 48, - 228, - 150, - 116, - 130, - 85, - 245, - 209, - 237, - 166, - 26, - 89, + 25, + 37, + 146, + 255, + 129, + 178, + 3, + 232, + 218, + 78, + 46, + 194, + 224, + 159, + 105, + 197, ], "type": "Buffer", }, @@ -33009,81 +33009,81 @@ PrivateKernelTailCircuitPublicInputs { "publicKey": Point { "kind": "point", "x": Fr { - "asBigInt": 11873960173015210040086294901568624593890870942366256174390060791254677352437n, + "asBigInt": 13561107487230884082737576024237471633099838481529282376039290602742111590162n, "asBuffer": { "data": [ - 26, - 64, - 108, - 93, - 17, - 81, - 213, - 193, - 181, - 152, - 99, - 214, + 29, + 251, + 80, + 153, + 4, + 136, + 2, + 238, + 187, + 2, + 39, + 162, + 117, + 38, + 94, + 34, + 11, + 192, + 211, 190, - 222, - 168, + 105, + 252, + 40, + 229, + 94, + 223, + 66, + 209, + 251, + 140, 215, - 45, - 255, - 97, - 148, - 70, - 70, - 63, - 195, - 226, - 205, - 164, - 73, - 119, - 150, - 111, - 245, + 18, ], "type": "Buffer", }, }, "y": Fr { - "asBigInt": 3532371157289644824573602409981516997911013774842077424929447513908749340515n, + "asBigInt": 6324513328887726568104093920077418860626288877507412009569537011690604983762n, "asBuffer": { "data": [ + 13, + 251, + 140, + 53, + 101, + 106, + 11, + 1, + 111, 7, + 169, + 2, + 26, + 189, + 219, + 46, 207, - 64, + 67, + 162, + 154, + 249, + 183, 80, + 123, + 202, + 68, 59, - 54, - 54, - 45, - 183, - 242, - 18, - 178, - 31, - 158, - 36, - 170, - 168, - 15, - 242, - 5, - 151, - 188, - 77, - 144, - 251, - 83, - 173, - 46, - 146, - 241, - 15, - 99, + 121, + 71, + 161, + 245, + 210, ], "type": "Buffer", }, @@ -33135,7 +33135,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - "end": FinalAccumulatedData { + "end": PrivateAccumulatedRevertibleData { "encryptedLogPreimagesLength": Fr { "asBigInt": 280n, "asBuffer": { @@ -33178,7 +33178,7 @@ PrivateKernelTailCircuitPublicInputs { }, "encryptedLogsHash": [ Fr { - "asBigInt": 209439645713937693790483103927790440284n, + "asBigInt": 269439869033622163450729375820816950931n, "asBuffer": { "data": [ 0, @@ -33197,28 +33197,28 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 157, - 144, - 155, - 200, - 28, - 240, - 20, - 42, - 145, - 168, - 48, - 78, - 92, - 67, - 143, - 92, + 202, + 180, + 59, + 47, + 208, + 223, + 34, + 79, + 189, + 213, + 95, + 147, + 39, + 53, + 166, + 147, ], "type": "Buffer", }, }, Fr { - "asBigInt": 191802798440418019544179515693881494574n, + "asBigInt": 253112633582138088262162443407797065852n, "asBuffer": { "data": [ 0, @@ -33237,22 +33237,22 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 144, - 75, - 224, - 19, - 57, - 225, - 224, - 235, - 199, - 169, - 111, - 44, - 233, - 202, - 12, - 46, + 190, + 107, + 184, + 84, + 1, + 247, + 7, + 0, + 66, + 130, + 39, + 69, + 131, + 49, + 24, + 124, ], "type": "Buffer", }, @@ -33301,1845 +33301,41 @@ PrivateKernelTailCircuitPublicInputs { }, }, "value": Fr { - "asBigInt": 17121188194577594238359208834433075615654415033361078812014833251046685799145n, + "asBigInt": 8767699493397561566233600994243971419703065668153922121137346128681280575026n, "asBuffer": { "data": [ - 37, - 218, - 63, - 197, - 149, - 131, - 178, - 172, - 122, - 107, - 163, - 249, - 247, - 13, - 44, - 4, - 196, - 118, 19, - 188, - 108, - 188, + 98, + 87, + 144, + 226, + 5, + 57, + 204, + 12, + 183, + 58, + 201, + 245, + 220, + 184, + 120, + 95, + 251, + 249, + 86, + 110, + 1, + 38, + 91, + 18, + 60, + 72, + 83, + 246, 113, - 186, - 70, - 37, - 149, - 237, - 71, - 101, - 242, - 233, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - SideEffect { - "counter": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 150, + 50, ], "type": "Buffer", }, @@ -38507,202 +36703,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - ], - "newContracts": [ - NewContractData { - "contractAddress": AztecAddress { - "asBigInt": 10943932243304071850461020351463699141394130558691702827213021214718844082123n, - "asBuffer": { - "data": [ - 24, - 50, - 11, - 207, - 229, - 76, - 127, - 168, - 92, - 91, - 42, - 20, - 49, - 236, - 170, - 243, - 76, - 115, - 80, - 91, - 69, - 114, - 123, - 110, - 10, - 250, - 7, - 46, - 79, - 202, - 23, - 203, - ], - "type": "Buffer", - }, - }, - "contractClassId": Fr { - "asBigInt": 2765999012159059061873056919167049901904093580059050493452992383935413898989n, - "asBuffer": { - "data": [ - 6, - 29, - 127, - 253, - 124, - 169, - 57, - 10, - 109, - 22, - 247, - 17, - 81, - 61, - 125, - 59, - 43, - 86, - 48, - 70, - 73, - 163, - 185, - 190, - 84, - 219, - 181, - 253, - 159, - 214, - 78, - 237, - ], - "type": "Buffer", - }, - }, - "portalContractAddress": EthAddress { - "buffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - ], - "newL2ToL1Msgs": [ - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -38743,7 +36744,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -38783,50 +36784,10 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 21274471018812848289894532688672135116647896144887463048205111089835005632472n, - "asBuffer": { - "data": [ - 47, - 8, - 236, - 131, - 142, - 87, - 68, - 92, - 64, - 182, - 132, - 74, - 121, - 47, - 220, - 186, - 14, - 156, - 100, - 93, - 122, - 55, - 169, - 34, - 76, - 104, - 105, - 150, - 153, - 190, - 223, - 216, - ], - "type": "Buffer", - }, - }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { - "asBigInt": 1n, + "asBigInt": 0n, "asBuffer": { "data": [ 0, @@ -38860,12 +36821,12 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 1, + 0, ], "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -38905,50 +36866,10 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 109016771386827246258860385676505471190002204621636322306905730406963027107n, - "asBuffer": { - "data": [ - 0, - 61, - 179, - 136, - 202, - 32, - 172, - 33, - 193, - 228, - 109, - 63, - 218, - 53, - 130, - 157, - 86, - 176, - 37, - 12, - 107, - 133, - 43, - 125, - 2, - 137, - 184, - 219, - 128, - 21, - 28, - 163, - ], - "type": "Buffer", - }, - }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { - "asBigInt": 2n, + "asBigInt": 0n, "asBuffer": { "data": [ 0, @@ -38982,12 +36903,12 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 2, + 0, ], "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39027,48 +36948,8 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 6181741276872238912292671589703618001577993427695450609839852759586221859621n, - "asBuffer": { - "data": [ - 13, - 170, - 189, - 215, - 169, - 76, - 206, - 121, - 249, - 206, - 74, - 210, - 140, - 200, - 229, - 94, - 249, - 68, - 125, - 51, - 148, - 213, - 37, - 58, - 9, - 63, - 190, - 245, - 36, - 236, - 35, - 37, - ], - "type": "Buffer", - }, - }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -39109,7 +36990,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39149,7 +37030,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39189,9 +37072,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffectLinkedToNoteHash { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39231,7 +37112,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39312,7 +37195,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -39353,46 +37236,6 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, "value": Fr { "asBigInt": 0n, "asBuffer": { @@ -39434,7 +37277,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -39475,46 +37318,6 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, "value": Fr { "asBigInt": 0n, "asBuffer": { @@ -39556,7 +37359,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -39597,7 +37400,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39637,7 +37440,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39677,9 +37482,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffectLinkedToNoteHash { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39719,7 +37522,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39800,7 +37605,7 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { + SideEffect { "counter": Fr { "asBigInt": 0n, "asBuffer": { @@ -39841,7 +37646,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39881,7 +37686,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39921,9 +37728,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffectLinkedToNoteHash { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -39963,7 +37768,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -40044,90 +37851,91 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { - "counter": Fr { - "asBigInt": 0n, + ], + "newContracts": [ + NewContractData { + "contractAddress": AztecAddress { + "asBigInt": 8673888678031921888204072884922625182692453803000189988860512202670674651744n, "asBuffer": { "data": [ + 19, + 45, + 63, + 60, + 89, + 110, + 87, + 38, + 153, + 36, + 88, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 227, + 95, + 146, + 182, + 11, + 164, + 9, + 201, + 127, + 8, + 104, + 124, + 175, + 201, + 36, + 243, + 161, + 1, + 170, + 96, ], "type": "Buffer", }, }, - "noteHash": Fr { - "asBigInt": 0n, + "contractClassId": Fr { + "asBigInt": 2765999012159059061873056919167049901904093580059050493452992383935413898989n, "asBuffer": { "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 6, + 29, + 127, + 253, + 124, + 169, + 57, + 10, + 109, + 22, + 247, + 17, + 81, + 61, + 125, + 59, + 43, + 86, + 48, + 70, + 73, + 163, + 185, + 190, + 84, + 219, + 181, + 253, + 159, + 214, + 78, + 237, ], "type": "Buffer", }, }, - "value": Fr { - "asBigInt": 0n, - "asBuffer": { + "portalContractAddress": EthAddress { + "buffer": { "data": [ 0, 0, @@ -40149,26 +37957,98 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, ], "type": "Buffer", }, }, }, + ], + "newL2ToL1Msgs": [ + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + ], + "newNullifiers": [ SideEffectLinkedToNoteHash { "counter": Fr { - "asBigInt": 0n, + "asBigInt": 2n, "asBuffer": { "data": [ 0, @@ -40202,7 +38082,7 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 0, + 2, ], "type": "Buffer", }, @@ -40248,41 +38128,41 @@ PrivateKernelTailCircuitPublicInputs { }, }, "value": Fr { - "asBigInt": 0n, + "asBigInt": 11056877638529911965311649281265139893863006080406008749701826820558787833712n, "asBuffer": { "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 24, + 113, + 248, + 145, + 113, + 60, + 198, + 114, + 90, + 114, + 130, + 152, + 139, + 26, + 254, + 130, + 172, + 108, + 232, + 85, + 80, + 166, + 243, + 186, + 10, + 230, + 205, + 173, + 146, + 125, + 239, + 112, ], "type": "Buffer", }, @@ -46510,132 +44390,8 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - ], - "privateCallStack": [ - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "storageContractAddress": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - "callerContractAddress": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "endSideEffectCounter": Fr { + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46675,7 +44431,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "hash": Fr { + "noteHash": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46715,7 +44471,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "startSideEffectCounter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46756,90 +44512,8 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "storageContractAddress": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - }, - "callerContractAddress": AztecAddress { + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46879,7 +44553,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "endSideEffectCounter": Fr { + "noteHash": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46919,7 +44593,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "hash": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46959,7 +44633,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "startSideEffectCounter": Fr { + }, + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -46999,91 +44675,47 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - CallRequest { - "callerContext": CallerContext { - "msgSender": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, - }, - "storageContractAddress": AztecAddress { - "asBigInt": 0n, - "asBuffer": { - "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - ], - "type": "Buffer", - }, + "noteHash": Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", }, }, - "callerContractAddress": AztecAddress { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -47123,7 +44755,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "endSideEffectCounter": Fr { + }, + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -47163,7 +44797,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "hash": Fr { + "noteHash": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -47203,7 +44837,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "startSideEffectCounter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -47244,6 +44878,8 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, + ], + "privateCallStack": [ CallRequest { "callerContext": CallerContext { "msgSender": AztecAddress { @@ -48464,8 +46100,6 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - ], - "publicCallStack": [ CallRequest { "callerContext": CallerContext { "msgSender": AztecAddress { @@ -49198,6 +46832,8 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, + ], + "publicCallStack": [ CallRequest { "callerContext": CallerContext { "msgSender": AztecAddress { @@ -50542,7 +48178,7 @@ PrivateKernelTailCircuitPublicInputs { }, ], }, - "endNonRevertibleData": AccumulatedNonRevertibleData { + "endNonRevertibleData": PrivateAccumulatedNonRevertibleData { "newCommitments": [ SideEffect { "counter": Fr { @@ -50749,7 +48385,49 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + "value": Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50789,9 +48467,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50831,7 +48507,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50871,9 +48549,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50913,7 +48589,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50953,9 +48631,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -50995,7 +48671,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51035,9 +48713,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51077,7 +48753,9 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + SideEffect { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51117,9 +48795,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - SideEffect { - "counter": Fr { + "value": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51159,7 +48835,11 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + }, + ], + "newNullifiers": [ + SideEffectLinkedToNoteHash { + "counter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51199,11 +48879,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - }, - ], - "newNullifiers": [ - SideEffectLinkedToNoteHash { - "counter": Fr { + "noteHash": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51243,8 +48919,50 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { - "asBigInt": 0n, + "value": Fr { + "asBigInt": 1720186267580687512325977995485491727892655959456478664143986840513076341841n, + "asBuffer": { + "data": [ + 3, + 205, + 151, + 70, + 215, + 35, + 91, + 60, + 96, + 66, + 51, + 62, + 235, + 136, + 214, + 145, + 87, + 144, + 141, + 18, + 253, + 210, + 233, + 235, + 222, + 172, + 74, + 87, + 101, + 189, + 44, + 81, + ], + "type": "Buffer", + }, + }, + }, + SideEffectLinkedToNoteHash { + "counter": Fr { + "asBigInt": 1n, "asBuffer": { "data": [ 0, @@ -51278,12 +48996,12 @@ PrivateKernelTailCircuitPublicInputs { 0, 0, 0, - 0, + 1, ], "type": "Buffer", }, }, - "value": Fr { + "noteHash": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -51323,6 +49041,46 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, + "value": Fr { + "asBigInt": 155132481437249853091322497299232935465038155153165489040892003777899112412n, + "asBuffer": { + "data": [ + 0, + 87, + 205, + 71, + 139, + 14, + 35, + 148, + 139, + 154, + 71, + 53, + 34, + 187, + 252, + 44, + 247, + 80, + 55, + 124, + 65, + 84, + 48, + 213, + 75, + 68, + 39, + 46, + 84, + 59, + 167, + 220, + ], + "type": "Buffer", + }, + }, }, SideEffectLinkedToNoteHash { "counter": Fr { @@ -52056,8 +49814,92 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - SideEffectLinkedToNoteHash { - "counter": Fr { + ], + "publicCallStack": [ + CallRequest { + "callerContext": CallerContext { + "msgSender": AztecAddress { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + "storageContractAddress": AztecAddress { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + }, + "callerContractAddress": AztecAddress { "asBigInt": 0n, "asBuffer": { "data": [ @@ -52097,7 +49939,7 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "noteHash": Fr { + "endSideEffectCounter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -52137,7 +49979,47 @@ PrivateKernelTailCircuitPublicInputs { "type": "Buffer", }, }, - "value": Fr { + "hash": Fr { + "asBigInt": 0n, + "asBuffer": { + "data": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + "type": "Buffer", + }, + }, + "startSideEffectCounter": Fr { "asBigInt": 0n, "asBuffer": { "data": [ @@ -52178,8 +50060,6 @@ PrivateKernelTailCircuitPublicInputs { }, }, }, - ], - "publicCallStack": [ CallRequest { "callerContext": CallerContext { "msgSender": AztecAddress { @@ -52670,6 +50550,8 @@ PrivateKernelTailCircuitPublicInputs { }, ], }, - "isPrivate": true, + "needsAppLogic": false, + "needsSetup": false, + "needsTeardown": false, } `; 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 e0ed6a517d77..4caeaf8766d7 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 @@ -18320bcfe54c7fa85c5b2a1431ecaaf34c73505b45727b6e0afa072e4fca17cbaf9f8c4400010103c02b1f180b2dd6bbdd69d533344ec28c6e2335a519cda5e0dd0773ef976dfb0000011a406c5d1151d5c1b59863d6bedea8d72dff619446463fc3e2cda44977966ff507cf40503b36362db7f212b21f9e24aaa80ff20597bc4d90fb53ad2e92f10f6315e20954b15a8815720ba6c0aa31ab9db66f335c30e496748255f5d1eda61a59061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed245e2cc4ff19f807ef414b50a5a37a355589f5db42e74810906fcea47c2e3bb600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000118320bcfe54c7fa85c5b2a1431ecaaf34c73505b45727b6e0afa072e4fca17cbaf9f8c44000101000000000000000000000000000000000000000000000000000000000000000018320bcfe54c7fa85c5b2a1431ecaaf34c73505b45727b6e0afa072e4fca17cb0000000000000000000000000000000000000000af9f8c440000010000000203c02b1f180b2dd6bbdd69d533344ec28c6e2335a519cda5e0dd0773ef976dfb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026e5d3b69e669eed93d3830412440715b55310bae5f62dccd2228aa1898c0a92000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003579f468b2283611cc4d7adfbb93b8a4815d93ac0b1e1d11dace012cf73c7aa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000e803dd26685a1a81a3efa2300f50e4c100000000000000000000000000000000229bdb7c7deffd1d4ff7b56b78b67c4b00000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b8550000000000000000000000000000000000000000000000000000000000000118000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a406c5d1151d5c1b59863d6bedea8d72dff619446463fc3e2cda44977966ff507cf40503b36362db7f212b21f9e24aaa80ff20597bc4d90fb53ad2e92f10f6315e20954b15a8815720ba6c0aa31ab9db66f335c30e496748255f5d1eda61a59061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed245e2cc4ff19f807ef414b50a5a37a355589f5db42e74810906fcea47c2e3bb600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0cdf0a064028dac87855bfa61ef1fd9cf2f1142142b750a3eb719019b7c5045b1dc6af9f2c4d0113c726cd66d90d9cca89b90bff3a5c3bf767644aab6aac7c551b594fd8073006bafc2a732dc31ccd75394f1049b1bb95429b6474f6a8659b182c43c93b690b3649150e9bee6aa2e7a81858bf15753d5079053ee896ccdae42400000000000000000000000000000000000000000000000000000000000000011d81e3a46dc51e14eefa4573af363bc3075d859d28d9ee73c545eceaf429ccc91fd163e98c3058b28c0c78a7cea427a8d86699c79c4cf9eeeeca2dc63288c0850bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +132d3f3c596e572699245800e35f92b60ba409c97f08687cafc924f3a101aa60af9f8c440001010bd75e56af5bbdc945a6a106be6bb88b2736520ca7b5858680387a1b78a1f1ca0000011dfb5099048802eebb0227a275265e220bc0d3be69fc28e55edf42d1fb8cd7120dfb8c35656a0b016f07a9021abddb2ecf43a29af9b7507bca443b7947a1f5d20b7eda29f856a12a7d8fa6aaaef2a731192592ff81b203e8da4e2ec2e09f69c5061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed16013e37d768bd9403e461d66ba86f48d92c261d38667605a04504b757bf061800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001132d3f3c596e572699245800e35f92b60ba409c97f08687cafc924f3a101aa60af9f8c440001010000000000000000000000000000000000000000000000000000000000000000132d3f3c596e572699245800e35f92b60ba409c97f08687cafc924f3a101aa600000000000000000000000000000000000000000af9f8c44000001000000020bd75e56af5bbdc945a6a106be6bb88b2736520ca7b5858680387a1b78a1f1ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b06834b16f74df937753e944d934795c4966031536d5b35d1c5d3cff0d10c31000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003579f468b2283611cc4d7adfbb93b8a4815d93ac0b1e1d11dace012cf73c7aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000b506ee763397cefffdec2e9826773f300000000000000000000000000000000c1f20207f729e56e62c3062cd9b78c4e00000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b8550000000000000000000000000000000000000000000000000000000000000118000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001dfb5099048802eebb0227a275265e220bc0d3be69fc28e55edf42d1fb8cd7120dfb8c35656a0b016f07a9021abddb2ecf43a29af9b7507bca443b7947a1f5d20b7eda29f856a12a7d8fa6aaaef2a731192592ff81b203e8da4e2ec2e09f69c5061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed16013e37d768bd9403e461d66ba86f48d92c261d38667605a04504b757bf061800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0cdf0a064028dac87855bfa61ef1fd9cf2f1142142b750a3eb719019b7c5045b1dc6af9f2c4d0113c726cd66d90d9cca89b90bff3a5c3bf767644aab6aac7c551d8d974c3ba4aeaef3a2939668949e0af6912c5f92378c6c8aca5cf816eddc6829f6e0f3f081753c5217289df2108de4fe3165b99dcf32e4cac4e73f7bcac56600000000000000000000000000000000000000000000000000000000000000011d81e3a46dc51e14eefa4573af363bc3075d859d28d9ee73c545eceaf429ccc91fd163e98c3058b28c0c78a7cea427a8d86699c79c4cf9eeeeca2dc63288c0850bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ 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 a2b90c640e5f..b38c2d617d6f 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 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000189b060e9054d43a6b0f6459bfc33b0a5a0dd7cb0d2497e7c8fa7a3aaaf499ab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b5773d03649995db087557315bfae29865bc158424fbccb135b3c68125e1d77150ec976ba46bcdd556ddc98ed9d953f03abc99f3fae2f5fd31111e40e6b922d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025d71ed0dbc1407d6e52f8e091930ce80aa2cf4dc0d6b5ca32f56cb29b59b2bc0000000300000000000000000000000000000000000000000000000000000000000000017f449cf888793c676b9b0d3c30ab27d78716acbacde23c0465ec0aa5daf1a9a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301b3f3d1de42022e892f1f5d31f3416ee77ca5936684f49cb1fe23ccaf2226cf1000001801faa17d61be69534c3bdd012245bc42bb709d8589def63404024f2f7e2aa2bc70000020007817a3f71192e69953dde15f3291a1fd8961fa68f1682b6a741c8fa85456b05000000061ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000065ce39f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000000f87ee100926291872c3c99ceb34d020c4dad58ae1ff17516f462813db33ebba2e9b763706adea49b05226133cbc05aeba828e6e4e94e6e4ab116495c83392b50af9e9002e30973fbe14cf397e295981fb0b6eeb8478b796fb849bf5167088c20c2ccf5b640c3d3b323d52033afe7ed2ed1f0f83b33fd328410f5605cf2e83a80906bca1000100150ec976ba46bcdd556ddc98ed9d953f03abc99f3fae2f5fd31111e40e6b922d0c2ccf5b640c3d3b323d52033afe7ed2ed1f0f83b33fd328410f5605cf2e83a800000000000000000000000000000000000000000906bca100000000000004173812cb2d7243dc1f635ed13d44b8e073ca8d9471192fa4b324986ebe9595100000000000000000000000000000000000000000000000000000000000007a6a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b8550000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000425d71ed0dbc1407d6e52f8e091930ce80aa2cf4dc0d6b5ca32f56cb29b59b2bc0000000300000000000000000000000000000000000000000000000000000000000000017f449cf888793c676b9b0d3c30ab27d78716acbacde23c0465ec0aa5daf1a9a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301b3f3d1de42022e892f1f5d31f3416ee77ca5936684f49cb1fe23ccaf2226cf1000001801faa17d61be69534c3bdd012245bc42bb709d8589def63404024f2f7e2aa2bc70000020007817a3f71192e69953dde15f3291a1fd8961fa68f1682b6a741c8fa85456b05000000061ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000065ce39f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f1c874c46448f9800a6e0b255dbb85694c7f87aa05ab4f3ceb6fc4c7c4d1098802ed914d2af6aefbfd556c00f2b51d12e833c1e29e61f260a7b185a2c45f4de0b27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed0264a50669832dd1152e361977fa1ec0107499a373fdb8723f7b69b5761abd8600000000000000000000000000000000000000000000000000000000000000001e53e2a4a2ea07593ada9539cab59e6f37d7a01d7d402c51c3d2eb337a960dec2daefd8c101018a4a3a076131a4d44d9ed900dbe3b3bee5f88d8de8ba4bcb76a1696a166ff19126c9aae06722ae10ebda42f3638167ae5c0597e1a290e3bc7ff06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000168227e81843829edc499101e15291b4bab3337ac2909f50a773f3ec15a28ffa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f8b3e8e76a45764fb4f693062f3adac46bb923dac9386676cc863b83dd9305028982c454c4954c94e12a41dd6d1deb6bb5a7284f2d87c3259d4921a6bd308e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070e6f5f2c3de93ff3a5115aa18ff3fa8408e8dc5f2ba98be139e60f5c4ee619000000030000000000000000000000000000000000000000000000000000000000000001ec032873b4fcb4bd480122321f353c4ef135c0c5e6f87afd9edb1f8a789fcd50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301693f9bbc47369e076f663e73555b826492613548bedc6507161aaedf96cb166000001802fc085dbd3f1360f57f46ebeee0ae9b35afe7972ebf2b87ef570f75dc795fdfe000002002bf391ecca40eeb00a850c6761b0ce94431123d19e226757d39c12d80bdb725c000000061ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000065cf686d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000001b87716f8f8a51f4a6c2a111f4e1feef2a9a4579627cd82854145c0e3c9969cb18205ab791ebb61971077a74de3a5eb72e1ae0566e3481e527ec3bba33bd18b1084a3c95ff5cfecc898219e4ef5864a8dcc0c75f5d374704a6ac1415e01961be1d5e498ab554c2230f52184e2a60ab86ef3daacb6f9491755dc914936cca4e290906bca1000100028982c454c4954c94e12a41dd6d1deb6bb5a7284f2d87c3259d4921a6bd308e1d5e498ab554c2230f52184e2a60ab86ef3daacb6f9491755dc914936cca4e2900000000000000000000000000000000000000000906bca100000000000004173812cb2d7243dc1f635ed13d44b8e073ca8d9471192fa4b324986ebe9595100000000000000000000000000000000000000000000000000000000000007a6a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004070e6f5f2c3de93ff3a5115aa18ff3fa8408e8dc5f2ba98be139e60f5c4ee619000000030000000000000000000000000000000000000000000000000000000000000001ec032873b4fcb4bd480122321f353c4ef135c0c5e6f87afd9edb1f8a789fcd50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000301693f9bbc47369e076f663e73555b826492613548bedc6507161aaedf96cb166000001802fc085dbd3f1360f57f46ebeee0ae9b35afe7972ebf2b87ef570f75dc795fdfe000002002bf391ecca40eeb00a850c6761b0ce94431123d19e226757d39c12d80bdb725c000000061ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000800000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000065cf686d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a690000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f1c874c46448f9800a6e0b255dbb85694c7f87aa05ab4f3ceb6fc4c7c4d10988022e01772067e948ed8ed7de50eb88b760b0d692ae3ba2644380b4c2749f7ff9527b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed116cf145bffe3709c3bbb8a57e6fabd7bb78bbf15266a3e3d7766c11d74a2d4b00000000000000000000000000000000000000000000000000000000000000001e53e2a4a2ea07593ada9539cab59e6f37d7a01d7d402c51c3d2eb337a960dec2daefd8c101018a4a3a076131a4d44d9ed900dbe3b3bee5f88d8de8ba4bcb76a1696a166ff19126c9aae06722ae10ebda42f3638167ae5c0597e1a290e3bc7ff06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ 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 b1e9b8a6dba5..e54c87fb8dbc 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 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016c6b290fd6873f3e41ade6c6e88f9a7f9befd1808c0f0d88dde9b56d45ac03f00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f08ec838e57445c40b6844a792fdcba0e9c645d7a37a9224c68699699bedfd8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000daabdd7a94cce79f9ce4ad28cc8e55ef9447d3394d5253a093fbef524ec232500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002003db388ca20ac21c1e46d3fda35829d56b0250c6b852b7d0289b8db80151ca30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009d909bc81cf0142a91a8304e5c438f5c00000000000000000000000000000000904be01339e1e0ebc7a96f2ce9ca0c2e000000000000000000000000000000001c9ecec90e28d2461650418635878a5c0000000000000000000000000000000091e49f47586ecf75f2b0cbb94e8971120000000000000000000000000000000000000000000000000000000000000118000000000000000000000000000000000000000000000000000000000000000418320bcfe54c7fa85c5b2a1431ecaaf34c73505b45727b6e0afa072e4fca17cb0000000000000000000000000000000000000000061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011a406c5d1151d5c1b59863d6bedea8d72dff619446463fc3e2cda44977966ff507cf40503b36362db7f212b21f9e24aaa80ff20597bc4d90fb53ad2e92f10f6315e20954b15a8815720ba6c0aa31ab9db66f335c30e496748255f5d1eda61a59061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed245e2cc4ff19f807ef414b50a5a37a355589f5db42e74810906fcea47c2e3bb600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f00000000242af0ce4d1aa2b0f40d867d44093bcd62d4415fe950c08dfae09ba7d3ab6a8414876df7ee73e63c0f2b9efe4ce8adb4b1f213d49d36d309a732c77f2a3a026702e011b010bebb94432b79489ee255bfe46e20a155e221327c213f552199565b16c6b290fd6873f3e41ade6c6e88f9a7f9befd1808c0f0d88dde9b56d45ac03f0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f08ec838e57445c40b6844a792fdcba0e9c645d7a37a9224c68699699bedfd800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003db388ca20ac21c1e46d3fda35829d56b0250c6b852b7d0289b8db80151ca3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010daabdd7a94cce79f9ce4ad28cc8e55ef9447d3394d5253a093fbef524ec232500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000001000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e73ca660d82979c8a289ed250dcb37ebe0708851901f0b8e7f713fa77558a2000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003cd9746d7235b3c6042333eeb88d69157908d12fdd2e9ebdeac4a5765bd2c51000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001871f891713cc6725a7282988b1afe82ac6ce85550a6f3ba0ae6cdad927def70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020057cd478b0e23948b9a473522bbfc2cf750377c415430d54b44272e543ba7dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cab43b2fd0df224fbdd55f932735a69300000000000000000000000000000000be6bb85401f70700428227458331187c000000000000000000000000000000001c9ecec90e28d2461650418635878a5c0000000000000000000000000000000091e49f47586ecf75f2b0cbb94e89711200000000000000000000000000000000000000000000000000000000000001180000000000000000000000000000000000000000000000000000000000000004132d3f3c596e572699245800e35f92b60ba409c97f08687cafc924f3a101aa600000000000000000000000000000000000000000061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f800000000016642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb000000000bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278000000801864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011dfb5099048802eebb0227a275265e220bc0d3be69fc28e55edf42d1fb8cd7120dfb8c35656a0b016f07a9021abddb2ecf43a29af9b7507bca443b7947a1f5d20b7eda29f856a12a7d8fa6aaaef2a731192592ff81b203e8da4e2ec2e09f69c5061d7ffd7ca9390a6d16f711513d7d3b2b56304649a3b9be54dbb5fd9fd64eed16013e37d768bd9403e461d66ba86f48d92c261d38667605a04504b757bf061800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f00000000150f830aae4f10618e4b7476f955a51ec7d770ae996793710b8c6115f99bc79c0bb8877684874274e472f386652e70bcbef456d75cc453df931bf5330ffc2259041c035c6c8b916924b132b6ebf6e71d4d75378f903afcb50c3e08268e64660c00e73ca660d82979c8a289ed250dcb37ebe0708851901f0b8e7f713fa77558a20000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003cd9746d7235b3c6042333eeb88d69157908d12fdd2e9ebdeac4a5765bd2c51000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057cd478b0e23948b9a473522bbfc2cf750377c415430d54b44272e543ba7dc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011871f891713cc6725a7282988b1afe82ac6ce85550a6f3ba0ae6cdad927def7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000001000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f000000300000003100000032000000330000003400000035000000360000003700000038000000390000003a0000003b0000003c0000003d0000003e0000003f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ 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 d544a9d3af9f..3389821ab555 100644 --- a/yarn-project/noir-protocol-circuits-types/src/index.ts +++ b/yarn-project/noir-protocol-circuits-types/src/index.ts @@ -23,10 +23,12 @@ 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 PublicKernelPublicPreviousJson from './target/public_kernel_app_logic.json' assert { type: 'json' }; -import PublicKernelPublicPreviousSimulatedJson from './target/public_kernel_app_logic_simulated.json' assert { type: 'json' }; -import PublicKernelPrivatePreviousJson from './target/public_kernel_setup.json' assert { type: 'json' }; -import PublicKernelPrivatePreviousSimulatedJson from './target/public_kernel_setup_simulated.json' assert { type: 'json' }; +import PublicKernelAppLogicJson from './target/public_kernel_app_logic.json' assert { type: 'json' }; +import PublicKernelAppLogicSimulatedJson from './target/public_kernel_app_logic_simulated.json' assert { type: 'json' }; +import PublicKernelSetupJson from './target/public_kernel_setup.json' assert { type: 'json' }; +import PublicKernelSetupSimulatedJson from './target/public_kernel_setup_simulated.json' assert { type: 'json' }; +import PublicKernelTeardownJson from './target/public_kernel_teardown.json' assert { type: 'json' }; +import PublicKernelTeardownSimulatedJson from './target/public_kernel_teardown_simulated.json' assert { type: 'json' }; import BaseRollupSimulatedJson from './target/rollup_base_simulated.json' assert { type: 'json' }; import MergeRollupJson from './target/rollup_merge.json' assert { type: 'json' }; import RootRollupJson from './target/rollup_root.json' assert { type: 'json' }; @@ -78,11 +80,13 @@ export const PrivateKernelInitArtifact = PrivateKernelInitJson as NoirCompiledCi export const PrivateKernelInnerArtifact = PrivateKernelInnerJson as NoirCompiledCircuit; -export const PrivateKernelOrderingArtifact = PrivateKernelTailJson as NoirCompiledCircuit; +export const PrivateKernelTailArtifact = PrivateKernelTailJson as NoirCompiledCircuit; -export const PublicKernelPrivatePreviousArtifact = PublicKernelPrivatePreviousJson as NoirCompiledCircuit; +export const PublicKernelSetupArtifact = PublicKernelSetupJson as NoirCompiledCircuit; -export const PublicKernelPublicPreviousArtifact = PublicKernelPublicPreviousJson as NoirCompiledCircuit; +export const PublicKernelAppLogicArtifact = PublicKernelAppLogicJson as NoirCompiledCircuit; + +export const PublicKernelTeardownArtifact = PublicKernelTeardownJson as NoirCompiledCircuit; /** * Executes the init private kernel. @@ -177,6 +181,23 @@ export async function executePublicKernelAppLogic( return mapPublicKernelCircuitPublicInputsFromNoir(returnType); } +/** + * Executes the public kernel in the teardown phase. + * @param publicKernelPrivateInputs - The public kernel teardown circuit private inputs. + * @returns The public inputs. + */ +export async function executePublicKernelTeardown( + publicKernelPrivateInputs: PublicKernelCircuitPrivateInputs, +): Promise { + const params: PublicPublicPreviousInputType = { + input: mapPublicKernelCircuitPrivateInputsToNoir(publicKernelPrivateInputs), + }; + + const returnType = await executePublicKernelTeardownWithACVM(params); + + return mapPublicKernelCircuitPublicInputsFromNoir(returnType); +} + /** * Executes the root rollup. * @param rootRollupInputs - The root rollup inputs. @@ -223,7 +244,7 @@ export async function executeBaseRollup(baseRollupInputs: BaseRollupInputs): Pro } /** - * Executes the init private kernel with the given inputs using the acvm. + * Executes the private init kernel with the given inputs using the acvm. * */ async function executePrivateKernelInitWithACVM(input: InitInputType): Promise { @@ -252,7 +273,7 @@ async function executePrivateKernelInitWithACVM(input: InitInputType): Promise { const initialWitnessMap = abiEncode(PrivateKernelInnerSimulatedJson.abi as Abi, input as any); @@ -280,7 +301,7 @@ async function executePrivateKernelInnerWithACVM(input: InnerInputType): Promise } /** - * Executes the ordering private kernel with the given inputs using the acvm. + * Executes the private tail kernel with the given inputs using the acvm. */ async function executePrivateKernelTailWithACVM(input: TailInputType): Promise { const initialWitnessMap = abiEncode(PrivateKernelTailSimulatedJson.abi as Abi, input as any); @@ -308,11 +329,11 @@ async function executePrivateKernelTailWithACVM(input: TailInputType): Promise { - const initialWitnessMap = abiEncode(PublicKernelPrivatePreviousSimulatedJson.abi as Abi, input as any); - const decodedBytecode = Buffer.from(PublicKernelPrivatePreviousSimulatedJson.bytecode, 'base64'); + const initialWitnessMap = abiEncode(PublicKernelSetupSimulatedJson.abi as Abi, input as any); + const decodedBytecode = Buffer.from(PublicKernelSetupSimulatedJson.bytecode, 'base64'); // Execute the circuit const _witnessMap = await executeCircuitWithBlackBoxSolver( await getSolver(), @@ -324,19 +345,44 @@ async function executePublicKernelSetupWithACVM(input: PublicSetupInputType): Pr ); // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(PublicKernelPrivatePreviousSimulatedJson.abi as Abi, _witnessMap); + const decodedInputs: DecodedInputs = abiDecode(PublicKernelSetupSimulatedJson.abi as Abi, _witnessMap); // Cast the inputs as the return type return decodedInputs.return_value as PublicSetupReturnType; } /** - * Executes the ordering private kernel with the given inputs using the acvm. + * Executes the public app logic kernel with the given inputs using the acvm. */ async function executePublicKernelAppLogicWithACVM( input: PublicPublicPreviousInputType, ): Promise { - const initialWitnessMap = abiEncode(PublicKernelPublicPreviousSimulatedJson.abi as Abi, input as any); - const decodedBytecode = Buffer.from(PublicKernelPublicPreviousSimulatedJson.bytecode, 'base64'); + const initialWitnessMap = abiEncode(PublicKernelAppLogicSimulatedJson.abi as Abi, input as any); + const decodedBytecode = Buffer.from(PublicKernelAppLogicSimulatedJson.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(PublicKernelAppLogicSimulatedJson.abi as Abi, _witnessMap); + + // Cast the inputs as the return type + return decodedInputs.return_value as PublicPublicPreviousReturnType; +} + +/** + * Executes the public teardown kernel with the given inputs using the acvm. + */ +async function executePublicKernelTeardownWithACVM( + input: PublicPublicPreviousInputType, +): Promise { + const initialWitnessMap = abiEncode(PublicKernelTeardownSimulatedJson.abi as Abi, input as any); + const decodedBytecode = Buffer.from(PublicKernelTeardownSimulatedJson.bytecode, 'base64'); // Execute the circuit const _witnessMap = await executeCircuitWithBlackBoxSolver( await getSolver(), @@ -348,7 +394,7 @@ async function executePublicKernelAppLogicWithACVM( ); // Decode the witness map into two fields, the return values and the inputs - const decodedInputs: DecodedInputs = abiDecode(PublicKernelPublicPreviousSimulatedJson.abi as Abi, _witnessMap); + const decodedInputs: DecodedInputs = abiDecode(PublicKernelTeardownSimulatedJson.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 8a56149a88ed..63837951472d 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_tail', 'public_kernel_setup', 'public_kernel_app_logic', + 'public_kernel_teardown', 'rollup_base', 'rollup_merge', 'rollup_root', 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 6d09892cba2f..218fe5adbfc4 100644 --- a/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits-types/src/type_conversion.ts @@ -1,6 +1,5 @@ import { ARCHIVE_HEIGHT, - AccumulatedNonRevertibleData, AggregationObject, AppendOnlyTreeSnapshot, AztecAddress, @@ -18,7 +17,6 @@ import { ContractStorageUpdateRequest, EthAddress, FUNCTION_TREE_HEIGHT, - FinalAccumulatedData, Fr, FunctionData, FunctionSelector, @@ -28,18 +26,25 @@ import { Header, L2ToL1Message, MAX_NEW_COMMITMENTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX_META, MAX_NEW_CONTRACTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, - MAX_NEW_NULLIFIERS_PER_TX_META, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, MAX_PUBLIC_DATA_READS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_READ_REQUESTS_PER_TX, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, MergeRollupInputs, NULLIFIER_TREE_HEIGHT, @@ -52,6 +57,8 @@ import { PartialStateReference, Point, PreviousRollupData, + PrivateAccumulatedNonRevertibleData, + PrivateAccumulatedRevertibleData, PrivateCallData, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -61,6 +68,8 @@ import { PrivateKernelInnerData, PrivateKernelTailCircuitPrivateInputs, PrivateKernelTailCircuitPublicInputs, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, PublicCallData, PublicCallStackItem, PublicCircuitPublicInputs, @@ -121,12 +130,16 @@ import { PrivateKernelInnerData as PrivateKernelInnerDataNoir, } from './types/private_kernel_inner_types.js'; import { - AccumulatedNonRevertibleData as AccumulatedNonRevertibleDataNoir, - FinalAccumulatedData as FinalAccumulatedDataNoir, + PrivateAccumulatedNonRevertibleData as PrivateAccumulatedNonRevertibleDataNoir, + PrivateAccumulatedRevertibleData as PrivateAccumulatedRevertibleDataNoir, PrivateKernelTailCircuitPrivateInputs as PrivateKernelTailCircuitPrivateInputsNoir, PrivateKernelTailCircuitPublicInputs as PrivateKernelTailCircuitPublicInputsNoir, } from './types/private_kernel_tail_types.js'; -import { PublicKernelData as PublicKernelDataNoir } from './types/public_kernel_app_logic_types.js'; +import { + PublicAccumulatedNonRevertibleData as PublicAccumulatedNonRevertibleDataNoir, + PublicAccumulatedRevertibleData as PublicAccumulatedRevertibleDataNoir, + PublicKernelData as PublicKernelDataNoir, +} from './types/public_kernel_app_logic_types.js'; import { PublicCallData as PublicCallDataNoir, PublicCallStackItem as PublicCallStackItemNoir, @@ -492,8 +505,8 @@ export function mapCallRequestFromNoir(callRequest: CallRequestNoir): CallReques mapFieldFromNoir(callRequest.hash), mapAztecAddressFromNoir(callRequest.caller_contract_address), mapCallerContextFromNoir(callRequest.caller_context), - Fr.ZERO, // todo: actual values of counters - Fr.ZERO, + mapFieldFromNoir(callRequest.start_side_effect_counter), + mapFieldFromNoir(callRequest.end_side_effect_counter), ); } @@ -514,8 +527,8 @@ export function mapCallRequestToNoir(callRequest: CallRequest): CallRequestNoir /** * Maps a SideEffect to a noir side effect. - * @param sideEffect - The side effect. - * @returns The noir sideeffect. + * @param sideEffect - The SideEffect. + * @returns The noir side effect. */ export function mapSideEffectToNoir(sideEffect: SideEffect): SideEffectNoir { return { @@ -525,9 +538,9 @@ export function mapSideEffectToNoir(sideEffect: SideEffect): SideEffectNoir { } /** - * Maps a noir side effect to aSideEffect. - * @param sideEffect - The noir side effect. - * @returns The TS sideeffect. + * Maps a noir side effect to a SideEffect. + * @param sideEffect - The noir SideEffect. + * @returns The TS side effect. */ export function mapSideEffectFromNoir(sideEffect: SideEffectNoir): SideEffect { return new SideEffect(mapFieldFromNoir(sideEffect.value), mapFieldFromNoir(sideEffect.counter)); @@ -536,7 +549,7 @@ export function mapSideEffectFromNoir(sideEffect: SideEffectNoir): SideEffect { /** * Maps a SideEffectLinked to a noir side effect. * @param sideEffectLinked - The side effect linked to note hash. - * @returns The noir sideeffectlinked to note hash. + * @returns The noir SideEffectLinkedToNoteHash. */ export function mapSideEffectLinkedToNoir( sideEffectLinked: SideEffectLinkedToNoteHash, @@ -664,9 +677,7 @@ export function mapPrivateCircuitPublicInputsToNoir( contract_deployment_data: mapContractDeploymentDataToNoir(privateCircuitPublicInputs.contractDeploymentData), chain_id: mapFieldToNoir(privateCircuitPublicInputs.chainId), version: mapFieldToNoir(privateCircuitPublicInputs.version), - max_non_revertible_side_effect_counter: mapFieldToNoir( - privateCircuitPublicInputs.maxNonRevertibleSideEffectCounter, - ), + min_revertible_side_effect_counter: mapFieldToNoir(privateCircuitPublicInputs.minRevertibleSideEffectCounter), }; } @@ -904,10 +915,16 @@ export function mapCombinedAccumulatedDataFromNoir( * @param finalAccumulatedData - The noir final accumulated data. * @returns The parsed final accumulated data. */ -export function mapFinalAccumulatedDataFromNoir(finalAccumulatedData: FinalAccumulatedDataNoir): FinalAccumulatedData { - return new FinalAccumulatedData( - mapTupleFromNoir(finalAccumulatedData.new_commitments, MAX_NEW_COMMITMENTS_PER_TX, mapSideEffectFromNoir), - mapTupleFromNoir(finalAccumulatedData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX, mapSideEffectLinkedFromNoir), +export function mapFinalAccumulatedDataFromNoir( + finalAccumulatedData: PrivateAccumulatedRevertibleDataNoir, +): PrivateAccumulatedRevertibleData { + return new PrivateAccumulatedRevertibleData( + mapTupleFromNoir(finalAccumulatedData.new_commitments, MAX_REVERTIBLE_COMMITMENTS_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, @@ -915,7 +932,7 @@ export function mapFinalAccumulatedDataFromNoir(finalAccumulatedData: FinalAccum ), mapTupleFromNoir( finalAccumulatedData.public_call_stack, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + 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), @@ -932,15 +949,19 @@ export function mapFinalAccumulatedDataFromNoir(finalAccumulatedData: FinalAccum * @param accumulatedMetaData - The noir accumulated meta data. * @returns The parsed accumulated meta data. */ -export function mapAccumulatedMetaDataFromNoir( - accumulatedMetaData: AccumulatedNonRevertibleDataNoir, -): AccumulatedNonRevertibleData { - return new AccumulatedNonRevertibleData( - mapTupleFromNoir(accumulatedMetaData.new_commitments, MAX_NEW_COMMITMENTS_PER_TX_META, mapSideEffectFromNoir), - mapTupleFromNoir(accumulatedMetaData.new_nullifiers, MAX_NEW_NULLIFIERS_PER_TX_META, mapSideEffectLinkedFromNoir), +export function mapAccumulatedNonRevertibleDataFromNoir( + accumulatedMetaData: PrivateAccumulatedNonRevertibleDataNoir, +): PrivateAccumulatedNonRevertibleData { + return new PrivateAccumulatedNonRevertibleData( + mapTupleFromNoir(accumulatedMetaData.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir( + accumulatedMetaData.new_nullifiers, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + mapSideEffectLinkedFromNoir, + ), mapTupleFromNoir( accumulatedMetaData.public_call_stack, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX_META, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, mapCallRequestFromNoir, ), ); @@ -951,9 +972,9 @@ export function mapAccumulatedMetaDataFromNoir( * @param accumulatedMetaData - The noir accumulated meta data. * @returns The parsed accumulated meta data. */ -export function mapAccumulatedMetaDataToNoir( - accumulatedMetaData: AccumulatedNonRevertibleData, -): AccumulatedNonRevertibleDataNoir { +export function mapAccumulatedNonRevertibleDataToNoir( + accumulatedMetaData: PrivateAccumulatedNonRevertibleData, +): PrivateAccumulatedNonRevertibleDataNoir { return { new_commitments: mapTuple(accumulatedMetaData.newCommitments, mapSideEffectToNoir), new_nullifiers: mapTuple(accumulatedMetaData.newNullifiers, mapSideEffectLinkedToNoir), @@ -961,6 +982,23 @@ export function mapAccumulatedMetaDataToNoir( }; } +export function mapPrivateAccumulatedRevertibleDataToNoir( + data: PrivateAccumulatedRevertibleData, +): PrivateAccumulatedRevertibleDataNoir { + return { + new_commitments: mapTuple(data.newCommitments, 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: mapTuple(data.encryptedLogsHash, mapFieldToNoir), + unencrypted_logs_hash: mapTuple(data.unencryptedLogsHash, mapFieldToNoir), + encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), + unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), + new_contracts: mapTuple(data.newContracts, mapNewContractDataToNoir), + }; +} + /** * Maps combined accumulated data to noir combined accumulated data. * @param combinedAccumulatedData - The combined accumulated data. @@ -1037,9 +1075,47 @@ export function mapPublicKernelCircuitPublicInputsToNoir( return { aggregation_object: {}, constants: mapCombinedConstantDataToNoir(inputs.constants), - end: mapCombinedAccumulatedDataToNoir(inputs.end), - end_non_revertible: mapAccumulatedMetaDataToNoir(inputs.endNonRevertibleData), - is_private: inputs.isPrivate, + end: mapPublicAccumulatedRevertibleDataToNoir(inputs.end), + end_non_revertible: mapPublicAccumulatedNonRevertibleDataToNoir(inputs.endNonRevertibleData), + needs_setup: inputs.needsSetup, + needs_app_logic: inputs.needsAppLogic, + needs_teardown: inputs.needsTeardown, + }; +} + +export function mapPublicAccumulatedRevertibleDataToNoir( + data: PublicAccumulatedRevertibleData, +): PublicAccumulatedRevertibleDataNoir { + return { + read_requests: mapTuple(data.readRequests, mapSideEffectToNoir), + nullifier_key_validation_requests: mapTuple( + data.nullifierKeyValidationRequests, + mapNullifierKeyValidationRequestContextToNoir, + ), + new_commitments: mapTuple(data.newCommitments, 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: mapTuple(data.encryptedLogsHash, mapFieldToNoir), + unencrypted_logs_hash: mapTuple(data.unencryptedLogsHash, mapFieldToNoir), + encrypted_log_preimages_length: mapFieldToNoir(data.encryptedLogPreimagesLength), + unencrypted_log_preimages_length: mapFieldToNoir(data.unencryptedLogPreimagesLength), + new_contracts: mapTuple(data.newContracts, mapNewContractDataToNoir), + public_data_update_requests: mapTuple(data.publicDataUpdateRequests, mapPublicDataUpdateRequestToNoir), + public_data_reads: mapTuple(data.publicDataReads, mapPublicDataReadToNoir), + }; +} + +export function mapPublicAccumulatedNonRevertibleDataToNoir( + data: PublicAccumulatedNonRevertibleData, +): PublicAccumulatedNonRevertibleDataNoir { + return { + new_commitments: mapTuple(data.newCommitments, mapSideEffectToNoir), + new_nullifiers: mapTuple(data.newNullifiers, mapSideEffectLinkedToNoir), + public_call_stack: mapTuple(data.publicCallStack, mapCallRequestToNoir), + public_data_reads: mapTuple(data.publicDataReads, mapPublicDataReadToNoir), + public_data_update_requests: mapTuple(data.publicDataUpdateRequests, mapPublicDataUpdateRequestToNoir), }; } @@ -1063,7 +1139,7 @@ export function mapPrivateKernelInnerCircuitPublicInputsFromNoir( ): PrivateKernelInnerCircuitPublicInputs { return new PrivateKernelInnerCircuitPublicInputs( AggregationObject.makeFake(), - mapFieldFromNoir(inputs.max_non_revertible_side_effect_counter), + mapFieldFromNoir(inputs.min_revertible_side_effect_counter), mapCombinedAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), inputs.is_private, @@ -1077,7 +1153,7 @@ export function mapPrivateKernelInnerCircuitPublicInputsToNoir( aggregation_object: {}, constants: mapCombinedConstantDataToNoir(inputs.constants), end: mapCombinedAccumulatedDataToNoir(inputs.end), - max_non_revertible_side_effect_counter: mapFieldToNoir(inputs.maxNonRevertibleSideEffectCounter), + min_revertible_side_effect_counter: mapFieldToNoir(inputs.minRevertibleSideEffectCounter), is_private: inputs.isPrivate, }; } @@ -1104,7 +1180,9 @@ export function mapPrivateKernelInnerDataToNoir( * @param finalAccumulatedData - The final accumulated data. * @returns The noir final accumulated data. */ -export function mapFinalAccumulatedDataToNoir(finalAccumulatedData: FinalAccumulatedData): FinalAccumulatedDataNoir { +export function mapFinalAccumulatedDataToNoir( + finalAccumulatedData: PrivateAccumulatedRevertibleData, +): PrivateAccumulatedRevertibleDataNoir { return { new_commitments: mapTuple(finalAccumulatedData.newCommitments, mapSideEffectToNoir), new_nullifiers: mapTuple(finalAccumulatedData.newNullifiers, mapSideEffectLinkedToNoir), @@ -1124,10 +1202,12 @@ export function mapPrivateKernelTailCircuitPublicInputsFromNoir( ): PrivateKernelTailCircuitPublicInputs { return new PrivateKernelTailCircuitPublicInputs( AggregationObject.makeFake(), - mapAccumulatedMetaDataFromNoir(inputs.end_non_revertible), + mapAccumulatedNonRevertibleDataFromNoir(inputs.end_non_revertible), mapFinalAccumulatedDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), - inputs.is_private, + inputs.needs_setup, + inputs.needs_app_logic, + inputs.needs_teardown, ); } @@ -1138,8 +1218,10 @@ export function mapPrivateKernelTailCircuitPublicInputsToNoir( aggregation_object: {}, constants: mapCombinedConstantDataToNoir(inputs.constants), end: mapFinalAccumulatedDataToNoir(inputs.end), - end_non_revertible: mapAccumulatedMetaDataToNoir(inputs.endNonRevertibleData), - is_private: inputs.isPrivate, + end_non_revertible: mapAccumulatedNonRevertibleDataToNoir(inputs.endNonRevertibleData), + needs_setup: inputs.needsSetup, + needs_app_logic: inputs.needsAppLogic, + needs_teardown: inputs.needsTeardown, }; } @@ -1191,10 +1273,61 @@ export function mapPublicKernelCircuitPublicInputsFromNoir( ): PublicKernelCircuitPublicInputs { return new PublicKernelCircuitPublicInputs( AggregationObject.makeFake(), - mapAccumulatedMetaDataFromNoir(inputs.end_non_revertible), - mapCombinedAccumulatedDataFromNoir(inputs.end), + mapPublicAccumulatedNonRevertibleDataFromNoir(inputs.end_non_revertible), + mapPublicAccumulatedRevertibleDataFromNoir(inputs.end), mapCombinedConstantDataFromNoir(inputs.constants), - inputs.is_private, + inputs.needs_setup, + inputs.needs_app_logic, + inputs.needs_teardown, + ); +} + +export function mapPublicAccumulatedNonRevertibleDataFromNoir( + data: PublicAccumulatedNonRevertibleDataNoir, +): PublicAccumulatedNonRevertibleData { + return new PublicAccumulatedNonRevertibleData( + mapTupleFromNoir(data.new_commitments, MAX_NON_REVERTIBLE_COMMITMENTS_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, + ), + mapTupleFromNoir(data.public_data_reads, MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, mapPublicDataReadFromNoir), + ); +} + +export function mapPublicAccumulatedRevertibleDataFromNoir( + data: PublicAccumulatedRevertibleDataNoir, +): PublicAccumulatedRevertibleData { + return new PublicAccumulatedRevertibleData( + mapTupleFromNoir(data.read_requests, MAX_READ_REQUESTS_PER_TX, mapSideEffectFromNoir), + mapTupleFromNoir( + data.nullifier_key_validation_requests, + MAX_NULLIFIER_KEY_VALIDATION_REQUESTS_PER_TX, + mapNullifierKeyValidationRequestContextFromNoir, + ), + mapTupleFromNoir(data.new_commitments, MAX_REVERTIBLE_COMMITMENTS_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), + mapTupleFromNoir(data.encrypted_logs_hash, NUM_FIELDS_PER_SHA256, mapFieldFromNoir), + mapTupleFromNoir(data.unencrypted_logs_hash, NUM_FIELDS_PER_SHA256, mapFieldFromNoir), + mapFieldFromNoir(data.encrypted_log_preimages_length), + mapFieldFromNoir(data.unencrypted_log_preimages_length), + mapTupleFromNoir(data.new_contracts, MAX_NEW_CONTRACTS_PER_TX, mapNewContractDataFromNoir), + mapTupleFromNoir( + data.public_data_update_requests, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + mapPublicDataUpdateRequestFromNoir, + ), + mapTupleFromNoir(data.public_data_reads, MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, mapPublicDataReadFromNoir), ); } diff --git a/yarn-project/p2p/src/service/libp2p_service.ts b/yarn-project/p2p/src/service/libp2p_service.ts index dff05585699c..4237307d9631 100644 --- a/yarn-project/p2p/src/service/libp2p_service.ts +++ b/yarn-project/p2p/src/service/libp2p_service.ts @@ -318,7 +318,7 @@ export class LibP2PService implements P2PService { } private async processTxFromPeer(tx: Tx, peerId: PeerId): Promise { - const txHash = await tx.getTxHash(); + const txHash = tx.getTxHash(); const txHashString = txHash.toString(); this.knownTxLookup.addPeerForTx(peerId, txHashString); this.logger(`Received tx ${txHashString} from peer ${peerId.toString()}`); @@ -330,7 +330,7 @@ export class LibP2PService implements P2PService { const txs = createTransactionsMessage([tx]); const payload = new Uint8Array(txs); const peers = this.getTxPeers(); - const txHash = await tx.getTxHash(); + const txHash = tx.getTxHash(); const txHashString = txHash.toString(); for (const peer of peers) { try { @@ -376,7 +376,7 @@ export class LibP2PService implements P2PService { const message = createTransactionsMessage(txs); await this.sendRawMessageToPeer(message, peer); for (const tx of txs) { - const hash = await tx.getTxHash(); + const hash = tx.getTxHash(); this.knownTxLookup.addPeerForTx(peer, hash.toString()); } } diff --git a/yarn-project/p2p/src/tx_pool/memory_tx_pool.ts b/yarn-project/p2p/src/tx_pool/memory_tx_pool.ts index ce4d284a281d..8f4aad46a38d 100644 --- a/yarn-project/p2p/src/tx_pool/memory_tx_pool.ts +++ b/yarn-project/p2p/src/tx_pool/memory_tx_pool.ts @@ -36,15 +36,16 @@ export class InMemoryTxPool implements TxPool { * @param txs - An array of txs to be added to the pool. * @returns Empty promise. */ - public async addTxs(txs: Tx[]): Promise { + public addTxs(txs: Tx[]): Promise { for (const tx of txs) { - const txHash = await tx.getTxHash(); + const txHash = tx.getTxHash(); this.log(`Adding tx with id ${txHash.toString()}`, { eventName: 'tx-added-to-pool', ...tx.getStats(), } satisfies TxAddedToPoolStats); this.txs.set(txHash.toBigInt(), tx); } + return Promise.resolve(); } /** diff --git a/yarn-project/p2p/src/tx_pool/tx_pool_test_suite.ts b/yarn-project/p2p/src/tx_pool/tx_pool_test_suite.ts index 0bf49f441840..e2e9f74156ef 100644 --- a/yarn-project/p2p/src/tx_pool/tx_pool_test_suite.ts +++ b/yarn-project/p2p/src/tx_pool/tx_pool_test_suite.ts @@ -17,17 +17,17 @@ export function describeTxPool(getTxPool: () => TxPool) { const tx1 = mockTx(); await pool.addTxs([tx1]); - const poolTx = pool.getTxByHash(await tx1.getTxHash()); - expect(await poolTx!.getTxHash()).toEqual(await tx1.getTxHash()); + const poolTx = pool.getTxByHash(tx1.getTxHash()); + expect(poolTx!.getTxHash()).toEqual(tx1.getTxHash()); }); it('Removes txs from the pool', async () => { const tx1 = mockTx(); await pool.addTxs([tx1]); - await pool.deleteTxs([await tx1.getTxHash()]); + await pool.deleteTxs([tx1.getTxHash()]); - const poolTx = pool.getTxByHash(await tx1.getTxHash()); + const poolTx = pool.getTxByHash(tx1.getTxHash()); expect(poolTx).toBeFalsy(); }); @@ -52,8 +52,6 @@ export function describeTxPool(getTxPool: () => TxPool) { const poolTxHashes = pool.getAllTxHashes(); expect(poolTxHashes).toHaveLength(3); - expect(poolTxHashes).toEqual( - expect.arrayContaining([await tx1.getTxHash(), await tx2.getTxHash(), await tx3.getTxHash()]), - ); + expect(poolTxHashes).toEqual(expect.arrayContaining([tx1.getTxHash(), tx2.getTxHash(), tx3.getTxHash()])); }); } 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 ea3fab328b5c..c52785c4743b 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.test.ts @@ -5,6 +5,7 @@ import { MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_COMMITMENTS_PER_TX, MAX_READ_REQUESTS_PER_CALL, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, MembershipWitness, PrivateCallStackItem, PrivateCircuitPublicInputs, @@ -96,7 +97,7 @@ describe('Kernel Prover', () => { const createProofOutputFinal = (newNoteIndices: number[]) => { const publicInputs = PrivateKernelTailCircuitPublicInputs.empty(); - const commitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); + const commitments = makeTuple(MAX_REVERTIBLE_COMMITMENTS_PER_TX, () => SideEffect.empty()); for (let i = 0; i < newNoteIndices.length; i++) { commitments[i] = new SideEffect(generateFakeSiloedCommitment(notesAndSlots[newNoteIndices[i]]), Fr.ZERO); } diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index dd73dadef971..0b6c878814db 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -32,7 +32,8 @@ import { CompleteAddress, FunctionData, GrumpkinPrivateKey, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, PartialAddress, PrivateKernelTailCircuitPublicInputs, PublicCallRequest, @@ -43,7 +44,7 @@ import { } from '@aztec/circuits.js'; import { computeCommitmentNonce, siloNullifier } from '@aztec/circuits.js/hash'; import { DecodedReturn, encodeArguments } from '@aztec/foundation/abi'; -import { padArrayEnd } from '@aztec/foundation/collection'; +import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; import { Fr } from '@aztec/foundation/fields'; import { SerialQueue } from '@aztec/foundation/fifo'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; @@ -391,7 +392,7 @@ export class PXEService implements PXE { const timer = new Timer(); const tx = await this.#simulateAndProve(txRequest, newContract); - this.log(`Processed private part of ${tx.data.end.newNullifiers[0]}`, { + this.log(`Processed private part of ${tx.getTxHash()}`, { eventName: 'tx-pxe-processing', duration: timer.ms(), ...tx.getStats(), @@ -399,14 +400,14 @@ export class PXEService implements PXE { if (simulatePublic) { await this.#simulatePublicCalls(tx); } - this.log.info(`Executed local simulation for ${await tx.getTxHash()}`); + this.log.info(`Executed local simulation for ${tx.getTxHash()}`); return tx; }); } public async sendTx(tx: Tx): Promise { - const txHash = await tx.getTxHash(); + const txHash = tx.getTxHash(); if (await this.node.getTx(txHash)) { throw new Error(`A settled tx with equal hash ${txHash.toString()} exists.`); } @@ -647,6 +648,9 @@ 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 TxL2Logs(collectEncryptedLogs(executionResult)); const unencryptedLogs = new TxL2Logs(collectUnencryptedLogs(executionResult)); @@ -714,19 +718,19 @@ export class PXEService implements PXE { enqueuedPublicCalls: PublicCallRequest[], ) { const enqueuedPublicCallStackItems = await Promise.all(enqueuedPublicCalls.map(c => c.toCallRequest())); - const { publicCallStack } = publicInputs.end; // Validate all items in enqueued public calls are in the kernel emitted stack - const areEqual = enqueuedPublicCallStackItems.reduce( - (accum, enqueued) => accum && !!publicCallStack.find(item => item.equals(enqueued)), - true, + const enqueuedRevertiblePublicCallStackItems = enqueuedPublicCallStackItems.filter(enqueued => + publicInputs.end.publicCallStack.find(item => item.equals(enqueued)), ); - if (!areEqual) { + const revertibleStackSize = arrayNonEmptyLength(publicInputs.end.publicCallStack, item => item.isEmpty()); + + if (enqueuedRevertiblePublicCallStackItems.length !== revertibleStackSize) { throw new Error( - `Enqueued public function calls and public call stack do not match.\nEnqueued calls: ${enqueuedPublicCallStackItems + `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: ${publicCallStack.map(i => i.toString()).join(', ')}`, + .join(', ')}\nPublic call stack: ${publicInputs.end.publicCallStack.map(i => i.toString()).join(', ')}`, ); } @@ -734,7 +738,34 @@ export class PXEService implements PXE { publicInputs.end.publicCallStack = padArrayEnd( enqueuedPublicCallStackItems, CallRequest.empty(), - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_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)), + ); + + const nonRevertibleStackSize = arrayNonEmptyLength(publicInputs.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 + .map(i => i.toString()) + .join(', ')}`, + ); + } + + // Override kernel output + publicInputs.endNonRevertibleData.publicCallStack = padArrayEnd( + enqueuedNonRevertiblePublicCallStackItems, + CallRequest.empty(), + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, ); } diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index b3743a99dc91..ba06d6273e46 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -18,11 +18,15 @@ import { Fr, GlobalVariables, Header, - MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_L2_TO_L1_MSGS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NULLIFIER_SUBTREE_HEIGHT, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, PUBLIC_DATA_SUBTREE_HEIGHT, @@ -133,22 +137,31 @@ describe('sequencer/solo_block_builder', () => { const updateExpectedTreesFromTxs = async (txs: ProcessedTx[]) => { const newContracts = txs.flatMap(tx => tx.data.end.newContracts.map(cd => cd.computeLeaf())); for (const [tree, leaves] of [ - [MerkleTreeId.NOTE_HASH_TREE, txs.flatMap(tx => tx.data.end.newCommitments.map(l => l.value.toBuffer()))], + [ + MerkleTreeId.NOTE_HASH_TREE, + txs.flatMap(tx => + [...tx.data.endNonRevertibleData.newCommitments, ...tx.data.end.newCommitments].map(l => l.value.toBuffer()), + ), + ], [MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer())], ] as const) { await expectsDb.appendLeaves(tree, leaves); } await expectsDb.batchInsert( MerkleTreeId.NULLIFIER_TREE, - txs.flatMap(tx => tx.data.end.newNullifiers.map(x => x.value.toBuffer())), + txs.flatMap(tx => + [...tx.data.endNonRevertibleData.newNullifiers, ...tx.data.end.newNullifiers].map(x => x.value.toBuffer()), + ), NULLIFIER_SUBTREE_HEIGHT, ); for (const tx of txs) { await expectsDb.batchInsert( MerkleTreeId.PUBLIC_DATA_TREE, - tx.data.end.publicDataUpdateRequests.map(write => { - return new PublicDataTreeLeaf(write.leafSlot, write.newValue).toBuffer(); - }), + [...tx.data.endNonRevertibleData.publicDataUpdateRequests, ...tx.data.end.publicDataUpdateRequests].map( + write => { + return new PublicDataTreeLeaf(write.leafSlot, write.newValue).toBuffer(); + }, + ), PUBLIC_DATA_SUBTREE_HEIGHT, ); } @@ -189,7 +202,7 @@ describe('sequencer/solo_block_builder', () => { const kernelOutput = makePrivateKernelTailCircuitPublicInputs(); kernelOutput.constants.historicalHeader = await expectsDb.buildInitialHeader(); - const tx = await makeProcessedTx( + const tx = makeProcessedTx( new Tx( kernelOutput, emptyProof, @@ -213,15 +226,22 @@ describe('sequencer/solo_block_builder', () => { // Update l1 to l2 message tree await updateL1ToL2MessageTree(mockL1ToL2Messages); - const newNullifiers = txs.flatMap(tx => tx.data.end.newNullifiers); - const newCommitments = txs.flatMap(tx => tx.data.end.newCommitments); + const newNullifiers = txs.flatMap(tx => [ + ...tx.data.endNonRevertibleData.newNullifiers, + ...tx.data.end.newNullifiers, + ]); + const newCommitments = txs.flatMap(tx => [ + ...tx.data.endNonRevertibleData.newCommitments, + ...tx.data.end.newCommitments, + ]); const newContracts = txs.flatMap(tx => tx.data.end.newContracts).map(cd => cd.computeLeaf()); const newContractData = txs .flatMap(tx => tx.data.end.newContracts) .map(n => new ContractData(n.contractAddress, n.portalContractAddress)); - const newPublicDataWrites = txs.flatMap(tx => - tx.data.end.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), - ); + const newPublicDataWrites = txs.flatMap(tx => [ + ...tx.data.endNonRevertibleData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), + ...tx.data.end.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), + ]); const newL2ToL1Msgs = txs.flatMap(tx => tx.data.end.newL2ToL1Msgs); const newEncryptedLogs = new L2BlockL2Logs(txs.map(tx => tx.encryptedLogs || new TxL2Logs([]))); const newUnencryptedLogs = new L2BlockL2Logs(txs.map(tx => tx.unencryptedLogs || new TxL2Logs([]))); @@ -296,19 +316,38 @@ describe('sequencer/solo_block_builder', () => { const kernelOutput = PublicKernelCircuitPublicInputs.empty(); kernelOutput.constants.historicalHeader = await builderDb.buildInitialHeader(); kernelOutput.end.publicDataUpdateRequests = makeTuple( - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_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, + i => new PublicDataUpdateRequest(fr(i), fr(i + 10)), + seed + 0x600, + ); - const processedTx = await makeProcessedTx(tx, kernelOutput, makeProof()); + const processedTx = makeProcessedTx(tx, kernelOutput, makeProof()); - processedTx.data.end.newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, makeNewSideEffect, seed + 0x100); + processedTx.data.end.newCommitments = makeTuple( + MAX_REVERTIBLE_COMMITMENTS_PER_TX, + makeNewSideEffect, + seed + 0x100, + ); + processedTx.data.endNonRevertibleData.newCommitments = makeTuple( + MAX_NON_REVERTIBLE_COMMITMENTS_PER_TX, + makeNewSideEffect, + seed + 0x100, + ); processedTx.data.end.newNullifiers = makeTuple( - MAX_NEW_NULLIFIERS_PER_TX, + MAX_REVERTIBLE_NULLIFIERS_PER_TX, makeNewSideEffectLinkedToNoteHash, seed + 0x200, ); + processedTx.data.endNonRevertibleData.newNullifiers = makeTuple( + MAX_NON_REVERTIBLE_NULLIFIERS_PER_TX, + makeNewSideEffectLinkedToNoteHash, + seed + 0x300, + ); processedTx.data.end.newNullifiers[tx.data.end.newNullifiers.length - 1] = SideEffectLinkedToNoteHash.empty(); processedTx.data.end.newL2ToL1Msgs = makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_TX, fr, seed + 0x300); diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index d2e670e89d70..37a26e9e5609 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -101,16 +101,16 @@ export class SoloBlockBuilder implements BlockBuilder { const [circuitsOutput, proof] = await this.runCircuits(globalVariables, txs, newL1ToL2Messages); // Collect all new nullifiers, commitments, and contracts from all txs in this block - const newNullifiers = txs.flatMap(tx => tx.data.end.newNullifiers); - const newCommitments = txs.flatMap(tx => tx.data.end.newCommitments); - const newContracts = txs.flatMap(tx => tx.data.end.newContracts).map(cd => cd.computeLeaf()); + const newNullifiers = txs.flatMap(tx => tx.data.combinedData.newNullifiers); + const newCommitments = txs.flatMap(tx => tx.data.combinedData.newCommitments); + const newContracts = txs.flatMap(tx => tx.data.combinedData.newContracts).map(cd => cd.computeLeaf()); const newContractData = txs - .flatMap(tx => tx.data.end.newContracts) + .flatMap(tx => tx.data.combinedData.newContracts) .map(n => new ContractData(n.contractAddress, n.portalContractAddress)); const newPublicDataWrites = txs.flatMap(tx => - tx.data.end.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), + tx.data.combinedData.publicDataUpdateRequests.map(t => new PublicDataWrite(t.leafSlot, t.newValue)), ); - const newL2ToL1Msgs = txs.flatMap(tx => tx.data.end.newL2ToL1Msgs); + const newL2ToL1Msgs = txs.flatMap(tx => tx.data.combinedData.newL2ToL1Msgs); // Consolidate logs data from all txs const encryptedLogsArr: TxL2Logs[] = []; @@ -500,13 +500,14 @@ export class SoloBlockBuilder implements BlockBuilder { } protected async processPublicDataUpdateRequests(tx: ProcessedTx) { + const combinedPublicDataUpdateRequests = tx.data.combinedData.publicDataUpdateRequests.map(updateRequest => { + return new PublicDataTreeLeaf(updateRequest.leafSlot, updateRequest.newValue).toBuffer(); + }); const { lowLeavesWitnessData, newSubtreeSiblingPath, sortedNewLeaves, sortedNewLeavesIndexes } = await this.db.batchInsert( MerkleTreeId.PUBLIC_DATA_TREE, + combinedPublicDataUpdateRequests, // TODO(#3675) remove oldValue from update requests - tx.data.end.publicDataUpdateRequests.map(updateRequest => { - return new PublicDataTreeLeaf(updateRequest.leafSlot, updateRequest.newValue).toBuffer(); - }), PUBLIC_DATA_SUBTREE_HEIGHT, ); @@ -562,8 +563,9 @@ export class SoloBlockBuilder implements BlockBuilder { const newPublicDataReadsPreimages: Tuple = makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataTreeLeafPreimage.empty()); - for (const i in tx.data.end.publicDataReads) { - const leafSlot = tx.data.end.publicDataReads[i].leafSlot.value; + + for (const i in tx.data.combinedData.publicDataReads) { + const leafSlot = tx.data.combinedData.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`); @@ -615,8 +617,9 @@ export class SoloBlockBuilder implements BlockBuilder { // Update the contract and 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 newContracts = tx.data.end.newContracts.map(cd => cd.computeLeaf()); - const newCommitments = tx.data.end.newCommitments.map(x => x.value.toBuffer()); + const newContracts = tx.data.combinedData.newContracts.map(cd => cd.computeLeaf()); + const newCommitments = tx.data.combinedData.newCommitments.map(x => x.value.toBuffer()); + await this.db.appendLeaves( MerkleTreeId.CONTRACT_TREE, newContracts.map(x => x.toBuffer()), @@ -630,8 +633,6 @@ export class SoloBlockBuilder implements BlockBuilder { const txPublicDataUpdateRequestInfo = await this.processPublicDataUpdateRequests(tx); // Update the nullifier tree, capturing the low nullifier info for each individual operation - const newNullifiers = tx.data.end.newNullifiers; - const { lowLeavesWitnessData: nullifierWitnessLeaves, newSubtreeSiblingPath: newNullifiersSubtreeSiblingPath, @@ -639,7 +640,7 @@ export class SoloBlockBuilder implements BlockBuilder { sortedNewLeavesIndexes, } = await this.db.batchInsert( MerkleTreeId.NULLIFIER_TREE, - newNullifiers.map(sideEffectLinkedToNoteHash => sideEffectLinkedToNoteHash.value.toBuffer()), + tx.data.combinedData.newNullifiers.map(sideEffectLinkedToNoteHash => sideEffectLinkedToNoteHash.value.toBuffer()), NULLIFIER_SUBTREE_HEIGHT, ); if (nullifierWitnessLeaves === undefined) { 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 c1cd3a1f5e6f..d45d2344133a 100644 --- a/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/abstract_phase_manager.ts @@ -2,7 +2,6 @@ import { FunctionL2Logs, MerkleTreeId, Tx } from '@aztec/circuit-types'; import { AztecAddress, CallRequest, - CombinedAccumulatedData, ContractStorageRead, ContractStorageUpdateRequest, Fr, @@ -12,13 +11,18 @@ import { MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, 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_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, MembershipWitness, + PrivateKernelTailCircuitPublicInputs, Proof, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, PublicCallData, PublicCallRequest, PublicCallStackItem, @@ -35,7 +39,7 @@ import { } from '@aztec/circuits.js'; import { computeVarArgsHash } from '@aztec/circuits.js/hash'; import { arrayNonEmptyLength, padArrayEnd } from '@aztec/foundation/collection'; -import { createDebugLogger } from '@aztec/foundation/log'; +import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { to2Fields } from '@aztec/foundation/serialize'; import { PublicExecution, @@ -54,15 +58,14 @@ import { PublicProver } from '../prover/index.js'; import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { FailedTx } from './processed_tx.js'; -/** - * A phase manager is responsible for performing/rolling back a phase of a transaction. - * - * The phases are as follows: - * 1. Fee Preparation - * 2. Application Logic - * 3. Fee Distribution - */ +export enum PublicKernelPhase { + SETUP = 'setup', + APP_LOGIC = 'app-logic', + TEARDOWN = 'teardown', +} + export abstract class AbstractPhaseManager { + protected log: DebugLogger; constructor( protected db: MerkleTreeOperations, protected publicExecutor: PublicExecutor, @@ -70,8 +73,10 @@ export abstract class AbstractPhaseManager { protected publicProver: PublicProver, protected globalVariables: GlobalVariables, protected historicalHeader: Header, - protected log = createDebugLogger('aztec:sequencer:phase-manager'), - ) {} + public phase: PublicKernelPhase, + ) { + this.log = createDebugLogger(`aztec:sequencer:${phase}`); + } /** * * @param tx - the tx to be processed @@ -80,25 +85,70 @@ export abstract class AbstractPhaseManager { */ abstract handle( tx: Tx, - publicKernelPublicInputs?: PublicKernelCircuitPublicInputs, - previousPublicKernelProof?: Proof, + publicKernelPublicInputs: PublicKernelCircuitPublicInputs, + previousPublicKernelProof: Proof, ): Promise<{ /** * the output of the public kernel circuit for this phase */ - publicKernelOutput?: PublicKernelCircuitPublicInputs; + publicKernelOutput: PublicKernelCircuitPublicInputs; /** * the proof of the public kernel circuit for this phase */ - publicKernelProof?: Proof; + publicKernelProof: Proof; }>; - abstract nextPhase(): AbstractPhaseManager | undefined; abstract rollback(tx: Tx, err: unknown): Promise; - // Extract the public calls from the tx for this phase - abstract extractEnqueuedPublicCalls(tx: Tx): PublicCallRequest[]; + public static extractEnqueuedPublicCallsByPhase( + publicInputs: PrivateKernelTailCircuitPublicInputs, + 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 callRequestsStack = publicCallsStack + .map(call => call.toCallRequest()) + .filter( + // filter out enqueued calls that are not in the public call stack + // TODO mitch left a question about whether this is only needed when unit testing + // with mock data + call => revertibleCallStack.find(p => p.equals(call)) || nonRevertibleCallStack.find(p => p.equals(call)), + ); + + if (callRequestsStack.length === 0) { + return { + [PublicKernelPhase.SETUP]: [], + [PublicKernelPhase.APP_LOGIC]: [], + [PublicKernelPhase.TEARDOWN]: [], + }; + } + + // find the first call that is not revertible + const firstNonRevertibleCallIndex = callRequestsStack.findIndex( + c => nonRevertibleCallStack.findIndex(p => p.equals(c)) !== -1, + ); + + if (firstNonRevertibleCallIndex === -1) { + return { + [PublicKernelPhase.SETUP]: [], + [PublicKernelPhase.APP_LOGIC]: publicCallsStack, + [PublicKernelPhase.TEARDOWN]: [], + }; + } else { + return { + [PublicKernelPhase.SETUP]: publicCallsStack.slice(firstNonRevertibleCallIndex + 1), + [PublicKernelPhase.APP_LOGIC]: publicCallsStack.slice(0, firstNonRevertibleCallIndex), + [PublicKernelPhase.TEARDOWN]: [publicCallsStack[firstNonRevertibleCallIndex]], + }; + } + } + + protected extractEnqueuedPublicCalls(tx: Tx): PublicCallRequest[] { + return AbstractPhaseManager.extractEnqueuedPublicCallsByPhase(tx.data, tx.enqueuedPublicFunctionCalls)[this.phase]; + } - protected getKernelOutputAndProof( + public static getKernelOutputAndProof( tx: Tx, publicKernelPublicInput?: PublicKernelCircuitPublicInputs, previousPublicKernelProof?: Proof, @@ -120,10 +170,12 @@ export abstract class AbstractPhaseManager { } else { const publicKernelPublicInput = new PublicKernelCircuitPublicInputs( tx.data.aggregationObject, - tx.data.endNonRevertibleData, - CombinedAccumulatedData.fromFinalAccumulatedData(tx.data.end), + PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData), + PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end), tx.data.constants, - tx.data.isPrivate, + tx.data.needsSetup, + tx.data.needsAppLogic, + tx.data.needsTeardown, ); const publicKernelProof = previousPublicKernelProof || tx.proof; return { @@ -134,16 +186,19 @@ export abstract class AbstractPhaseManager { } protected async processEnqueuedPublicCalls( - enqueuedCalls: PublicCallRequest[], + tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs, previousPublicKernelProof: Proof, ): Promise<[PublicKernelCircuitPublicInputs, Proof, FunctionL2Logs[]]> { - if (!enqueuedCalls || !enqueuedCalls.length) { - throw new Error(`Missing preimages for enqueued public calls`); - } let kernelOutput = previousPublicKernelOutput; let kernelProof = previousPublicKernelProof; + const enqueuedCalls = this.extractEnqueuedPublicCalls(tx); + + if (!enqueuedCalls || !enqueuedCalls.length) { + return [kernelOutput, kernelProof, []]; + } + const newUnencryptedFunctionLogs: FunctionL2Logs[] = []; // TODO(#1684): Should multiple separately enqueued public calls be treated as @@ -170,7 +225,7 @@ export abstract class AbstractPhaseManager { newUnencryptedFunctionLogs.push(result.unencryptedLogs); const functionSelector = result.execution.functionData.selector.toString(); - this.log( + this.log.debug( `Running public kernel circuit for ${functionSelector}@${result.execution.contractAddress.toString()}`, ); executionStack.push(...result.nestedExecutions); @@ -208,18 +263,17 @@ export abstract class AbstractPhaseManager { previousOutput: PublicKernelCircuitPublicInputs, previousProof: Proof, ): Promise { - if (previousOutput?.isPrivate && previousProof) { - // Run the public kernel circuit with previous private kernel - const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); - const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); - return this.publicKernel.publicKernelCircuitPrivateInput(inputs); - } else if (previousOutput && previousProof) { - // Run the public kernel circuit with previous public kernel - const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); - const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); - return this.publicKernel.publicKernelCircuitNonFirstIteration(inputs); - } else { - throw new Error(`No public kernel circuit for inputs`); + const previousKernel = this.getPreviousKernelData(previousOutput, previousProof); + const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData); + switch (this.phase) { + case PublicKernelPhase.SETUP: + return this.publicKernel.publicKernelCircuitSetup(inputs); + case PublicKernelPhase.APP_LOGIC: + return this.publicKernel.publicKernelCircuitAppLogic(inputs); + case PublicKernelPhase.TEARDOWN: + return this.publicKernel.publicKernelCircuitTeardown(inputs); + default: + throw new Error(`No public kernel circuit for inputs`); } } @@ -336,95 +390,148 @@ export abstract class AbstractPhaseManager { publicInputs: PublicKernelCircuitPublicInputs, execResult: PublicExecutionResult, ) { + const { publicDataReads: revertiblePublicDataReads, publicDataUpdateRequests: revertiblePublicDataUpdateRequests } = + publicInputs.end; // from kernel + const { + publicDataReads: nonRevertiblePublicDataReads, + publicDataUpdateRequests: nonRevertiblePublicDataUpdateRequests, + } = publicInputs.endNonRevertibleData; // from kernel + // Convert ContractStorage* objects to PublicData* objects and sort them in execution order const simPublicDataReads = collectPublicDataReads(execResult); const simPublicDataUpdateRequests = collectPublicDataUpdateRequests(execResult); - const { publicDataReads, publicDataUpdateRequests } = publicInputs.end; // from kernel + const simRevertiblePublicDataReads = simPublicDataReads.filter(read => + revertiblePublicDataReads.find(item => item.leafSlot.equals(read.leafSlot) && item.value.equals(read.value)), + ); + const simRevertiblePublicDataUpdateRequests = simPublicDataUpdateRequests.filter(update => + revertiblePublicDataUpdateRequests.find( + item => item.leafSlot.equals(update.leafSlot) && item.newValue.equals(update.newValue), + ), + ); - // Validate all items in enqueued public calls are in the kernel emitted stack - const readsAreEqual = simPublicDataReads.reduce( - (accum, read) => - accum && !!publicDataReads.find(item => item.leafSlot.equals(read.leafSlot) && item.value.equals(read.value)), - true, + const simNonRevertiblePublicDataReads = simPublicDataReads.filter(read => + nonRevertiblePublicDataReads.find(item => item.leafSlot.equals(read.leafSlot) && item.value.equals(read.value)), ); - const updatesAreEqual = simPublicDataUpdateRequests.reduce( - (accum, update) => - accum && - !!publicDataUpdateRequests.find( - item => item.leafSlot.equals(update.leafSlot) && item.newValue.equals(update.newValue), - ), - true, + const simNonRevertiblePublicDataUpdateRequests = simPublicDataUpdateRequests.filter(update => + nonRevertiblePublicDataUpdateRequests.find( + item => item.leafSlot.equals(update.leafSlot) && item.newValue.equals(update.newValue), + ), ); + // Assume that kernel public inputs has the right number of items. + // We only want to reorder the items from the public inputs of the + // most recently processed top/enqueued call. + const numRevertibleReadsInKernel = arrayNonEmptyLength(publicInputs.end.publicDataReads, f => f.isEmpty()); + const numRevertibleUpdatesInKernel = arrayNonEmptyLength(publicInputs.end.publicDataUpdateRequests, f => + f.isEmpty(), + ); + const numNonRevertibleReadsInKernel = arrayNonEmptyLength(publicInputs.endNonRevertibleData.publicDataReads, f => + f.isEmpty(), + ); + const numNonRevertibleUpdatesInKernel = arrayNonEmptyLength( + publicInputs.endNonRevertibleData.publicDataUpdateRequests, + f => f.isEmpty(), + ); + + // Validate all items in enqueued public calls are in the kernel emitted stack + const readsAreEqual = + simRevertiblePublicDataReads.length + simNonRevertiblePublicDataReads.length === simPublicDataReads.length; + + const updatesAreEqual = + simRevertiblePublicDataUpdateRequests.length + simNonRevertiblePublicDataUpdateRequests.length === + simPublicDataUpdateRequests.length; + if (!readsAreEqual) { throw new Error( `Public data reads from simulator do not match those from public kernel.\nFrom simulator: ${simPublicDataReads .map(p => p.toFriendlyJSON()) - .join(', ')}\nFrom public kernel: ${publicDataReads.map(i => i.toFriendlyJSON()).join(', ')}`, + .join(', ')}\nFrom public kernel revertible: ${revertiblePublicDataReads + .map(i => i.toFriendlyJSON()) + .join(', ')}\nFrom public kernel non-revertible: ${nonRevertiblePublicDataReads + .map(i => i.toFriendlyJSON()) + .join(', ')}`, ); } if (!updatesAreEqual) { throw new Error( `Public data update requests from simulator do not match those from public kernel.\nFrom simulator: ${simPublicDataUpdateRequests .map(p => p.toFriendlyJSON()) - .join(', ')}\nFrom public kernel: ${publicDataUpdateRequests.map(i => i.toFriendlyJSON()).join(', ')}`, + .join(', ')}\nFrom public kernel revertible: ${revertiblePublicDataUpdateRequests + .map(i => i.toFriendlyJSON()) + .join(', ')}\nFrom public kernel non-revertible: ${nonRevertiblePublicDataUpdateRequests + .map(i => i.toFriendlyJSON()) + .join(', ')}`, ); } - // Assume that kernel public inputs has the right number of items. - // We only want to reorder the items from the public inputs of the - // most recently processed top/enqueued call. - const numTotalReadsInKernel = arrayNonEmptyLength( - publicInputs.end.publicDataReads, - f => f.leafSlot.equals(Fr.ZERO) && f.value.equals(Fr.ZERO), - ); - const numTotalUpdatesInKernel = arrayNonEmptyLength( - publicInputs.end.publicDataUpdateRequests, - f => f.leafSlot.equals(Fr.ZERO) && f.newValue.equals(Fr.ZERO), - ); - const numReadsBeforeThisEnqueuedCall = numTotalReadsInKernel - simPublicDataReads.length; - const numUpdatesBeforeThisEnqueuedCall = numTotalUpdatesInKernel - simPublicDataUpdateRequests.length; + const numRevertibleReadsBeforeThisEnqueuedCall = numRevertibleReadsInKernel - simRevertiblePublicDataReads.length; + const numRevertibleUpdatesBeforeThisEnqueuedCall = + numRevertibleUpdatesInKernel - simRevertiblePublicDataUpdateRequests.length; + + const numNonRevertibleReadsBeforeThisEnqueuedCall = + numNonRevertibleReadsInKernel - simNonRevertiblePublicDataReads.length; + const numNonRevertibleUpdatesBeforeThisEnqueuedCall = + numNonRevertibleUpdatesInKernel - simNonRevertiblePublicDataUpdateRequests.length; - // Override kernel output + // Override revertible kernel output publicInputs.end.publicDataReads = padArrayEnd( [ // do not mess with items from previous top/enqueued calls in kernel output - ...publicDataReads.slice(0, numReadsBeforeThisEnqueuedCall), - ...simPublicDataReads, + ...publicInputs.end.publicDataReads.slice(0, numRevertibleReadsBeforeThisEnqueuedCall), + ...simRevertiblePublicDataReads, ], PublicDataRead.empty(), - MAX_PUBLIC_DATA_READS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, ); - // Override kernel output publicInputs.end.publicDataUpdateRequests = padArrayEnd( [ - // do not mess with items from previous top/enqueued calls in kernel output - ...publicDataUpdateRequests.slice(0, numUpdatesBeforeThisEnqueuedCall), - ...simPublicDataUpdateRequests, + ...publicInputs.end.publicDataUpdateRequests.slice(0, numRevertibleUpdatesBeforeThisEnqueuedCall), + ...simRevertiblePublicDataUpdateRequests, + ], + PublicDataUpdateRequest.empty(), + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + ); + + publicInputs.endNonRevertibleData.publicDataReads = padArrayEnd( + [ + ...publicInputs.endNonRevertibleData.publicDataReads.slice(0, numNonRevertibleReadsBeforeThisEnqueuedCall), + ...simNonRevertiblePublicDataReads, + ], + PublicDataRead.empty(), + MAX_NON_REVERTIBLE_PUBLIC_DATA_READS_PER_TX, + ); + + publicInputs.endNonRevertibleData.publicDataUpdateRequests = padArrayEnd( + [ + ...publicInputs.endNonRevertibleData.publicDataUpdateRequests.slice( + 0, + numNonRevertibleUpdatesBeforeThisEnqueuedCall, + ), + ...simNonRevertiblePublicDataUpdateRequests, ], PublicDataUpdateRequest.empty(), - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_NON_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ); } private removeRedundantPublicDataWrites(publicInputs: PublicKernelCircuitPublicInputs) { - const lastWritesMap = new Map(); + const lastWritesMap = new Map(); for (const write of publicInputs.end.publicDataUpdateRequests) { const key = write.leafSlot.toString(); lastWritesMap.set(key, write); } - const lastWrites = publicInputs.end.publicDataUpdateRequests.filter( - write => lastWritesMap.get(write.leafSlot.toString()) === write, + const lastWrites = publicInputs.end.publicDataUpdateRequests.filter(write => + lastWritesMap.get(write.leafSlot.toString())?.equals(write), ); publicInputs.end.publicDataUpdateRequests = padArrayEnd( lastWrites, PublicDataUpdateRequest.empty(), - MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, + MAX_REVERTIBLE_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, ); } } diff --git a/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts new file mode 100644 index 000000000000..01fee546818c --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/app_logic_phase_manager.ts @@ -0,0 +1,72 @@ +import { Tx } from '@aztec/circuit-types'; +import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; +import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; +import { MerkleTreeOperations } from '@aztec/world-state'; + +import { PublicProver } from '../prover/index.js'; +import { PublicKernelCircuitSimulator } from '../simulator/index.js'; +import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; +import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js'; +import { FailedTx } from './processed_tx.js'; + +/** + * The phase manager responsible for performing the fee preparation phase. + */ +export class AppLogicPhaseManager extends AbstractPhaseManager { + constructor( + protected db: MerkleTreeOperations, + protected publicExecutor: PublicExecutor, + protected publicKernel: PublicKernelCircuitSimulator, + protected publicProver: PublicProver, + protected globalVariables: GlobalVariables, + protected historicalHeader: Header, + protected publicContractsDB: ContractsDataSourcePublicDB, + protected publicStateDB: PublicStateDB, + public phase: PublicKernelPhase = PublicKernelPhase.APP_LOGIC, + ) { + super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader, phase); + } + + async handle( + tx: Tx, + previousPublicKernelOutput: PublicKernelCircuitPublicInputs, + previousPublicKernelProof: Proof, + ): Promise<{ + /** + * the output of the public kernel circuit for this phase + */ + publicKernelOutput: PublicKernelCircuitPublicInputs; + /** + * the proof of the public kernel circuit for this phase + */ + publicKernelProof: Proof; + }> { + // add new contracts to the contracts db so that their functions may be found and called + this.log(`Processing tx ${tx.getTxHash()}`); + await this.publicContractsDB.addNewContracts(tx); + this.log(`Executing enqueued public calls for tx ${tx.getTxHash()}`); + const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls( + tx, + previousPublicKernelOutput, + previousPublicKernelProof, + ); + tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); + + // commit the state updates from this transaction + await this.publicStateDB.commit(); + + return { publicKernelOutput, publicKernelProof }; + } + + async rollback(tx: Tx, err: unknown): Promise { + this.log.warn(`Error processing tx ${tx.getTxHash()}: ${err}`); + // remove contracts on failure + await this.publicContractsDB.removeNewContracts(tx); + // rollback any state updates from this failed transaction + await this.publicStateDB.rollback(); + return { + tx, + error: err instanceof Error ? err : new Error('Unknown error'), + }; + } +} diff --git a/yarn-project/sequencer-client/src/sequencer/application_logic_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/application_logic_phase_manager.ts deleted file mode 100644 index 0d53e0dcf782..000000000000 --- a/yarn-project/sequencer-client/src/sequencer/application_logic_phase_manager.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Tx } from '@aztec/circuit-types'; -import { GlobalVariables, Header, Proof, PublicCallRequest, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; -import { isArrayEmpty } from '@aztec/foundation/collection'; -import { createDebugLogger } from '@aztec/foundation/log'; -import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; -import { MerkleTreeOperations } from '@aztec/world-state'; - -import { PublicProver } from '../prover/index.js'; -import { PublicKernelCircuitSimulator } from '../simulator/index.js'; -import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; -import { AbstractPhaseManager } from './abstract_phase_manager.js'; -import { FeeDistributionPhaseManager } from './fee_distribution_phase_manager.js'; -import { FailedTx } from './processed_tx.js'; - -/** - * The phase manager responsible for performing the fee preparation phase. - */ -export class ApplicationLogicPhaseManager extends AbstractPhaseManager { - constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected publicProver: PublicProver, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, - - protected log = createDebugLogger('aztec:sequencer:application-logic'), - ) { - super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader); - } - - extractEnqueuedPublicCalls(tx: Tx): PublicCallRequest[] { - if (!tx.enqueuedPublicFunctionCalls) { - throw new Error(`Missing preimages for enqueued public calls`); - } - // Note: the first enqueued public call is for fee payments - // TODO(dbanks12): why must these be reversed? - return tx.enqueuedPublicFunctionCalls.slice().reverse(); - } - - async handle( - tx: Tx, - previousPublicKernelOutput?: PublicKernelCircuitPublicInputs, - previousPublicKernelProof?: Proof, - ): Promise<{ - /** - * the output of the public kernel circuit for this phase - */ - publicKernelOutput?: PublicKernelCircuitPublicInputs; - /** - * the proof of the public kernel circuit for this phase - */ - publicKernelProof?: Proof; - }> { - // add new contracts to the contracts db so that their functions may be found and called - this.log(`Processing tx ${await tx.getTxHash()}`); - await this.publicContractsDB.addNewContracts(tx); - if (!isArrayEmpty(tx.data.end.publicCallStack, item => item.isEmpty())) { - const outputAndProof = this.getKernelOutputAndProof(tx, previousPublicKernelOutput, previousPublicKernelProof); - - this.log(`Executing enqueued public calls for tx ${await tx.getTxHash()}`); - const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls( - this.extractEnqueuedPublicCalls(tx), - outputAndProof.publicKernelPublicInput, - outputAndProof.publicKernelProof, - ); - tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); - - // commit the state updates from this transaction - await this.publicStateDB.commit(); - - return { publicKernelOutput, publicKernelProof }; - } else { - return { - publicKernelOutput: undefined, - publicKernelProof: undefined, - }; - } - } - - nextPhase() { - return new FeeDistributionPhaseManager( - this.db, - this.publicExecutor, - this.publicKernel, - this.publicProver, - this.globalVariables, - this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, - ); - } - - async rollback(tx: Tx, err: unknown): Promise { - this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`); - // remove contracts on failure - await this.publicContractsDB.removeNewContracts(tx); - // rollback any state updates from this failed transaction - await this.publicStateDB.rollback(); - return { - tx, - error: err instanceof Error ? err : new Error('Unknown error'), - }; - } -} diff --git a/yarn-project/sequencer-client/src/sequencer/fee_preparation_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/fee_preparation_phase_manager.ts deleted file mode 100644 index d54e8ac10ce8..000000000000 --- a/yarn-project/sequencer-client/src/sequencer/fee_preparation_phase_manager.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Tx } from '@aztec/circuit-types'; -import { GlobalVariables, Header, Proof, PublicCallRequest, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; -import { createDebugLogger } from '@aztec/foundation/log'; -import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; -import { MerkleTreeOperations } from '@aztec/world-state'; - -import { PublicProver } from '../prover/index.js'; -import { PublicKernelCircuitSimulator } from '../simulator/index.js'; -import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; -import { AbstractPhaseManager } from './abstract_phase_manager.js'; -import { ApplicationLogicPhaseManager } from './application_logic_phase_manager.js'; -import { FailedTx } from './processed_tx.js'; - -/** - * The phase manager responsible for performing the fee preparation phase. - */ -export class FeePreparationPhaseManager extends AbstractPhaseManager { - constructor( - protected db: MerkleTreeOperations, - protected publicExecutor: PublicExecutor, - protected publicKernel: PublicKernelCircuitSimulator, - protected publicProver: PublicProver, - protected globalVariables: GlobalVariables, - protected historicalHeader: Header, - protected publicContractsDB: ContractsDataSourcePublicDB, - protected publicStateDB: PublicStateDB, - - protected log = createDebugLogger('aztec:sequencer:fee-preparation'), - ) { - super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader); - } - - extractEnqueuedPublicCalls(_tx: Tx): PublicCallRequest[] { - return []; - } - - // this is a no-op for now - async handle( - tx: Tx, - previousPublicKernelOutput?: PublicKernelCircuitPublicInputs, - previousPublicKernelProof?: Proof, - ): Promise<{ - /** - * the output of the public kernel circuit for this phase - */ - publicKernelOutput?: PublicKernelCircuitPublicInputs; - /** - * the proof of the public kernel circuit for this phase - */ - publicKernelProof?: Proof; - }> { - this.log.debug(`Handle ${await tx.getTxHash()} with no-op`); - return { - publicKernelOutput: previousPublicKernelOutput, - publicKernelProof: previousPublicKernelProof, - }; - } - - nextPhase(): AbstractPhaseManager { - return new ApplicationLogicPhaseManager( - this.db, - this.publicExecutor, - this.publicKernel, - this.publicProver, - this.globalVariables, - this.historicalHeader, - this.publicContractsDB, - this.publicStateDB, - ); - } - - async rollback(tx: Tx, err: unknown): Promise { - this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`); - return { - tx, - error: err instanceof Error ? err : new Error('Unknown error'), - }; - } -} diff --git a/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts b/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts new file mode 100644 index 000000000000..845b5cb28a98 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/phase_manager_factory.ts @@ -0,0 +1,122 @@ +import { Tx } from '@aztec/circuit-types'; +import { GlobalVariables, Header, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; +import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; +import { MerkleTreeOperations } from '@aztec/world-state'; + +import { PublicProver } from '../prover/index.js'; +import { PublicKernelCircuitSimulator } from '../simulator/index.js'; +import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; +import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js'; +import { AppLogicPhaseManager } from './app_logic_phase_manager.js'; +import { SetupPhaseManager } from './setup_phase_manager.js'; +import { TeardownPhaseManager } from './teardown_phase_manager.js'; + +export class PhaseDidNotChangeError extends Error { + constructor(phase: PublicKernelPhase) { + super(`Tried to advance the phase from [${phase}] when the circuit still needs [${phase}]`); + } +} + +export class CannotTransitionToSetupError extends Error { + constructor() { + super('Cannot transition to setup phase'); + } +} + +export class PhaseManagerFactory { + public static phaseFromTx( + tx: Tx, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + publicProver: PublicProver, + globalVariables: GlobalVariables, + historicalHeader: Header, + publicContractsDB: ContractsDataSourcePublicDB, + publicStateDB: PublicStateDB, + ): AbstractPhaseManager | undefined { + if (tx.data.needsSetup) { + return new SetupPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + globalVariables, + historicalHeader, + publicContractsDB, + publicStateDB, + ); + } else if (tx.data.needsAppLogic) { + return new AppLogicPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + globalVariables, + historicalHeader, + publicContractsDB, + publicStateDB, + ); + } else if (tx.data.needsTeardown) { + return new TeardownPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + globalVariables, + historicalHeader, + publicContractsDB, + publicStateDB, + ); + } else { + return undefined; + } + } + + public static phaseFromOutput( + output: PublicKernelCircuitPublicInputs, + currentPhaseManager: AbstractPhaseManager, + db: MerkleTreeOperations, + publicExecutor: PublicExecutor, + publicKernel: PublicKernelCircuitSimulator, + publicProver: PublicProver, + globalVariables: GlobalVariables, + historicalHeader: Header, + publicContractsDB: ContractsDataSourcePublicDB, + publicStateDB: PublicStateDB, + ): AbstractPhaseManager | undefined { + if (output.needsSetup) { + throw new CannotTransitionToSetupError(); + } else if (output.needsAppLogic) { + if (currentPhaseManager.phase === PublicKernelPhase.APP_LOGIC) { + throw new PhaseDidNotChangeError(currentPhaseManager.phase); + } + return new AppLogicPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + globalVariables, + historicalHeader, + publicContractsDB, + publicStateDB, + ); + } else if (output.needsTeardown) { + if (currentPhaseManager.phase === PublicKernelPhase.TEARDOWN) { + throw new PhaseDidNotChangeError(currentPhaseManager.phase); + } + return new TeardownPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + globalVariables, + historicalHeader, + publicContractsDB, + publicStateDB, + ); + } else { + return undefined; + } + } +} diff --git a/yarn-project/sequencer-client/src/sequencer/processed_tx.ts b/yarn-project/sequencer-client/src/sequencer/processed_tx.ts index c96d5219cd5f..206c190b04a6 100644 --- a/yarn-project/sequencer-client/src/sequencer/processed_tx.ts +++ b/yarn-project/sequencer-client/src/sequencer/processed_tx.ts @@ -1,9 +1,10 @@ import { ExtendedContractData, Tx, TxHash, TxL2Logs } from '@aztec/circuit-types'; import { - CombinedAccumulatedData, Fr, Header, Proof, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, PublicKernelCircuitPublicInputs, makeEmptyProof, } from '@aztec/circuits.js'; @@ -47,21 +48,19 @@ export type FailedTx = { * @param kernelOutput - Output of the kernel circuit simulation for this tx. * @param proof - Proof of the kernel circuit for this tx. */ -export async function makeProcessedTx( - tx: Tx, - kernelOutput?: PublicKernelCircuitPublicInputs, - proof?: Proof, -): Promise { +export function makeProcessedTx(tx: Tx, kernelOutput?: PublicKernelCircuitPublicInputs, proof?: Proof): ProcessedTx { return { - hash: await tx.getTxHash(), + hash: tx.getTxHash(), data: kernelOutput ?? new PublicKernelCircuitPublicInputs( tx.data.aggregationObject, - tx.data.endNonRevertibleData, - CombinedAccumulatedData.fromFinalAccumulatedData(tx.data.end), + PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData), + PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end), tx.data.constants, - tx.data.isPrivate, + tx.data.needsSetup, + tx.data.needsAppLogic, + tx.data.needsTeardown, ), proof: proof ?? tx.proof, encryptedLogs: tx.encryptedLogs, @@ -75,7 +74,7 @@ export async function makeProcessedTx( * Makes an empty tx from an empty kernel circuit public inputs. * @returns A processed empty tx. */ -export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): Promise { +export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): ProcessedTx { const emptyKernelOutput = PublicKernelCircuitPublicInputs.empty(); emptyKernelOutput.constants.historicalHeader = header; emptyKernelOutput.constants.txContext.chainId = chainId; @@ -83,7 +82,7 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): const emptyProof = makeEmptyProof(); const hash = new TxHash(Fr.ZERO.toBuffer()); - return Promise.resolve({ + return { hash, encryptedLogs: new TxL2Logs([]), unencryptedLogs: new TxL2Logs([]), @@ -91,5 +90,5 @@ export function makeEmptyProcessedTx(header: Header, chainId: Fr, version: Fr): proof: emptyProof, newContracts: [ExtendedContractData.empty()], isEmpty: true, - }); + }; } 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 b1ebcbadd477..e2bc9e78a035 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -13,16 +13,18 @@ import { AztecAddress, CallContext, CallRequest, - CombinedAccumulatedData, EthAddress, Fr, FunctionData, GlobalVariables, Header, + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, PUBLIC_DATA_TREE_HEIGHT, Proof, + PublicAccumulatedNonRevertibleData, + PublicAccumulatedRevertibleData, PublicCallRequest, PublicKernelCircuitPublicInputs, makeEmptyProof, @@ -44,6 +46,7 @@ import { PublicProver } from '../prover/index.js'; import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { ContractsDataSourcePublicDB, WorldStatePublicDB } from '../simulator/public_executor.js'; import { RealPublicKernelCircuitSimulator } from '../simulator/public_kernel.js'; +import { ProcessedTx } from './processed_tx.js'; import { PublicProcessor } from './public_processor.js'; describe('public_processor', () => { @@ -92,27 +95,51 @@ describe('public_processor', () => { it('skips txs without public execution requests', async function () { const tx = mockTx(); - tx.data.end.publicCallStack = makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, CallRequest.empty); - const hash = await tx.getTxHash(); + 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, + CallRequest.empty, + ); + tx.data.needsSetup = false; + tx.data.needsAppLogic = false; + tx.data.needsTeardown = false; + + const hash = tx.getTxHash(); const [processed, failed] = await processor.process([tx]); - expect(processed).toEqual([ - { - isEmpty: false, - hash, - data: new PublicKernelCircuitPublicInputs( - tx.data.aggregationObject, - tx.data.endNonRevertibleData, - CombinedAccumulatedData.fromFinalAccumulatedData(tx.data.end), - tx.data.constants, - tx.data.isPrivate, - ), - proof: tx.proof, - encryptedLogs: tx.encryptedLogs, - unencryptedLogs: tx.unencryptedLogs, - newContracts: tx.newContracts, - }, - ]); + expect(processed.length).toBe(1); + + const p = processed[0]; + const e = { + hash, + data: new PublicKernelCircuitPublicInputs( + tx.data.aggregationObject, + PublicAccumulatedNonRevertibleData.fromPrivateAccumulatedNonRevertibleData(tx.data.endNonRevertibleData), + PublicAccumulatedRevertibleData.fromPrivateAccumulatedRevertibleData(tx.data.end), + tx.data.constants, + tx.data.needsSetup, + tx.data.needsAppLogic, + tx.data.needsTeardown, + ), + proof: tx.proof, + encryptedLogs: tx.encryptedLogs, + unencryptedLogs: tx.unencryptedLogs, + newContracts: tx.newContracts, + isEmpty: false, + }; + + // Jest is complaining that the two objects are not equal, but they are. + // It expects something and says "Received: serializes to the same string" + // TODO why can't we just expect(p).toEqual(e) here anymore? + expect(Object.keys(p)).toEqual(Object.keys(e)); + for (const key in e) { + if (key === 'data') { + expect(p.data.toBuffer()).toEqual(e.data.toBuffer()); + } else { + expect(p[key as keyof ProcessedTx]).toEqual(e[key as keyof ProcessedTx]); + } + } + expect(failed).toEqual([]); }); @@ -148,9 +175,9 @@ describe('public_processor', () => { ); }); - const expectedTxByHash = async (tx: Tx) => + const expectedTxByHash = (tx: Tx) => expect.objectContaining({ - hash: await tx.getTxHash(), + hash: tx.getTxHash(), proof, }); @@ -162,14 +189,22 @@ describe('public_processor', () => { kernelOutput.end.publicCallStack = padArrayEnd( callRequests, CallRequest.empty(), - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + 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, + ); + const tx = new Tx(kernelOutput, proof, TxL2Logs.random(2, 3), TxL2Logs.random(3, 2), publicCallRequests, [ ExtendedContractData.random(), ]); + tx.data.needsSetup = false; + tx.data.needsTeardown = false; + publicExecutor.simulate.mockImplementation(execution => { for (const request of publicCallRequests) { if (execution.contractAddress.equals(request.contractAddress)) { @@ -182,7 +217,7 @@ describe('public_processor', () => { const [processed, failed] = await processor.process([tx]); expect(processed).toHaveLength(1); - expect(processed).toEqual([await expectedTxByHash(tx)]); + expect(processed).toEqual([expectedTxByHash(tx)]); expect(failed).toHaveLength(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(2); expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); @@ -197,9 +232,16 @@ describe('public_processor', () => { kernelOutput.end.publicCallStack = padArrayEnd( [callStackItem], CallRequest.empty(), - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + 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.needsSetup = false; + kernelOutput.needsTeardown = false; const tx = new Tx( kernelOutput, @@ -223,7 +265,7 @@ describe('public_processor', () => { const [processed, failed] = await processor.process([tx]); expect(processed).toHaveLength(1); - expect(processed).toEqual([await expectedTxByHash(tx)]); + expect(processed).toEqual([expectedTxByHash(tx)]); expect(failed).toHaveLength(0); expect(publicExecutor.simulate).toHaveBeenCalledTimes(1); expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(1); @@ -238,10 +280,13 @@ describe('public_processor', () => { kernelOutput.end.publicCallStack = padArrayEnd( [callStackItem], CallRequest.empty(), - MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, + 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, + ); const tx = new Tx( kernelOutput, proof, @@ -251,6 +296,9 @@ describe('public_processor', () => { [ExtendedContractData.random()], ); + tx.data.needsSetup = false; + tx.data.needsTeardown = false; + const publicExecutionResult = makePublicExecutionResultFromRequest(callRequest); publicExecutionResult.nestedExecutions = [ makePublicExecutionResult(publicExecutionResult.execution.contractAddress, { @@ -269,6 +317,51 @@ describe('public_processor', () => { expect(publicWorldStateDB.rollback).toHaveBeenCalledTimes(1); expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(0); }); + + it('runs a tx with setup and teardown phases', async function () { + const callRequests: PublicCallRequest[] = [0x100, 0x200, 0x300].map(makePublicCallRequest); + + const kernelOutput = makePrivateKernelTailCircuitPublicInputs(0x10); + + // the first two calls are non-revertible + // the first is for setup, the second is for teardown + kernelOutput.endNonRevertibleData.publicCallStack = padArrayEnd( + // this is a stack, so the first item is the last call + // and callRequests is in the order of the calls + [callRequests[1].toCallRequest(), callRequests[0].toCallRequest()], + CallRequest.empty(), + MAX_NON_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + ); + + kernelOutput.end.publicCallStack = padArrayEnd( + [callRequests[2].toCallRequest()], + CallRequest.empty(), + MAX_REVERTIBLE_PUBLIC_CALL_STACK_LENGTH_PER_TX, + ); + kernelOutput.end.privateCallStack = padArrayEnd([], CallRequest.empty(), MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX); + + const tx = new Tx(kernelOutput, proof, TxL2Logs.random(2, 3), TxL2Logs.random(3, 2), callRequests, [ + ExtendedContractData.random(), + ]); + + publicExecutor.simulate.mockImplementation(execution => { + for (const request of callRequests) { + if (execution.contractAddress.equals(request.contractAddress)) { + return Promise.resolve(makePublicExecutionResultFromRequest(request)); + } + } + throw new Error(`Unexpected execution request: ${execution}`); + }); + + const [processed, failed] = await processor.process([tx]); + + expect(processed).toHaveLength(1); + expect(processed).toEqual([expectedTxByHash(tx)]); + expect(failed).toHaveLength(0); + expect(publicExecutor.simulate).toHaveBeenCalledTimes(3); + expect(publicWorldStateDB.commit).toHaveBeenCalledTimes(3); + expect(publicWorldStateDB.rollback).toHaveBeenCalledTimes(0); + }); }); }); diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.ts index 0b123a5a32b2..99189c376a1b 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.ts @@ -1,6 +1,6 @@ import { ContractDataSource, L1ToL2MessageSource, Tx } from '@aztec/circuit-types'; import { TxSequencerProcessingStats } from '@aztec/circuit-types/stats'; -import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; +import { GlobalVariables, Header } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; @@ -12,7 +12,7 @@ import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from '../simulator/public_executor.js'; import { RealPublicKernelCircuitSimulator } from '../simulator/public_kernel.js'; import { AbstractPhaseManager } from './abstract_phase_manager.js'; -import { FeePreparationPhaseManager } from './fee_preparation_phase_manager.js'; +import { PhaseManagerFactory } from './phase_manager_factory.js'; import { FailedTx, ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js'; /** @@ -85,7 +85,8 @@ export class PublicProcessor { const failed: FailedTx[] = []; for (const tx of txs) { - let phase: AbstractPhaseManager | undefined = new FeePreparationPhaseManager( + let phase: AbstractPhaseManager | undefined = PhaseManagerFactory.phaseFromTx( + tx, this.db, this.publicExecutor, this.publicKernel, @@ -95,25 +96,41 @@ export class PublicProcessor { this.publicContractsDB, this.publicStateDB, ); - let publicKernelOutput: PublicKernelCircuitPublicInputs | undefined = undefined; - let publicKernelProof: Proof | undefined = undefined; + this.log(`Beginning processing in phase ${phase?.phase} for tx ${tx.getTxHash()}`); + let { publicKernelPublicInput, publicKernelProof } = AbstractPhaseManager.getKernelOutputAndProof( + tx, + undefined, + undefined, + ); const timer = new Timer(); try { while (phase) { - const output = await phase.handle(tx, publicKernelOutput, publicKernelProof); - publicKernelOutput = output.publicKernelOutput; + const output = await phase.handle(tx, publicKernelPublicInput, publicKernelProof); + publicKernelPublicInput = output.publicKernelOutput; publicKernelProof = output.publicKernelProof; - phase = phase.nextPhase(); + phase = PhaseManagerFactory.phaseFromOutput( + publicKernelPublicInput, + phase, + this.db, + this.publicExecutor, + this.publicKernel, + this.publicProver, + this.globalVariables, + this.historicalHeader, + this.publicContractsDB, + this.publicStateDB, + ); } - const processedTransaction = await makeProcessedTx(tx, publicKernelOutput, publicKernelProof); + const processedTransaction = makeProcessedTx(tx, publicKernelPublicInput, publicKernelProof); result.push(processedTransaction); - this.log(`Processed public part of ${tx.data.end.newNullifiers[0]}`, { + this.log(`Processed public part of ${tx.data.endNonRevertibleData.newNullifiers[0]}`, { eventName: 'tx-sequencer-processing', duration: timer.ms(), publicDataUpdateRequests: - processedTransaction.data.end.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ?? 0, + processedTransaction.data.combinedData.publicDataUpdateRequests.filter(x => !x.leafSlot.isZero()).length ?? + 0, ...tx.getStats(), } satisfies TxSequencerProcessingStats); } catch (err) { @@ -129,7 +146,7 @@ export class PublicProcessor { * Makes an empty processed tx. Useful for padding a block to a power of two number of txs. * @returns A processed tx with empty data. */ - public makeEmptyProcessedTx(): Promise { + public makeEmptyProcessedTx(): ProcessedTx { const { chainId, version } = this.globalVariables; return makeEmptyProcessedTx(this.historicalHeader, chainId, version); } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index dc433041bb51..d6a655bc4aa1 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -114,7 +114,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = [...(await Tx.getHashes([tx])), ...times(1, () => TxHash.ZERO)]; + const expectedTxHashes = [...Tx.getHashes([tx]), ...times(1, () => TxHash.ZERO)]; expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO, coinbase, feeRecipient), @@ -151,7 +151,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = await Tx.getHashes([txs[0], txs[2]]); + const expectedTxHashes = Tx.getHashes([txs[0], txs[2]]); expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO, coinbase, feeRecipient), @@ -159,7 +159,7 @@ describe('sequencer', () => { Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)), ); expect(publisher.processL2Block).toHaveBeenCalledWith(block); - expect(p2p.deleteTxs).toHaveBeenCalledWith([await doubleSpendTx.getTxHash()]); + expect(p2p.deleteTxs).toHaveBeenCalledWith([doubleSpendTx.getTxHash()]); }); it('builds a block out of several txs rejecting incorrect chain ids', async () => { @@ -184,7 +184,7 @@ describe('sequencer', () => { await sequencer.initialSync(); await sequencer.work(); - const expectedTxHashes = await Tx.getHashes([txs[0], txs[2]]); + const expectedTxHashes = Tx.getHashes([txs[0], txs[2]]); expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( new GlobalVariables(chainId, version, new Fr(lastBlockNumber + 1), Fr.ZERO, coinbase, feeRecipient), @@ -192,7 +192,7 @@ describe('sequencer', () => { Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(new Fr(0n)), ); expect(publisher.processL2Block).toHaveBeenCalledWith(block); - expect(p2p.deleteTxs).toHaveBeenCalledWith([await invalidChainTx.getTxHash()]); + expect(p2p.deleteTxs).toHaveBeenCalledWith([invalidChainTx.getTxHash()]); }); it('aborts building a block if the chain moves underneath it', async () => { @@ -250,8 +250,8 @@ describe('sequencer', () => { expect(blockBuilder.buildL2Block).toHaveBeenCalledWith( expect.anything(), expect.arrayContaining([ - expect.objectContaining({ hash: await txWithContract.getTxHash() }), - expect.objectContaining({ hash: await txWithEmptyContract.getTxHash() }), + expect.objectContaining({ hash: txWithContract.getTxHash() }), + expect.objectContaining({ hash: txWithEmptyContract.getTxHash() }), ]), expect.any(Array), ); diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.ts index da7df333d2d3..08cc58cdd5ea 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.ts @@ -186,8 +186,8 @@ export class Sequencer { const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs)); if (failedTxs.length > 0) { const failedTxData = failedTxs.map(fail => fail.tx); - this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`); - await this.p2pClient.deleteTxs(await Tx.getHashes(failedTxData)); + this.log(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`); + await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData)); } // Only accept processed transactions that are not double-spends, @@ -213,7 +213,7 @@ export class Sequencer { await assertBlockHeight(); - const emptyTx = await processor.makeEmptyProcessedTx(); + const emptyTx = processor.makeEmptyProcessedTx(); const [rollupCircuitsDuration, block] = await elapsed(() => this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables), ); @@ -296,7 +296,7 @@ export class Sequencer { for (const tx of txs) { if (tx.data.constants.txContext.chainId.value !== globalVariables.chainId.value) { this.log( - `Deleting tx for incorrect chain ${tx.data.constants.txContext.chainId.toString()}, tx hash ${await Tx.getHash( + `Deleting tx for incorrect chain ${tx.data.constants.txContext.chainId.toString()}, tx hash ${Tx.getHash( tx, )}`, ); @@ -304,17 +304,18 @@ export class Sequencer { continue; } if (await this.isTxDoubleSpend(tx)) { - this.log(`Deleting double spend tx ${await Tx.getHash(tx)}`); + this.log(`Deleting double spend tx ${Tx.getHash(tx)}`); txsToDelete.push(tx); continue; } else if (this.isTxDoubleSpendSameBlock(tx, thisBlockNullifiers)) { // We don't drop these txs from the p2p pool immediately since they become valid // again if the current block fails to be published for some reason. - this.log(`Skipping tx with double-spend for this same block ${await Tx.getHash(tx)}`); + this.log(`Skipping tx with double-spend for this same block ${Tx.getHash(tx)}`); continue; } tx.data.end.newNullifiers.forEach(n => thisBlockNullifiers.add(n.value.toBigInt())); + tx.data.endNonRevertibleData.newNullifiers.forEach(n => thisBlockNullifiers.add(n.value.toBigInt())); validTxs.push(tx); if (validTxs.length >= this.maxTxsPerBlock) { break; @@ -323,7 +324,7 @@ export class Sequencer { // Make sure we remove these from the tx pool so we do not consider it again if (txsToDelete.length > 0) { - await this.p2pClient.deleteTxs(await Tx.getHashes([...txsToDelete])); + await this.p2pClient.deleteTxs(Tx.getHashes([...txsToDelete])); } return validTxs; @@ -385,7 +386,10 @@ export class Sequencer { */ protected isTxDoubleSpendSameBlock(tx: Tx | ProcessedTx, thisBlockNullifiers: Set): boolean { // We only consider non-empty nullifiers - const newNullifiers = tx.data.end.newNullifiers.filter(n => !n.isEmpty()); + const newNullifiers = [ + ...tx.data.endNonRevertibleData.newNullifiers.filter(n => !n.isEmpty()), + ...tx.data.end.newNullifiers.filter(n => !n.isEmpty()), + ]; for (const nullifier of newNullifiers) { if (thisBlockNullifiers.has(nullifier.value.toBigInt())) { @@ -403,7 +407,10 @@ export class Sequencer { */ protected async isTxDoubleSpend(tx: Tx | ProcessedTx): Promise { // We only consider non-empty nullifiers - const newNullifiers = tx.data.end.newNullifiers.filter(n => !n.isEmpty()); + const newNullifiers = [ + ...tx.data.endNonRevertibleData.newNullifiers.filter(n => !n.isEmpty()), + ...tx.data.end.newNullifiers.filter(n => !n.isEmpty()), + ]; // Ditch this tx if it has a repeated nullifiers const uniqNullifiers = new Set(newNullifiers.map(n => n.value.toBigInt())); 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 new file mode 100644 index 000000000000..853bd0e8d1a0 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.test.ts @@ -0,0 +1,79 @@ +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, + Proof, + makeEmptyProof, +} from '@aztec/circuits.js'; +import { makeTuple } from '@aztec/foundation/array'; +import { PublicExecutor } from '@aztec/simulator'; +import { MerkleTreeOperations, TreeInfo } from '@aztec/world-state'; + +import { it } from '@jest/globals'; +import { MockProxy, mock } from 'jest-mock-extended'; + +import { PublicProver } from '../prover/index.js'; +import { PublicKernelCircuitSimulator } from '../simulator/index.js'; +import { ContractsDataSourcePublicDB, WorldStatePublicDB } from '../simulator/public_executor.js'; +import { SetupPhaseManager } from './setup_phase_manager.js'; + +class TestSetupPhaseManager extends SetupPhaseManager { + extractEnqueuedPublicCalls(tx: any) { + return super.extractEnqueuedPublicCalls(tx); + } +} + +describe('setup_phase_manager', () => { + let db: MockProxy; + let publicExecutor: MockProxy; + let publicProver: MockProxy; + let publicContractsDB: MockProxy; + let publicWorldStateDB: MockProxy; + let publicKernel: MockProxy; + + let proof: Proof; + let root: Buffer; + + let phaseManager: TestSetupPhaseManager; + + beforeEach(() => { + db = mock(); + publicExecutor = mock(); + publicProver = mock(); + publicContractsDB = mock(); + publicWorldStateDB = mock(); + + proof = makeEmptyProof(); + root = Buffer.alloc(32, 5); + + publicProver.getPublicCircuitProof.mockResolvedValue(proof); + publicProver.getPublicKernelCircuitProof.mockResolvedValue(proof); + db.getTreeInfo.mockResolvedValue({ root } as TreeInfo); + publicKernel = mock(); + phaseManager = new TestSetupPhaseManager( + db, + publicExecutor, + publicKernel, + publicProver, + GlobalVariables.empty(), + Header.empty(), + publicContractsDB, + publicWorldStateDB, + ); + }); + + 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, + CallRequest.empty, + ); + const enqueuedNonRevertibleCalls = phaseManager.extractEnqueuedPublicCalls(tx); + + expect(enqueuedNonRevertibleCalls).toEqual([]); + }); +}); diff --git a/yarn-project/sequencer-client/src/sequencer/fee_distribution_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts similarity index 53% rename from yarn-project/sequencer-client/src/sequencer/fee_distribution_phase_manager.ts rename to yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts index a59608ba4036..efac1e362028 100644 --- a/yarn-project/sequencer-client/src/sequencer/fee_distribution_phase_manager.ts +++ b/yarn-project/sequencer-client/src/sequencer/setup_phase_manager.ts @@ -1,19 +1,18 @@ import { Tx } from '@aztec/circuit-types'; -import { GlobalVariables, Header, Proof, PublicCallRequest, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; -import { createDebugLogger } from '@aztec/foundation/log'; +import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; import { MerkleTreeOperations } from '@aztec/world-state'; import { PublicProver } from '../prover/index.js'; import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; -import { AbstractPhaseManager } from './abstract_phase_manager.js'; +import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js'; import { FailedTx } from './processed_tx.js'; /** * The phase manager responsible for performing the fee preparation phase. */ -export class FeeDistributionPhaseManager extends AbstractPhaseManager { +export class SetupPhaseManager extends AbstractPhaseManager { constructor( protected db: MerkleTreeOperations, protected publicExecutor: PublicExecutor, @@ -23,45 +22,44 @@ export class FeeDistributionPhaseManager extends AbstractPhaseManager { protected historicalHeader: Header, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, - - protected log = createDebugLogger('aztec:sequencer:fee-distribution'), + public phase: PublicKernelPhase = PublicKernelPhase.SETUP, ) { - super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader); - } - - // this is a no-op for now - extractEnqueuedPublicCalls(_tx: Tx): PublicCallRequest[] { - return []; + super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader, phase); } // this is a no-op for now async handle( tx: Tx, - previousPublicKernelOutput?: PublicKernelCircuitPublicInputs, - previousPublicKernelProof?: Proof, + previousPublicKernelOutput: PublicKernelCircuitPublicInputs, + previousPublicKernelProof: Proof, ): Promise<{ /** * the output of the public kernel circuit for this phase */ - publicKernelOutput?: PublicKernelCircuitPublicInputs; + publicKernelOutput: PublicKernelCircuitPublicInputs; /** * the proof of the public kernel circuit for this phase */ - publicKernelProof?: Proof; + publicKernelProof: Proof; }> { - this.log.debug(`Handle ${await tx.getTxHash()} with no-op`); - return { - publicKernelOutput: previousPublicKernelOutput, - publicKernelProof: previousPublicKernelProof, - }; - } + this.log(`Processing tx ${tx.getTxHash()}`); + this.log(`Executing enqueued public calls for tx ${tx.getTxHash()}`); + const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls( + tx, + previousPublicKernelOutput, + previousPublicKernelProof, + ); + tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); + + // commit the state updates from this transaction + await this.publicStateDB.commit(); - nextPhase() { - return undefined; + return { publicKernelOutput, publicKernelProof }; } async rollback(tx: Tx, err: unknown): Promise { - this.log.warn(`Error processing tx ${await tx.getTxHash()}: ${err}`); + this.log.warn(`Error processing tx ${tx.getTxHash()}: ${err}`); + await this.publicStateDB.rollback(); return { tx, error: err instanceof Error ? err : new Error('Unknown error'), diff --git a/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts b/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts new file mode 100644 index 000000000000..48cc3d8b0b76 --- /dev/null +++ b/yarn-project/sequencer-client/src/sequencer/teardown_phase_manager.ts @@ -0,0 +1,67 @@ +import { Tx } from '@aztec/circuit-types'; +import { GlobalVariables, Header, Proof, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; +import { PublicExecutor, PublicStateDB } from '@aztec/simulator'; +import { MerkleTreeOperations } from '@aztec/world-state'; + +import { PublicProver } from '../prover/index.js'; +import { PublicKernelCircuitSimulator } from '../simulator/index.js'; +import { ContractsDataSourcePublicDB } from '../simulator/public_executor.js'; +import { AbstractPhaseManager, PublicKernelPhase } from './abstract_phase_manager.js'; +import { FailedTx } from './processed_tx.js'; + +/** + * The phase manager responsible for performing the fee preparation phase. + */ +export class TeardownPhaseManager extends AbstractPhaseManager { + constructor( + protected db: MerkleTreeOperations, + protected publicExecutor: PublicExecutor, + protected publicKernel: PublicKernelCircuitSimulator, + protected publicProver: PublicProver, + protected globalVariables: GlobalVariables, + protected historicalHeader: Header, + protected publicContractsDB: ContractsDataSourcePublicDB, + protected publicStateDB: PublicStateDB, + public phase: PublicKernelPhase = PublicKernelPhase.TEARDOWN, + ) { + super(db, publicExecutor, publicKernel, publicProver, globalVariables, historicalHeader, phase); + } + + async handle( + tx: Tx, + previousPublicKernelOutput: PublicKernelCircuitPublicInputs, + previousPublicKernelProof: Proof, + ): Promise<{ + /** + * the output of the public kernel circuit for this phase + */ + publicKernelOutput: PublicKernelCircuitPublicInputs; + /** + * the proof of the public kernel circuit for this phase + */ + publicKernelProof: Proof; + }> { + this.log(`Processing tx ${tx.getTxHash()}`); + this.log(`Executing enqueued public calls for tx ${tx.getTxHash()}`); + const [publicKernelOutput, publicKernelProof, newUnencryptedFunctionLogs] = await this.processEnqueuedPublicCalls( + tx, + previousPublicKernelOutput, + previousPublicKernelProof, + ); + tx.unencryptedLogs.addFunctionLogs(newUnencryptedFunctionLogs); + + // commit the state updates from this transaction + await this.publicStateDB.commit(); + + return { publicKernelOutput, publicKernelProof }; + } + + async rollback(tx: Tx, err: unknown): Promise { + this.log.warn(`Error processing tx ${tx.getTxHash()}: ${err}`); + await this.publicStateDB.rollback(); + return { + tx, + error: err instanceof Error ? err : new Error('Unknown error'), + }; + } +} diff --git a/yarn-project/sequencer-client/src/simulator/index.ts b/yarn-project/sequencer-client/src/simulator/index.ts index 6893bf4c8cb5..7bc2504999ee 100644 --- a/yarn-project/sequencer-client/src/simulator/index.ts +++ b/yarn-project/sequencer-client/src/simulator/index.ts @@ -37,17 +37,21 @@ export interface RollupSimulator { */ export interface PublicKernelCircuitSimulator { /** - * Simulates the public kernel circuit (with a previous private kernel circuit run) from its inputs. + * Simulates the public kernel setup circuit from its inputs. * @param inputs - Inputs to the circuit. * @returns The public inputs as outputs of the simulation. */ - publicKernelCircuitPrivateInput(inputs: PublicKernelCircuitPrivateInputs): Promise; + publicKernelCircuitSetup(inputs: PublicKernelCircuitPrivateInputs): Promise; /** - * Simulates the public kernel circuit (with no previous public kernel circuit run) from its inputs. + * Simulates the public kernel app logic circuit from its inputs. * @param inputs - Inputs to the circuit. * @returns The public inputs as outputs of the simulation. */ - publicKernelCircuitNonFirstIteration( - inputs: PublicKernelCircuitPrivateInputs, - ): Promise; + publicKernelCircuitAppLogic(inputs: PublicKernelCircuitPrivateInputs): Promise; + /** + * Simulates the public kernel teardown circuit from its inputs. + * @param inputs - Inputs to the circuit. + * @returns The public inputs as outputs of the simulation. + */ + publicKernelCircuitTeardown(inputs: PublicKernelCircuitPrivateInputs): Promise; } diff --git a/yarn-project/sequencer-client/src/simulator/public_kernel.ts b/yarn-project/sequencer-client/src/simulator/public_kernel.ts index 4ecf11d203f1..2c67a5d6c051 100644 --- a/yarn-project/sequencer-client/src/simulator/public_kernel.ts +++ b/yarn-project/sequencer-client/src/simulator/public_kernel.ts @@ -2,7 +2,11 @@ import { CircuitSimulationStats } from '@aztec/circuit-types/stats'; import { PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { elapsed } from '@aztec/foundation/timer'; -import { executePublicKernelAppLogic, executePublicKernelSetup } from '@aztec/noir-protocol-circuits-types'; +import { + executePublicKernelAppLogic, + executePublicKernelSetup, + executePublicKernelTeardown, +} from '@aztec/noir-protocol-circuits-types'; import { PublicKernelCircuitSimulator } from './index.js'; @@ -13,20 +17,20 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu private log = createDebugLogger('aztec:public-kernel-simulator'); /** - * Simulates the public kernel circuit (with a previous private kernel circuit run) from its inputs. + * Simulates the public kernel setup circuit from its inputs. * @param input - Inputs to the circuit. * @returns The public inputs as outputs of the simulation. */ - public async publicKernelCircuitPrivateInput( + public async publicKernelCircuitSetup( input: PublicKernelCircuitPrivateInputs, ): Promise { - if (!input.previousKernel.publicInputs.isPrivate) { - throw new Error(`Expected private kernel previous inputs`); + if (!input.previousKernel.publicInputs.needsSetup) { + throw new Error(`Expected previous kernel inputs to need setup`); } const [duration, result] = await elapsed(() => executePublicKernelSetup(input)); - this.log(`Simulated public kernel circuit with private input`, { + this.log(`Simulated public kernel setup circuit`, { eventName: 'circuit-simulation', - circuitName: 'public-kernel-private-input', + circuitName: 'public-kernel-setup', duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, @@ -35,20 +39,42 @@ export class RealPublicKernelCircuitSimulator implements PublicKernelCircuitSimu } /** - * Simulates the public kernel circuit (with no previous public kernel circuit run) from its inputs. + * Simulates the public kernel app logic circuit from its inputs. * @param input - Inputs to the circuit. * @returns The public inputs as outputs of the simulation. */ - public async publicKernelCircuitNonFirstIteration( + public async publicKernelCircuitAppLogic( input: PublicKernelCircuitPrivateInputs, ): Promise { - if (input.previousKernel.publicInputs.isPrivate) { - throw new Error(`Expected public kernel previous inputs`); + if (!input.previousKernel.publicInputs.needsAppLogic) { + throw new Error(`Expected previous kernel inputs to need app logic`); } const [duration, result] = await elapsed(() => executePublicKernelAppLogic(input)); - this.log(`Simulated public kernel circuit non-first iteration`, { + this.log(`Simulated public kernel app logic circuit`, { eventName: 'circuit-simulation', - circuitName: 'public-kernel-non-first-iteration', + circuitName: 'public-kernel-app-logic', + duration, + inputSize: input.toBuffer().length, + outputSize: result.toBuffer().length, + } satisfies CircuitSimulationStats); + return result; + } + + /** + * Simulates the public kernel teardown circuit from its inputs. + * @param input - Inputs to the circuit. + * @returns The public inputs as outputs of the simulation. + */ + public async publicKernelCircuitTeardown( + input: PublicKernelCircuitPrivateInputs, + ): Promise { + if (!input.previousKernel.publicInputs.needsTeardown) { + throw new Error(`Expected previous kernel inputs to need teardown`); + } + const [duration, result] = await elapsed(() => executePublicKernelTeardown(input)); + this.log(`Simulated public kernel teardown circuit`, { + eventName: 'circuit-simulation', + circuitName: 'public-kernel-teardown', duration, inputSize: input.toBuffer().length, outputSize: result.toBuffer().length, From 886cc7585f935f4f12257444af7862b51dc91584 Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 19 Feb 2024 17:20:08 +0000 Subject: [PATCH 03/10] fix: msan build (#4646) Co-authored-by: ludamad --- .../crypto/merkle_tree/indexed_tree/indexed_tree.hpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp index 3afb64e91634..b7112be54476 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/merkle_tree/indexed_tree/indexed_tree.hpp @@ -7,7 +7,7 @@ namespace bb::crypto::merkle_tree { -typedef uint256_t index_t; +using index_t = uint256_t; /** * @brief Used in parallel insertions in the the IndexedTree. Workers signal to other following workes as they move up @@ -18,11 +18,13 @@ class LevelSignal { public: LevelSignal(size_t initial_level) : signal_(initial_level){}; - ~LevelSignal(){}; + ~LevelSignal() = default; LevelSignal(const LevelSignal& other) : signal_(other.signal_.load()) {} - LevelSignal(const LevelSignal&& other) = delete; + LevelSignal(const LevelSignal&& other) noexcept + : signal_(other.signal_.load()) + {} /** * @brief Causes the thread to wait until the required level has been signalled From 13647c24487116f971c81dfaf4ee4664870522d5 Mon Sep 17 00:00:00 2001 From: Innokentii Sennovskii Date: Mon, 19 Feb 2024 18:03:36 +0000 Subject: [PATCH 04/10] feat: Implementing IPA optimisation (#4363) IPA optimisation halving the opening time according to the last section of https://hackmd.io/q-A8y6aITWyWJrvsGGMWNA?view --- .../commitment_schemes/ipa/ipa.hpp | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index b179a6dee7e8..a0c7f7350961 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -13,6 +13,7 @@ * @brief IPA (inner-product argument) commitment scheme class. Conforms to the specification * https://hackmd.io/q-A8y6aITWyWJrvsGGMWNA?view. * + * */ namespace bb { template class IPA { @@ -141,32 +142,30 @@ template class IPA { const Fr round_challenge = transcript->get_challenge("IPA:round_challenge_" + index); const Fr round_challenge_inv = round_challenge.invert(); - auto G_lo = GroupElement::batch_mul_with_endomorphism( - std::span{ G_vec_local.begin(), G_vec_local.begin() + static_cast(round_size) }, - round_challenge_inv); auto G_hi = GroupElement::batch_mul_with_endomorphism( std::span{ G_vec_local.begin() + static_cast(round_size), G_vec_local.begin() + static_cast(round_size * 2) }, - round_challenge); + round_challenge_inv); // Update the vectors a_vec, b_vec and G_vec. - // a_vec_next = a_vec_lo * round_challenge + a_vec_hi * round_challenge_inv - // b_vec_next = b_vec_lo * round_challenge_inv + b_vec_hi * round_challenge - // G_vec_next = G_vec_lo * round_challenge_inv + G_vec_hi * round_challenge + // a_vec_next = a_vec_lo + a_vec_hi * round_challenge + // b_vec_next = b_vec_lo + b_vec_hi * round_challenge_inv + // G_vec_next = G_vec_lo + G_vec_hi * round_challenge_inv run_loop_in_parallel_if_effective( round_size, [&a_vec, &b_vec, round_challenge, round_challenge_inv, round_size](size_t start, size_t end) { for (size_t j = start; j < end; j++) { - a_vec[j] *= round_challenge; - a_vec[j] += round_challenge_inv * a_vec[round_size + j]; - b_vec[j] *= round_challenge_inv; - b_vec[j] += round_challenge * b_vec[round_size + j]; + a_vec[j] += round_challenge * a_vec[round_size + j]; + b_vec[j] += round_challenge_inv * b_vec[round_size + j]; } }, /*finite_field_additions_per_iteration=*/4, /*finite_field_multiplications_per_iteration=*/8, /*finite_field_inversions_per_iteration=*/1); - GroupElement::batch_affine_add(G_lo, G_hi, G_vec_local); + GroupElement::batch_affine_add( + std::span{ G_vec_local.begin(), G_vec_local.begin() + static_cast(round_size) }, + G_hi, + G_vec_local); } transcript->send_to_verifier("IPA:a_0", a_vec[0]); @@ -196,7 +195,7 @@ template class IPA { // Compute C_prime GroupElement C_prime = opening_claim.commitment + (aux_generator * opening_claim.opening_pair.evaluation); - // Compute C_zero = C_prime + ∑_{j ∈ [k]} u_j^2L_j + ∑_{j ∈ [k]} u_j^{-2}R_j + // Compute C_zero = C_prime + ∑_{j ∈ [k]} u_j^{-1}L_j + ∑_{j ∈ [k]} u_jR_j auto pippenger_size = 2 * log_poly_degree; std::vector round_challenges(log_poly_degree); std::vector round_challenges_inv(log_poly_degree); @@ -211,8 +210,8 @@ template class IPA { msm_elements[2 * i] = element_L; msm_elements[2 * i + 1] = element_R; - msm_scalars[2 * i] = round_challenges[i].sqr(); - msm_scalars[2 * i + 1] = round_challenges_inv[i].sqr(); + msm_scalars[2 * i] = round_challenges_inv[i]; + msm_scalars[2 * i + 1] = round_challenges[i]; } GroupElement LR_sums = bb::scalar_multiplication::pippenger_without_endomorphism_basis_points( @@ -222,15 +221,15 @@ template class IPA { /** * Compute b_zero where b_zero can be computed using the polynomial: * - * g(X) = ∏_{i ∈ [k]} (u_{k-i}^{-1} + u_{k-i}.X^{2^{i-1}}). + * g(X) = ∏_{i ∈ [k]} (1 + u_{k-i}^{-1}.X^{2^{i-1}}). * - * b_zero = g(evaluation) = ∏_{i ∈ [k]} (u_{k-i}^{-1} + u_{k-i}. (evaluation)^{2^{i-1}}) + * b_zero = g(evaluation) = ∏_{i ∈ [k]} (1 + u_{k-i}^{-1}. (evaluation)^{2^{i-1}}) */ Fr b_zero = Fr::one(); for (size_t i = 0; i < log_poly_degree; i++) { auto exponent = static_cast(Fr(2).pow(i)); - b_zero *= round_challenges_inv[log_poly_degree - 1 - i] + - (round_challenges[log_poly_degree - 1 - i] * opening_claim.opening_pair.challenge.pow(exponent)); + b_zero *= Fr::one() + (round_challenges_inv[log_poly_degree - 1 - i] * + opening_claim.opening_pair.challenge.pow(exponent)); } // Compute G_zero @@ -238,15 +237,13 @@ template class IPA { std::vector s_vec(poly_degree); run_loop_in_parallel_if_effective( poly_degree, - [&s_vec, &round_challenges, &round_challenges_inv, log_poly_degree](size_t start, size_t end) { + [&s_vec, &round_challenges_inv, log_poly_degree](size_t start, size_t end) { for (size_t i = start; i < end; i++) { Fr s_vec_scalar = Fr::one(); for (size_t j = (log_poly_degree - 1); j != size_t(-1); j--) { auto bit = (i >> j) & 1; bool b = static_cast(bit); if (b) { - s_vec_scalar *= round_challenges[log_poly_degree - 1 - j]; - } else { s_vec_scalar *= round_challenges_inv[log_poly_degree - 1 - j]; } } From 2dd53fd65a3eeb7e1a5c939664c9b3c3b838474c Mon Sep 17 00:00:00 2001 From: just-mitch <68168980+just-mitch@users.noreply.github.com> Date: Mon, 19 Feb 2024 18:33:55 +0000 Subject: [PATCH 05/10] turn off fees test (#4670) --- yarn-project/end-to-end/src/e2e_fees.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/end-to-end/src/e2e_fees.test.ts b/yarn-project/end-to-end/src/e2e_fees.test.ts index f4caf1252225..3f1d3f31c596 100644 --- a/yarn-project/end-to-end/src/e2e_fees.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees.test.ts @@ -43,7 +43,7 @@ describe('e2e_fees', () => { }); describe('NativeFeePaymentMethod', () => { - it('pays out the expected fee to the sequencer', async () => { + it.skip('pays out the expected fee to the sequencer', async () => { await testContract.methods .mint_public(aliceAddress, 1000) .send({ From ba6048d89effccac95a5eb4331e64b912fa212cc Mon Sep 17 00:00:00 2001 From: ludamad Date: Mon, 19 Feb 2024 22:18:11 +0000 Subject: [PATCH 06/10] Revert "refactor(bb): allow dynamic plookup tables" (#4672) Reverts AztecProtocol/aztec-packages#4667 Turned out to be more involved than thought + not planned imminently --- .../circuit_builder/ultra_circuit_builder.cpp | 4 +- .../circuit_builder/ultra_circuit_builder.hpp | 2 +- .../plookup_tables/plookup_tables.cpp | 12 +-- .../plookup_tables/plookup_tables.hpp | 3 +- .../proof_system/plookup_tables/types.hpp | 88 ++++++++++++++----- .../stdlib/primitives/plookup/plookup.cpp | 11 ++- .../stdlib/primitives/plookup/plookup.hpp | 9 +- .../primitives/plookup/plookup.test.cpp | 16 +--- 8 files changed, 83 insertions(+), 62 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index e65527a48675..21aa754edfed 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -633,12 +633,12 @@ plookup::BasicTable& UltraCircuitBuilder_::get_table(const ploo template plookup::ReadData UltraCircuitBuilder_::create_gates_from_plookup_accumulators( - const plookup::MultiTableIdOrPtr& id, + const plookup::MultiTableId& id, const plookup::ReadData& read_values, const uint32_t key_a_index, std::optional key_b_index) { - const auto& multi_table = plookup::get_table(id); + const auto& multi_table = plookup::create_table(id); const size_t num_lookups = read_values[plookup::ColumnIdx::C1].size(); plookup::ReadData read_data; for (size_t i = 0; i < num_lookups; ++i) { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 1abd54ef5de0..78242840d9cc 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -1009,7 +1009,7 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase create_gates_from_plookup_accumulators( - const plookup::MultiTableIdOrPtr& id, + const plookup::MultiTableId& id, const plookup::ReadData& read_values, const uint32_t key_a_index, std::optional key_b_index = std::nullopt); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.cpp b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.cpp index ee05af86e282..6a2257bf1029 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.cpp @@ -108,21 +108,13 @@ const MultiTable& create_table(const MultiTableId id) return MULTI_TABLES[id]; } -const MultiTable& get_table(const MultiTableIdOrPtr& id) -{ - if (id.ptr == nullptr) { - return create_table(id.id); - } - return *id.ptr; -} - -ReadData get_lookup_accumulators(const MultiTableIdOrPtr& id, +ReadData get_lookup_accumulators(const MultiTableId id, const fr& key_a, const fr& key_b, const bool is_2_to_1_lookup) { // return multi-table, populating global array of all multi-tables if need be - const auto& multi_table = get_table(id); + const auto& multi_table = create_table(id); const size_t num_lookups = multi_table.lookup_ids.size(); ReadData lookup; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.hpp b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.hpp index be85303fa8df..492793150d3b 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/plookup_tables.hpp @@ -19,9 +19,8 @@ namespace bb::plookup { const MultiTable& create_table(MultiTableId id); -const MultiTable& get_table(const MultiTableIdOrPtr& id); -ReadData get_lookup_accumulators(const MultiTableIdOrPtr& id, +ReadData get_lookup_accumulators(MultiTableId id, const bb::fr& key_a, const bb::fr& key_b = 0, bool is_2_to_1_lookup = false); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/types.hpp b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/types.hpp index f4dd1083a6e0..489d9e600716 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/types.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/types.hpp @@ -132,17 +132,17 @@ struct MultiTable { std::vector column_1_step_sizes; std::vector column_2_step_sizes; std::vector column_3_step_sizes; - using table_out = std::array; - using table_in = std::array; + typedef std::array table_out; + typedef std::array table_in; std::vector get_table_values; private: void init_step_sizes() { const size_t num_lookups = column_1_coefficients.size(); - column_1_step_sizes.emplace_back(1); - column_2_step_sizes.emplace_back(1); - column_3_step_sizes.emplace_back(1); + column_1_step_sizes.emplace_back(bb::fr(1)); + column_2_step_sizes.emplace_back(bb::fr(1)); + column_3_step_sizes.emplace_back(bb::fr(1)); std::vector coefficient_inverses(column_1_coefficients.begin(), column_1_coefficients.end()); std::copy(column_2_coefficients.begin(), column_2_coefficients.end(), std::back_inserter(coefficient_inverses)); @@ -184,7 +184,7 @@ struct MultiTable { init_step_sizes(); } - MultiTable() = default; + MultiTable(){}; MultiTable(const MultiTable& other) = default; MultiTable(MultiTable&& other) = default; @@ -192,22 +192,66 @@ struct MultiTable { MultiTable& operator=(MultiTable&& other) = default; }; -// Represents either a predefined table from our enum list of supported lookup tables, or a dynamic lookup table defined -// by ACIR -struct MultiTableIdOrPtr { - // Used if we are using a lookup table from our predefined list, otherwise set to NUM_MULTI_TABLES and unused. - MultiTableId id; - // Used if we are using a lookup table from a lookup table defined by e.g. ACIR, otherwise set to nullptr. - MultiTable* ptr; - MultiTableIdOrPtr(MultiTable* ptr) - : id(NUM_MULTI_TABLES) - , ptr(ptr) - {} - MultiTableIdOrPtr(MultiTableId id) - : id(id) - , ptr(nullptr) - {} -}; +// struct PlookupLargeKeyTable { +// struct KeyEntry { +// uint256_t key; +// std::array value{ bb::fr(0), bb::fr(0) }; +// bool operator<(const KeyEntry& other) const { return key < other.key; } + +// std::array to_sorted_list_components(const bool use_two_keys) const +// { +// return { +// key[0], +// value[0], +// value[1], +// }; +// } +// }; + +// BasicTableId id; +// size_t table_index; +// size_t size; +// bool use_twin_keys; + +// bb::fr column_1_step_size = bb::fr(0); +// bb::fr column_2_step_size = bb::fr(0); +// bb::fr column_3_step_size = bb::fr(0); +// std::vector column_1; +// std::vector column_3; +// std::vector column_2; +// std::vector lookup_gates; + +// std::array (*get_values_from_key)(const std::array); +// }; + +// struct PlookupFatKeyTable { +// struct KeyEntry { +// bb::fr key; +// std::array values{ 0, 0 }; +// bool operator<(const KeyEntry& other) const +// { +// return (key.from_montgomery_form() < other.key.from_montgomery_form()); +// } + +// std::array to_sorted_list_components() const { return { key, values[0], values[0] }; } +// } + +// BasicTableId id; +// size_t table_index; +// size_t size; +// bool use_twin_keys; + +// bb::fr column_1_step_size = bb::fr(0); +// bb::fr column_2_step_size = bb::fr(0); +// bb::fr column_3_step_size = bb::fr(0); +// std::vector column_1; +// std::vector column_3; +// std::vector column_2; +// std::vector lookup_gates; + +// std::array (*get_values_from_key)(const std::array); + +// } /** * @brief The structure contains the most basic table serving one function (for, example an xor table) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp index becddf86d14d..103784ba2de8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.cpp @@ -14,7 +14,7 @@ using plookup::MultiTableId; using namespace bb; template -plookup::ReadData> plookup_read::get_lookup_accumulators(const plookup::MultiTableIdOrPtr& id, +plookup::ReadData> plookup_read::get_lookup_accumulators(const MultiTableId id, const field_t& key_a_in, const field_t& key_b_in, const bool is_2_to_1_lookup) @@ -64,8 +64,8 @@ plookup::ReadData> plookup_read::get_lookup_accumulato } template -std::pair, field_t> plookup_read::read_pair_from_table( - const plookup::MultiTableIdOrPtr& id, const field_t& key) +std::pair, field_t> plookup_read::read_pair_from_table(const MultiTableId id, + const field_t& key) { const auto lookup = get_lookup_accumulators(id, key); @@ -73,7 +73,7 @@ std::pair, field_t> plookup_read::read_pair_f } template -field_t plookup_read::read_from_2_to_1_table(const plookup::MultiTableIdOrPtr& id, +field_t plookup_read::read_from_2_to_1_table(const MultiTableId id, const field_t& key_a, const field_t& key_b) { @@ -83,8 +83,7 @@ field_t plookup_read::read_from_2_to_1_table(const plookup::Mu } template -field_t plookup_read::read_from_1_to_2_table(const plookup::MultiTableIdOrPtr& id, - const field_t& key_a) +field_t plookup_read::read_from_1_to_2_table(const MultiTableId id, const field_t& key_a) { const auto lookup = get_lookup_accumulators(id, key_a); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.hpp index 361930721325..eb85f1642423 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.hpp @@ -12,15 +12,14 @@ template class plookup_read { typedef field_t field_pt; public: - static std::pair read_pair_from_table(const plookup::MultiTableIdOrPtr& id, - const field_pt& key); + static std::pair read_pair_from_table(const plookup::MultiTableId id, const field_pt& key); - static field_pt read_from_2_to_1_table(const plookup::MultiTableIdOrPtr& id, + static field_pt read_from_2_to_1_table(const plookup::MultiTableId id, const field_pt& key_a, const field_pt& key_b); - static field_pt read_from_1_to_2_table(const plookup::MultiTableIdOrPtr& id, const field_pt& key_a); + static field_pt read_from_1_to_2_table(const plookup::MultiTableId id, const field_pt& key_a); - static plookup::ReadData get_lookup_accumulators(const plookup::MultiTableIdOrPtr& id, + static plookup::ReadData get_lookup_accumulators(const plookup::MultiTableId id, const field_pt& key_a, const field_pt& key_b = 0, const bool is_2_to_1_lookup = false); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.test.cpp index e147fdbae897..00d2b6846eed 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/plookup/plookup.test.cpp @@ -468,7 +468,7 @@ TEST(stdlib_plookup, blake2s_xor) EXPECT_EQ(result, true); } -static void test_uint32_and(const MultiTableIdOrPtr& id) +TEST(stdlib_plookup, uint32_and) { Builder builder = Builder(); @@ -480,7 +480,7 @@ static void test_uint32_and(const MultiTableIdOrPtr& id) field_ct left = witness_ct(&builder, bb::fr(left_value)); field_ct right = witness_ct(&builder, bb::fr(right_value)); - const auto lookup = plookup_read::get_lookup_accumulators(id, left, right, true); + const auto lookup = plookup_read::get_lookup_accumulators(MultiTableId::UINT32_AND, left, right, true); const auto left_slices = numeric::slice_input(left_value, 1 << 6, num_lookups); const auto right_slices = numeric::slice_input(right_value, 1 << 6, num_lookups); std::vector out_expected(num_lookups); @@ -510,18 +510,6 @@ static void test_uint32_and(const MultiTableIdOrPtr& id) EXPECT_EQ(result, true); } -// Tests the dynamic multitable interface used by ACIR (the Noir interface to bb) -TEST(stdlib_plookup, dynamic_uint32_and) -{ - MultiTable and_table = bb::plookup::uint_tables::get_uint32_and_table(); - test_uint32_and(&and_table); -} - -TEST(stdlib_plookup, uint32_and) -{ - test_uint32_and(MultiTableId::UINT32_AND); -} - TEST(stdlib_plookup, secp256k1_generator) { using curve = stdlib::secp256k1; From 9f67eec73c5d639df16e6b3bf45c4a1fc1c54bad Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Tue, 20 Feb 2024 01:39:38 +0000 Subject: [PATCH 07/10] feat(avm): hashing to simulator (#4527) --- avm-transpiler/src/opcodes.rs | 6 +- avm-transpiler/src/transpile.rs | 203 ++++++++++++++++-- noir-projects/aztec-nr/aztec/src/avm.nr | 1 + noir-projects/aztec-nr/aztec/src/avm/hash.nr | 8 + .../contracts/avm_test_contract/src/main.nr | 40 +++- .../simulator/src/avm/avm_simulator.test.ts | 61 ++++++ .../simulator/src/avm/opcodes/hashing.test.ts | 138 ++++++++++-- .../simulator/src/avm/opcodes/hashing.ts | 72 +++++-- .../simulator/src/avm/opcodes/memory.ts | 1 + 9 files changed, 475 insertions(+), 55 deletions(-) create mode 100644 noir-projects/aztec-nr/aztec/src/avm/hash.nr diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index ef91f2b368da..84414239aa9c 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -150,10 +150,10 @@ impl AvmOpcode { // World State AvmOpcode::SLOAD => "SLOAD", // Public Storage AvmOpcode::SSTORE => "SSTORE", // Public Storage - AvmOpcode::NOTEHASHEXISTS => "NOTEHASHEXISTS", // Notes & Nullifiers - AvmOpcode::EMITNOTEHASH => "EMITNOTEHASH", // Notes & Nullifiers + AvmOpcode::NOTEHASHEXISTS => "NOTEHASHEXISTS", // Notes & Nullifiers + AvmOpcode::EMITNOTEHASH => "EMITNOTEHASH", // Notes & Nullifiers AvmOpcode::NULLIFIEREXISTS => "NULLIFIEREXISTS", // Notes & Nullifiers - AvmOpcode::EMITNULLIFIER => "EMITNULLIFIER", // Notes & Nullifiers + AvmOpcode::EMITNULLIFIER => "EMITNULLIFIER", // Notes & Nullifiers AvmOpcode::READL1TOL2MSG => "READL1TOL2MSG", // Messages AvmOpcode::HEADERMEMBER => "HEADERMEMBER", // Archive tree & Headers diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index ad079b4b098c..5dfac47fe6ac 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1,7 +1,9 @@ use acvm::acir::brillig::Opcode as BrilligOpcode; use acvm::acir::circuit::brillig::Brillig; -use acvm::brillig_vm::brillig::{BinaryFieldOp, BinaryIntOp, MemoryAddress, Value, ValueOrArray}; +use acvm::brillig_vm::brillig::{ + BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapArray, MemoryAddress, Value, ValueOrArray, +}; use crate::instructions::{ AvmInstruction, AvmOperand, AvmTypeTag, ALL_DIRECT, FIRST_OPERAND_INDIRECT, @@ -93,7 +95,6 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { value: destination.to_usize() as u32, }, ], - ..Default::default() }); } BrilligOpcode::CalldataCopy { destination_address, size, offset } => { @@ -200,9 +201,13 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { ..Default::default() }); }, + BrilligOpcode::Cast { destination, source, bit_size } => { + avm_instrs.push(emit_cast(source.to_usize() as u32, destination.to_usize() as u32, tag_from_bit_size(*bit_size))); + } BrilligOpcode::ForeignCall { function, destinations, inputs, destination_value_types:_, input_value_types:_ } => { handle_foreign_call(&mut avm_instrs, function, destinations, inputs); }, + BrilligOpcode::BlackBox(operation) => handle_black_box_function(&mut avm_instrs, operation), _ => panic!( "Transpiler doesn't know how to process {:?} brillig instruction", brillig_instr @@ -228,9 +233,148 @@ fn handle_foreign_call( function: &String, destinations: &Vec, inputs: &Vec, +) { + match function.as_str() { + "keccak256" | "sha256" => { + emit_2_field_hash_instruction(avm_instrs, function, destinations, inputs) + } + "poseidon" => { + emit_single_field_hash_instruction(avm_instrs, function, destinations, inputs) + } + _ => handle_getter_instruction(avm_instrs, function, destinations, inputs), + } +} + +/// Two field hash instructions represent instruction's that's outputs are larger than a field element +/// +/// This includes: +/// - keccak +/// - sha256 +/// +/// In the future the output of these may expand / contract depending on what is most efficient for the circuit +/// to reason about. In order to decrease user friction we will use two field outputs. +fn emit_2_field_hash_instruction( + avm_instrs: &mut Vec, + function: &String, + destinations: &[ValueOrArray], + inputs: &[ValueOrArray], +) { + // handle field returns differently + let hash_offset_maybe = inputs[0]; + println!("hash_offset_maybe: {:?}", hash_offset_maybe); + let (hash_offset, hash_size) = match hash_offset_maybe { + ValueOrArray::HeapArray(HeapArray { pointer, size }) => (pointer.0, size), + _ => panic!("Keccak | Sha256 address inputs destination should be a single value"), + }; + + assert!(destinations.len() == 1); + let dest_offset_maybe = destinations[0]; + let dest_offset = match dest_offset_maybe { + ValueOrArray::HeapArray(HeapArray { pointer, size }) => { + assert!(size == 2); + pointer.0 + } + _ => panic!("Keccak | Poseidon address destination should be a single value"), + }; + + let opcode = match function.as_str() { + "keccak256" => AvmOpcode::KECCAK, + "sha256" => AvmOpcode::SHA256, + _ => panic!( + "Transpiler doesn't know how to process ForeignCall function {:?}", + function + ), + }; + + avm_instrs.push(AvmInstruction { + opcode, + indirect: Some(3), // 11 - addressing mode, indirect for input and output + operands: vec![ + AvmOperand::U32 { + value: dest_offset as u32, + }, + AvmOperand::U32 { + value: hash_offset as u32, + }, + AvmOperand::U32 { + value: hash_size as u32, + }, + ], + ..Default::default() + }); +} + +/// A single field hash instruction includes hash functions that emit a single field element +/// directly onto the stack. +/// +/// This includes (snark friendly functions): +/// - poseidon2 +/// +/// Pedersen is not implemented this way as the black box function representation has the correct api. +/// As the Poseidon BBF only deals with a single permutation, it is not quite suitable for our current avm +/// representation. +fn emit_single_field_hash_instruction( + avm_instrs: &mut Vec, + function: &String, + destinations: &[ValueOrArray], + inputs: &[ValueOrArray], +) { + // handle field returns differently + let hash_offset_maybe = inputs[0]; + let (hash_offset, hash_size) = match hash_offset_maybe { + ValueOrArray::HeapArray(HeapArray { pointer, size }) => (pointer.0, size), + _ => panic!("Poseidon address inputs destination should be a single value"), + }; + + assert!(destinations.len() == 1); + let dest_offset_maybe = destinations[0]; + let dest_offset = match dest_offset_maybe { + ValueOrArray::MemoryAddress(dest_offset) => dest_offset.0, + _ => panic!("Poseidon address destination should be a single value"), + }; + + let opcode = match function.as_str() { + "poseidon" => AvmOpcode::POSEIDON, + _ => panic!( + "Transpiler doesn't know how to process ForeignCall function {:?}", + function + ), + }; + + avm_instrs.push(AvmInstruction { + opcode, + indirect: Some(1), + operands: vec![ + AvmOperand::U32 { + value: dest_offset as u32, + }, + AvmOperand::U32 { + value: hash_offset as u32, + }, + AvmOperand::U32 { + value: hash_size as u32, + }, + ], + ..Default::default() + }); +} + +/// Getter Instructions are instructions that take NO inputs, and return information +/// from the current execution context. +/// +/// This includes: +/// - Global variables +/// - Caller +/// - storage address +/// - ... +fn handle_getter_instruction( + avm_instrs: &mut Vec, + function: &String, + destinations: &Vec, + inputs: &Vec, ) { // For the foreign calls we want to handle, we do not want inputs, as they are getters - assert!(inputs.len() == 0); + assert!(inputs.is_empty()); assert!(destinations.len() == 1); let dest_offset_maybe = destinations[0]; let dest_offset = match dest_offset_maybe { @@ -257,7 +401,6 @@ fn handle_foreign_call( function ), }; - avm_instrs.push(AvmInstruction { opcode, indirect: Some(ALL_DIRECT), @@ -265,7 +408,7 @@ fn handle_foreign_call( value: dest_offset as u32, }], ..Default::default() - }); + }) } /// Handles Brillig's CONST opcode. @@ -316,7 +459,7 @@ fn emit_set(tag: AvmTypeTag, dest: u32, value: u128) -> AvmInstruction { AvmTypeTag::UINT64 => AvmOperand::U64 { value: value as u64, }, - AvmTypeTag::UINT128 => AvmOperand::U128 { value: value }, + AvmTypeTag::UINT128 => AvmOperand::U128 { value }, _ => panic!("Invalid type tag {:?} for set", tag), }, // dest offset @@ -342,7 +485,7 @@ fn emit_cast(source: u32, destination: u32, dst_tag: AvmTypeTag) -> AvmInstructi fn emit_mov(indirect: Option, source: u32, dest: u32) -> AvmInstruction { AvmInstruction { opcode: AvmOpcode::MOV, - indirect: indirect, + indirect, operands: vec![ AvmOperand::U32 { value: source }, AvmOperand::U32 { value: dest }, @@ -351,6 +494,44 @@ fn emit_mov(indirect: Option, source: u32, dest: u32) -> AvmInstruction { } } +/// Black box functions, for the meantime only covers pedersen operations as the blackbox function api suits our current needs. +/// (array goes in -> field element comes out) +fn handle_black_box_function(avm_instrs: &mut Vec, operation: &BlackBoxOp) { + match operation { + BlackBoxOp::PedersenHash { + inputs, + domain_separator: _, + output, + } => { + let hash_offset = inputs.pointer.0; + let hash_size = inputs.size.0; + + let dest_offset = output.0; + + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::PEDERSEN, + indirect: Some(1), + operands: vec![ + AvmOperand::U32 { + value: dest_offset as u32, + }, + AvmOperand::U32 { + value: hash_offset as u32, + }, + AvmOperand::U32 { + value: hash_size as u32, + }, + ], + ..Default::default() + }); + } + _ => panic!( + "Transpiler doesn't know how to process BlackBoxOp {:?}", + operation + ), + } +} + /// Compute an array that maps each Brillig pc to an AVM pc. /// This must be done before transpiling to properly transpile jump destinations. /// This is necessary for two reasons: @@ -367,12 +548,7 @@ fn map_brillig_pcs_to_avm_pcs(initial_offset: usize, brillig: &Brillig) -> Vec 2, - BrilligOpcode::Store { .. } => 2, - BrilligOpcode::Const { bit_size, .. } => match bit_size { - 254 => 2, // Field. - _ => 1, - }, + BrilligOpcode::Const { bit_size: 254, .. } => 2, _ => 1, }; // next Brillig pc will map to an AVM pc offset by the @@ -384,6 +560,7 @@ fn map_brillig_pcs_to_avm_pcs(initial_offset: usize, brillig: &Brillig) -> Vec AvmTypeTag { match bit_size { + 1 => AvmTypeTag::UINT8, // temp workaround 8 => AvmTypeTag::UINT8, 16 => AvmTypeTag::UINT16, 32 => AvmTypeTag::UINT32, diff --git a/noir-projects/aztec-nr/aztec/src/avm.nr b/noir-projects/aztec-nr/aztec/src/avm.nr index 3d9885db80d8..cfd9aa3e6f4b 100644 --- a/noir-projects/aztec-nr/aztec/src/avm.nr +++ b/noir-projects/aztec-nr/aztec/src/avm.nr @@ -1 +1,2 @@ mod context; +mod hash; diff --git a/noir-projects/aztec-nr/aztec/src/avm/hash.nr b/noir-projects/aztec-nr/aztec/src/avm/hash.nr new file mode 100644 index 000000000000..2c2ac6f2448b --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/avm/hash.nr @@ -0,0 +1,8 @@ +#[oracle(keccak256)] +pub fn keccak256(input: [Field; N]) -> [Field; 2] {} + +#[oracle(poseidon)] +pub fn poseidon(input: [Field; N]) -> Field {} + +#[oracle(sha256)] +pub fn sha256(input: [Field; N]) -> [Field; 2] {} diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 64fe1644489f..67e3086814cf 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -1,11 +1,16 @@ -// - contract AvmTest { // Libs use dep::aztec::protocol_types::address::{AztecAddress, EthAddress}; // avm lib - use dep::aztec::avm::context::AvmContext; + use dep::aztec::avm::{ + context::AvmContext, + hash::{ + keccak256, + poseidon, + sha256 + } + }; #[aztec(private)] fn constructor() {} @@ -51,9 +56,32 @@ contract AvmTest { 200 as Field } - /************************************************************************ - * AvmContext functions - ************************************************************************/ + // /************************************************************************ + // * Hashing functions + // ************************************************************************/ + #[aztec(public-vm)] + fn keccak_hash(data: [Field; 3]) -> pub [Field; 2] { + keccak256(data) + } + + #[aztec(public-vm)] + fn poseidon_hash(data: [Field; 3]) -> pub Field { + poseidon(data) + } + + #[aztec(public-vm)] + fn sha256_hash(data: [Field; 3]) -> pub [Field; 2] { + sha256(data) + } + + #[aztec(public-vm)] + fn pedersen_hash(data: [Field; 3]) -> pub Field { + dep::std::hash::pedersen_hash(data) + } + + // /************************************************************************ + // * AvmContext functions + // ************************************************************************/ #[aztec(public-vm)] fn getAddress() -> pub AztecAddress { context.address() diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 5133f1c5a4d2..8a56550155ae 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -1,4 +1,5 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/crypto'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; import { AvmTestContractArtifact } from '@aztec/noir-contracts.js'; @@ -82,6 +83,66 @@ describe('AVM simulator', () => { }); }); + describe.each([ + ['avm_sha256_hash', sha256], + ['avm_keccak_hash', keccak], + ])('Hashes with 2 fields returned in noir contracts', (name: string, hashFunction: (data: Buffer) => Buffer) => { + it(`Should execute contract function that performs ${name} hash`, async () => { + const calldata = [new Fr(1), new Fr(2), new Fr(3)]; + const hash = hashFunction(Buffer.concat(calldata.map(f => f.toBuffer()))); + + // Get contract function artifact + const artifact = AvmTestContractArtifact.functions.find(f => f.name === name)!; + + // Decode bytecode into instructions + const bytecode = Buffer.from(artifact.bytecode, 'base64'); + + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.worldState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValue(Promise.resolve(bytecode)); + + const results = await new AvmSimulator(context).execute(); + + expect(results.reverted).toBe(false); + + const returnData = results.output; + const reconstructedHash = Buffer.concat([ + returnData[0].toBuffer().subarray(16, 32), + returnData[1].toBuffer().subarray(16, 32), + ]); + expect(reconstructedHash).toEqual(hash); + }); + }); + + describe.each([ + ['avm_poseidon_hash', poseidonHash], + ['avm_pedersen_hash', pedersenHash], + ])('Hashes with field returned in noir contracts', (name: string, hashFunction: (data: Buffer[]) => Buffer) => { + it(`Should execute contract function that performs ${name} hash`, async () => { + const calldata = [new Fr(1), new Fr(2), new Fr(3)]; + const hash = hashFunction(calldata.map(f => f.toBuffer())); + + // Get contract function artifact + const artifact = AvmTestContractArtifact.functions.find(f => f.name === name)!; + + // Decode bytecode into instructions + const bytecode = Buffer.from(artifact.bytecode, 'base64'); + + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.worldState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValue(Promise.resolve(bytecode)); + + const results = await new AvmSimulator(context).execute(); + + expect(results.reverted).toBe(false); + + const returnData = results.output; + expect(returnData).toEqual([new Fr(hash)]); + }); + }); + describe('Test env getters from noir contract', () => { const testEnvGetter = async (valueName: string, value: any, functionName: string, globalVar: boolean = false) => { const getterArtifact = AvmTestContractArtifact.functions.find(f => f.name === functionName)!; diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts index 48e7206385a0..0c7b363df048 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts @@ -2,7 +2,7 @@ import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/crypto'; import { AvmContext } from '../avm_context.js'; -import { Field } from '../avm_memory_types.js'; +import { Field, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; import { Keccak, Pedersen, Poseidon2, Sha256 } from './hashing.js'; @@ -17,17 +17,24 @@ describe('Hashing Opcodes', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ Poseidon2.opcode, // opcode + 1, // indirect ...Buffer.from('12345678', 'hex'), // dstOffset ...Buffer.from('23456789', 'hex'), // hashOffset ...Buffer.from('3456789a', 'hex'), // hashSize ]); - const inst = new Poseidon2(/*dstOffset=*/ 0x12345678, /*hashOffset=*/ 0x23456789, /*hashSize=*/ 0x3456789a); + const inst = new Poseidon2( + /*indirect=*/ 1, + /*dstOffset=*/ 0x12345678, + /*hashOffset=*/ 0x23456789, + /*hashSize=*/ 0x3456789a, + ); expect(Poseidon2.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); - it('Should hash correctly', async () => { + it('Should hash correctly - direct', async () => { + const indirect = 0; const args = [new Field(1n), new Field(2n), new Field(3n)]; const hashOffset = 0; context.machineState.memory.setSlice(hashOffset, args); @@ -35,7 +42,25 @@ describe('Hashing Opcodes', () => { const dstOffset = 3; const expectedHash = poseidonHash(args.map(field => field.toBuffer())); - await new Poseidon2(dstOffset, hashOffset, args.length).execute(context); + await new Poseidon2(indirect, dstOffset, hashOffset, args.length).execute(context); + + const result = context.machineState.memory.get(dstOffset); + expect(result).toEqual(new Field(toBigIntBE(expectedHash))); + }); + + it('Should hash correctly - indirect', async () => { + const args = [new Field(1n), new Field(2n), new Field(3n)]; + const indirect = 1; + const hashOffset = 0; + const realLocation = 4; + + context.machineState.memory.set(hashOffset, new Uint32(realLocation)); + context.machineState.memory.setSlice(realLocation, args); + + const dstOffset = 3; + + const expectedHash = poseidonHash(args.map(field => field.toBuffer())); + await new Poseidon2(indirect, dstOffset, hashOffset, args.length).execute(context); const result = context.machineState.memory.get(dstOffset); expect(result).toEqual(new Field(toBigIntBE(expectedHash))); @@ -46,18 +71,25 @@ describe('Hashing Opcodes', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ Keccak.opcode, // opcode + 1, // indirect ...Buffer.from('12345678', 'hex'), // dstOffset ...Buffer.from('23456789', 'hex'), // hashOffset ...Buffer.from('3456789a', 'hex'), // hashSize ]); - const inst = new Keccak(/*dstOffset=*/ 0x12345678, /*hashOffset=*/ 0x23456789, /*hashSize=*/ 0x3456789a); + const inst = new Keccak( + /*indirect=*/ 1, + /*dstOffset=*/ 0x12345678, + /*hashOffset=*/ 0x23456789, + /*hashSize=*/ 0x3456789a, + ); expect(Keccak.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); - it('Should hash correctly', async () => { + it('Should hash correctly - direct', async () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; + const indirect = 0; const hashOffset = 0; context.machineState.memory.setSlice(hashOffset, args); @@ -65,71 +97,151 @@ describe('Hashing Opcodes', () => { const inputBuffer = Buffer.concat(args.map(field => field.toBuffer())); const expectedHash = keccak(inputBuffer); - await new Keccak(dstOffset, hashOffset, args.length).execute(context); + await new Keccak(indirect, dstOffset, hashOffset, args.length).execute(context); const result = context.machineState.memory.getSliceAs(dstOffset, 2); const combined = Buffer.concat([result[0].toBuffer().subarray(16, 32), result[1].toBuffer().subarray(16, 32)]); expect(combined).toEqual(expectedHash); }); + + it('Should hash correctly - indirect', async () => { + const args = [new Field(1n), new Field(2n), new Field(3n)]; + const indirect = 3; // dest and return are indirect + const hashOffset = 0; + const argsLocation = 4; + + const dstOffset = 2; + const readLocation = 6; + + context.machineState.memory.set(hashOffset, new Uint32(argsLocation)); + context.machineState.memory.set(dstOffset, new Uint32(readLocation)); + context.machineState.memory.setSlice(argsLocation, args); + + const inputBuffer = Buffer.concat(args.map(field => field.toBuffer())); + const expectedHash = keccak(inputBuffer); + await new Keccak(indirect, dstOffset, hashOffset, args.length).execute(context); + + const result = context.machineState.memory.getSliceAs(readLocation, 2); + const combined = Buffer.concat([result[0].toBuffer().subarray(16, 32), result[1].toBuffer().subarray(16, 32)]); + + expect(combined).toEqual(expectedHash); + }); + // TODO: indirect }); describe('Sha256', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ Sha256.opcode, // opcode + 1, // indirect ...Buffer.from('12345678', 'hex'), // dstOffset ...Buffer.from('23456789', 'hex'), // hashOffset ...Buffer.from('3456789a', 'hex'), // hashSize ]); - const inst = new Sha256(/*dstOffset=*/ 0x12345678, /*hashOffset=*/ 0x23456789, /*hashSize=*/ 0x3456789a); + const inst = new Sha256( + /*indirect=*/ 1, + /*dstOffset=*/ 0x12345678, + /*hashOffset=*/ 0x23456789, + /*hashSize=*/ 0x3456789a, + ); expect(Sha256.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); - it('Should hash correctly', async () => { + it('Should hash correctly - direct', async () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; const hashOffset = 0; + const indirect = 0; context.machineState.memory.setSlice(hashOffset, args); const dstOffset = 3; const inputBuffer = Buffer.concat(args.map(field => field.toBuffer())); const expectedHash = sha256(inputBuffer); - await new Sha256(dstOffset, hashOffset, args.length).execute(context); + await new Sha256(indirect, dstOffset, hashOffset, args.length).execute(context); const result = context.machineState.memory.getSliceAs(dstOffset, 2); const combined = Buffer.concat([result[0].toBuffer().subarray(16, 32), result[1].toBuffer().subarray(16, 32)]); expect(combined).toEqual(expectedHash); }); + + it('Should hash correctly - indirect', async () => { + const args = [new Field(1n), new Field(2n), new Field(3n)]; + const indirect = 3; // dest and return are indirect + const hashOffset = 0; + const argsLocation = 4; + + const dstOffset = 2; + const readLocation = 6; + + context.machineState.memory.set(hashOffset, new Uint32(argsLocation)); + context.machineState.memory.set(dstOffset, new Uint32(readLocation)); + context.machineState.memory.setSlice(argsLocation, args); + + const inputBuffer = Buffer.concat(args.map(field => field.toBuffer())); + const expectedHash = sha256(inputBuffer); + await new Sha256(indirect, dstOffset, hashOffset, args.length).execute(context); + + const result = context.machineState.memory.getSliceAs(readLocation, 2); + const combined = Buffer.concat([result[0].toBuffer().subarray(16, 32), result[1].toBuffer().subarray(16, 32)]); + + expect(combined).toEqual(expectedHash); + }); }); describe('Pedersen', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ Pedersen.opcode, // opcode + 1, // indirect ...Buffer.from('12345678', 'hex'), // dstOffset ...Buffer.from('23456789', 'hex'), // hashOffset ...Buffer.from('3456789a', 'hex'), // hashSize ]); - const inst = new Pedersen(/*dstOffset=*/ 0x12345678, /*hashOffset=*/ 0x23456789, /*hashSize=*/ 0x3456789a); + const inst = new Pedersen( + /*indirect=*/ 1, + /*dstOffset=*/ 0x12345678, + /*hashOffset=*/ 0x23456789, + /*hashSize=*/ 0x3456789a, + ); expect(Sha256.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); - it('Should hash correctly', async () => { + it('Should hash correctly - direct', async () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; const hashOffset = 0; + const indirect = 0; context.machineState.memory.setSlice(hashOffset, args); const dstOffset = 3; const inputBuffer = args.map(field => field.toBuffer()); const expectedHash = pedersenHash(inputBuffer); - await new Pedersen(dstOffset, hashOffset, args.length).execute(context); + await new Pedersen(indirect, dstOffset, hashOffset, args.length).execute(context); + + const result = context.machineState.memory.get(dstOffset); + expect(result).toEqual(new Field(toBigIntBE(expectedHash))); + }); + + it('Should hash correctly - indirect', async () => { + const args = [new Field(1n), new Field(2n), new Field(3n)]; + const indirect = 1; + const hashOffset = 0; + const realLocation = 4; + + context.machineState.memory.set(hashOffset, new Uint32(realLocation)); + context.machineState.memory.setSlice(realLocation, args); + + const dstOffset = 3; + + const inputBuffer = args.map(field => field.toBuffer()); + const expectedHash = pedersenHash(inputBuffer); + await new Pedersen(indirect, dstOffset, hashOffset, args.length).execute(context); const result = context.machineState.memory.get(dstOffset); expect(result).toEqual(new Field(toBigIntBE(expectedHash))); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.ts b/yarn-project/simulator/src/avm/opcodes/hashing.ts index 5add968ac6e0..99e64b0a4439 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.ts @@ -4,6 +4,7 @@ import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/cr import { AvmContext } from '../avm_context.js'; import { Field } from '../avm_memory_types.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; +import { Addressing } from './addressing_mode.js'; import { Instruction } from './instruction.js'; export class Poseidon2 extends Instruction { @@ -12,21 +13,28 @@ export class Poseidon2 extends Instruction { // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ + OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, ]; - constructor(private dstOffset: number, private hashOffset: number, private hashSize: number) { + constructor( + private indirect: number, + private dstOffset: number, + private hashOffset: number, + private hashSize: number, + ) { super(); } async execute(context: AvmContext): Promise { // We hash a set of field elements - const hashData = context.machineState.memory - .getSlice(this.hashOffset, this.hashOffset + this.hashSize) - .map(word => word.toBuffer()); + const [hashOffset] = Addressing.fromWire(this.indirect).resolve([this.hashOffset], context.machineState.memory); + + // Memory pointer will be indirect + const hashData = context.machineState.memory.getSlice(hashOffset, this.hashSize).map(word => word.toBuffer()); const hash = poseidonHash(hashData); context.machineState.memory.set(this.dstOffset, new Field(hash)); @@ -41,22 +49,31 @@ export class Keccak extends Instruction { // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ + OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, ]; - constructor(private dstOffset: number, private hashOffset: number, private hashSize: number) { + constructor( + private indirect: number, + private dstOffset: number, + private hashOffset: number, + private hashSize: number, + ) { super(); } // Note hash output is 32 bytes, so takes up two fields async execute(context: AvmContext): Promise { // We hash a set of field elements - const hashData = context.machineState.memory - .getSlice(this.hashOffset, this.hashOffset + this.hashSize) - .map(word => word.toBuffer()); + const [hashOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve( + [this.hashOffset, this.dstOffset], + context.machineState.memory, + ); + + const hashData = context.machineState.memory.getSlice(hashOffset, this.hashSize).map(word => word.toBuffer()); const hash = keccak(Buffer.concat(hashData)); @@ -64,8 +81,8 @@ export class Keccak extends Instruction { const high = new Field(toBigIntBE(hash.subarray(0, 16))); const low = new Field(toBigIntBE(hash.subarray(16, 32))); - context.machineState.memory.set(this.dstOffset, high); - context.machineState.memory.set(this.dstOffset + 1, low); + context.machineState.memory.set(dstOffset, high); + context.machineState.memory.set(dstOffset + 1, low); context.machineState.incrementPc(); } @@ -77,22 +94,31 @@ export class Sha256 extends Instruction { // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ + OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, ]; - constructor(private dstOffset: number, private hashOffset: number, private hashSize: number) { + constructor( + private indirect: number, + private dstOffset: number, + private hashOffset: number, + private hashSize: number, + ) { super(); } // Note hash output is 32 bytes, so takes up two fields async execute(context: AvmContext): Promise { + const [hashOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve( + [this.hashOffset, this.dstOffset], + context.machineState.memory, + ); + // We hash a set of field elements - const hashData = context.machineState.memory - .getSlice(this.hashOffset, this.hashOffset + this.hashSize) - .map(word => word.toBuffer()); + const hashData = context.machineState.memory.getSlice(hashOffset, this.hashSize).map(word => word.toBuffer()); const hash = sha256(Buffer.concat(hashData)); @@ -100,8 +126,8 @@ export class Sha256 extends Instruction { const high = new Field(toBigIntBE(hash.subarray(0, 16))); const low = new Field(toBigIntBE(hash.subarray(16, 32))); - context.machineState.memory.set(this.dstOffset, high); - context.machineState.memory.set(this.dstOffset + 1, low); + context.machineState.memory.set(dstOffset, high); + context.machineState.memory.set(dstOffset + 1, low); context.machineState.incrementPc(); } @@ -113,21 +139,27 @@ export class Pedersen extends Instruction { // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ + OperandType.UINT8, OperandType.UINT8, OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, ]; - constructor(private dstOffset: number, private hashOffset: number, private hashSize: number) { + constructor( + private indirect: number, + private dstOffset: number, + private hashOffset: number, + private hashSize: number, + ) { super(); } async execute(context: AvmContext): Promise { + const [hashOffset] = Addressing.fromWire(this.indirect).resolve([this.hashOffset], context.machineState.memory); + // We hash a set of field elements - const hashData = context.machineState.memory - .getSlice(this.hashOffset, this.hashOffset + this.hashSize) - .map(word => word.toBuffer()); + const hashData = context.machineState.memory.getSlice(hashOffset, this.hashSize).map(word => word.toBuffer()); // No domain sep for now const hash = pedersenHash(hashData); diff --git a/yarn-project/simulator/src/avm/opcodes/memory.ts b/yarn-project/simulator/src/avm/opcodes/memory.ts index d8c9ad7c0aed..4f8f28e1f862 100644 --- a/yarn-project/simulator/src/avm/opcodes/memory.ts +++ b/yarn-project/simulator/src/avm/opcodes/memory.ts @@ -186,6 +186,7 @@ export class CalldataCopy extends Instruction { const transformedData = context.environment.calldata .slice(this.cdOffset, this.cdOffset + this.copySize) .map(f => new Field(f)); + context.machineState.memory.setSlice(this.dstOffset, transformedData); context.machineState.incrementPc(); From 7c0004d4e3333bede11b317e73312471ff0963d1 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Tue, 20 Feb 2024 02:08:56 +0000 Subject: [PATCH 08/10] git subrepo push --branch=master barretenberg subrepo: subdir: "barretenberg" merged: "71c35f6b8" upstream: origin: "https://github.com/AztecProtocol/barretenberg" branch: "master" commit: "71c35f6b8" git-subrepo: version: "0.4.6" origin: "???" commit: "???" [skip ci] --- barretenberg/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/barretenberg/.gitrepo b/barretenberg/.gitrepo index 671fc4108206..da257d1bf089 100644 --- a/barretenberg/.gitrepo +++ b/barretenberg/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AztecProtocol/barretenberg branch = master - commit = c2f1a58aa28097f7f303a469a7499ea845104736 - parent = e6d65a7fe9ebe855dcac389775aae2ccc3fa311f + commit = 71c35f6b838ed4dbd14ae6cc329677bcd0391499 + parent = 9f67eec73c5d639df16e6b3bf45c4a1fc1c54bad method = merge cmdver = 0.4.6 From 4f372703bcd2a13a7949cc3370356d0b376746ef Mon Sep 17 00:00:00 2001 From: spypsy Date: Tue, 20 Feb 2024 10:35:17 +0000 Subject: [PATCH 09/10] fix: aztec-node terraform args (#4669) Co-authored-by: PhilWindle <60546371+PhilWindle@users.noreply.github.com> --- yarn-project/aztec-node/terraform/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/aztec-node/terraform/main.tf b/yarn-project/aztec-node/terraform/main.tf index a65230f6a16c..531d7c0535ab 100644 --- a/yarn-project/aztec-node/terraform/main.tf +++ b/yarn-project/aztec-node/terraform/main.tf @@ -155,6 +155,7 @@ resource "aws_ecs_task_definition" "aztec-node" { { "name": "${var.DEPLOY_TAG}-aztec-node-${count.index + 1}", "image": "${var.DOCKERHUB_ACCOUNT}/aztec:${var.DEPLOY_TAG}", + "command": ["start", "--node", "--archiver", "--sequencer"], "essential": true, "memoryReservation": 3776, "portMappings": [ From 4c7f24f8ea8c21bc8114ead67d2082a06c9c5493 Mon Sep 17 00:00:00 2001 From: Lucas Xia Date: Tue, 20 Feb 2024 05:56:32 -0500 Subject: [PATCH 10/10] chore: make first iteration of protogalaxy more efficient (#4630) This work makes the first iteration of protogalaxy more efficient by removing the perturbator computation in just the first iteration. We can do this because in the first iteration, there is no accumulator, so we're just folding instances together. Because of this, we can assume that f_i(\omega) is 0 for all i. This seems suspicious, but this assumption is fine because if the instances were not valid (some f_i(\omega) is not 0), folding invalid instances would yield an invalid accumlator so it wouldn't matter in the end. Normally, we can't do this because f_i(\omega) for a correct accumulator is not all 0s, as \omega is some folded thing. Fixes https://github.com/AztecProtocol/barretenberg/issues/740. --- .../protogalaxy/protogalaxy_prover.cpp | 20 ++++++++----------- .../protogalaxy/protogalaxy_prover.hpp | 2 -- .../protogalaxy/protogalaxy_verifier.cpp | 19 +++++++----------- .../protogalaxy_recursive_verifier.cpp | 19 +++++++----------- 4 files changed, 22 insertions(+), 38 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 372926ddafb4..b32aecff411f 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -154,17 +154,9 @@ template void ProtoGalaxyProver_::prepa send_accumulator(instance, domain_separator); } else { // This is the first round of folding and we need to generate some gate challenges. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more - // efficient by avoiding the computation of the perturbator finalise_and_send_instance(instance, domain_separator); instance->target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(instance->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < instance->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - instance->gate_challenges = gate_challenges; + instance->gate_challenges = std::vector(instance->log_instance_size, 0); } idx++; @@ -315,9 +307,13 @@ template void ProtoGalaxyProver_::pertu state.accumulator = get_accumulator(); FF delta = transcript->template get_challenge("delta"); state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); - state.perturbator = compute_perturbator(state.accumulator, state.deltas); - for (size_t idx = 0; idx <= state.accumulator->log_instance_size; idx++) { - transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); + state.perturbator = Polynomial(state.accumulator->log_instance_size + 1); // initialize to all zeros + // compute perturbator only if this is not the first round and has an accumulator + if (state.accumulator->is_accumulator) { + state.perturbator = compute_perturbator(state.accumulator, state.deltas); + for (size_t idx = 0; idx <= state.accumulator->log_instance_size; idx++) { + transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); + } } }; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index cbe139eb37c0..0df61d1d82f1 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -134,8 +134,6 @@ template class ProtoGalaxyProver_ { // Returns the accumulator, which is the first element in ProverInstances. The accumulator is assumed to have the // FoldingParameters set and be the result of a previous round of folding. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): handle the case when the accumulator is empty - // (i.e. we are in the first round of folding)/ std::shared_ptr get_accumulator() { return instances[0]; } /** diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 07b32554f348..bdcfa0500e93 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -159,17 +159,9 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec receive_accumulator(inst, domain_separator); } else { // This is the first round of folding and we need to generate some gate challenges. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more - // efficient by avoiding the computation of the perturbator receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(inst->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < inst->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - inst->gate_challenges = gate_challenges; + inst->gate_challenges = std::vector(inst->log_instance_size, 0); } index++; @@ -189,9 +181,12 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve auto accumulator = get_accumulator(); auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); - std::vector perturbator_coeffs(accumulator->log_instance_size + 1); - for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { - perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + if (accumulator->is_accumulator) { + for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { + perturbator_coeffs[idx] = + transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + } } if (perturbator_coeffs[0] != accumulator->target_sum) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 047cfa4037e6..6ac10f7cd30d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -164,17 +164,9 @@ template void ProtoGalaxyRecursiveVerifier_target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(inst->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < inst->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - inst->gate_challenges = gate_challenges; + inst->gate_challenges = std::vector(inst->log_instance_size, 0); } index++; @@ -199,9 +191,12 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons auto accumulator = get_accumulator(); auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); - std::vector perturbator_coeffs(accumulator->log_instance_size + 1); - for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { - perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + if (accumulator->is_accumulator) { + for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { + perturbator_coeffs[idx] = + transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + } } // TODO(https://github.com/AztecProtocol/barretenberg/issues/833): As currently the stdlib transcript is not