From aa3775f57a20a8fc861a654e60654291f4ffd080 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 23 Jan 2020 14:02:37 -0500 Subject: [PATCH 001/220] Delete libsnark source code --- src/snark/.gitignore | 51 - src/snark/AUTHORS | 22 - src/snark/LICENSE | 24 - src/snark/Makefile | 289 --- src/snark/README.md | 628 ------ src/snark/doxygen.conf | 1807 ----------------- .../algebra/curves/alt_bn128/alt_bn128_g1.cpp | 525 ----- .../algebra/curves/alt_bn128/alt_bn128_g1.hpp | 95 - .../algebra/curves/alt_bn128/alt_bn128_g2.cpp | 506 ----- .../algebra/curves/alt_bn128/alt_bn128_g2.hpp | 96 - .../curves/alt_bn128/alt_bn128_init.cpp | 273 --- .../curves/alt_bn128/alt_bn128_init.hpp | 57 - .../curves/alt_bn128/alt_bn128_pairing.cpp | 547 ----- .../curves/alt_bn128/alt_bn128_pairing.hpp | 92 - .../algebra/curves/alt_bn128/alt_bn128_pp.cpp | 58 - .../algebra/curves/alt_bn128/alt_bn128_pp.hpp | 50 - .../libsnark/algebra/curves/curve_utils.hpp | 22 - .../libsnark/algebra/curves/curve_utils.tcc | 37 - .../libsnark/algebra/curves/public_params.hpp | 103 - .../algebra/curves/tests/test_bilinearity.cpp | 139 -- .../algebra/curves/tests/test_groups.cpp | 176 -- .../domains/basic_radix2_domain.hpp | 45 - .../domains/basic_radix2_domain.tcc | 113 -- .../domains/basic_radix2_domain_aux.hpp | 48 - .../domains/basic_radix2_domain_aux.tcc | 243 --- .../evaluation_domain/evaluation_domain.hpp | 125 -- .../evaluation_domain/evaluation_domain.tcc | 118 -- .../algebra/exponentiation/exponentiation.hpp | 31 - .../algebra/exponentiation/exponentiation.tcc | 53 - src/snark/libsnark/algebra/fields/bigint.hpp | 70 - src/snark/libsnark/algebra/fields/bigint.tcc | 280 --- .../libsnark/algebra/fields/field_utils.hpp | 51 - .../libsnark/algebra/fields/field_utils.tcc | 184 -- src/snark/libsnark/algebra/fields/fp.hpp | 182 -- src/snark/libsnark/algebra/fields/fp.tcc | 790 ------- .../algebra/fields/fp12_2over3over2.hpp | 116 -- .../algebra/fields/fp12_2over3over2.tcc | 412 ---- src/snark/libsnark/algebra/fields/fp2.hpp | 120 -- src/snark/libsnark/algebra/fields/fp2.tcc | 261 --- .../libsnark/algebra/fields/fp6_3over2.hpp | 104 - .../libsnark/algebra/fields/fp6_3over2.tcc | 216 -- src/snark/libsnark/algebra/fields/fp_aux.tcc | 389 ---- .../algebra/fields/tests/test_bigint.cpp | 106 - .../algebra/fields/tests/test_fields.cpp | 245 --- .../knowledge_commitment.hpp | 84 - .../knowledge_commitment.tcc | 111 - .../scalar_multiplication/kc_multiexp.hpp | 55 - .../scalar_multiplication/kc_multiexp.tcc | 276 --- .../scalar_multiplication/multiexp.hpp | 110 - .../scalar_multiplication/multiexp.tcc | 591 ------ .../algebra/scalar_multiplication/wnaf.hpp | 39 - .../algebra/scalar_multiplication/wnaf.tcc | 123 -- src/snark/libsnark/common/assert_except.hpp | 12 - .../data_structures/accumulation_vector.hpp | 74 - .../data_structures/accumulation_vector.tcc | 84 - .../common/data_structures/merkle_tree.hpp | 71 - .../common/data_structures/merkle_tree.tcc | 246 --- .../common/data_structures/sparse_vector.hpp | 79 - .../common/data_structures/sparse_vector.tcc | 316 --- .../libsnark/common/default_types/ec_pp.hpp | 53 - .../default_types/r1cs_ppzksnark_pp.hpp | 22 - src/snark/libsnark/common/profiling.cpp | 399 ---- src/snark/libsnark/common/profiling.hpp | 51 - src/snark/libsnark/common/serialization.hpp | 104 - src/snark/libsnark/common/serialization.tcc | 181 -- src/snark/libsnark/common/template_utils.hpp | 26 - src/snark/libsnark/common/utils.cpp | 102 - src/snark/libsnark/common/utils.hpp | 62 - src/snark/libsnark/common/utils.tcc | 31 - .../gadgetlib1/constraint_profiling.cpp | 48 - .../gadgetlib1/constraint_profiling.hpp | 42 - .../gadgetlib1/examples/simple_example.hpp | 23 - .../gadgetlib1/examples/simple_example.tcc | 54 - src/snark/libsnark/gadgetlib1/gadget.hpp | 27 - src/snark/libsnark/gadgetlib1/gadget.tcc | 23 - .../gadgetlib1/gadgets/basic_gadgets.hpp | 351 ---- .../gadgetlib1/gadgets/basic_gadgets.tcc | 705 ------- .../gadgetlib1/gadgets/gadget_from_r1cs.hpp | 45 - .../gadgetlib1/gadgets/gadget_from_r1cs.tcc | 123 -- .../gadgets/hashes/digest_selector_gadget.hpp | 42 - .../gadgets/hashes/digest_selector_gadget.tcc | 62 - .../gadgetlib1/gadgets/hashes/hash_io.hpp | 63 - .../gadgetlib1/gadgets/hashes/hash_io.tcc | 105 - .../gadgets/hashes/sha256/sha256_aux.hpp | 160 -- .../gadgets/hashes/sha256/sha256_aux.tcc | 297 --- .../hashes/sha256/sha256_components.hpp | 108 - .../hashes/sha256/sha256_components.tcc | 250 --- .../gadgets/hashes/sha256/sha256_gadget.hpp | 98 - .../gadgets/hashes/sha256/sha256_gadget.tcc | 230 --- .../tests/generate_sha256_gadget_tests.py | 55 - .../hashes/sha256/tests/pypy_sha256.py | 263 --- .../sha256/tests/test_sha256_gadget.cpp | 46 - .../merkle_authentication_path_variable.hpp | 38 - .../merkle_authentication_path_variable.tcc | 76 - .../merkle_tree_check_read_gadget.hpp | 73 - .../merkle_tree_check_read_gadget.tcc | 196 -- .../merkle_tree_check_update_gadget.hpp | 91 - .../merkle_tree_check_update_gadget.tcc | 265 --- .../tests/test_merkle_tree_gadgets.cpp | 48 - src/snark/libsnark/gadgetlib1/pb_variable.hpp | 144 -- src/snark/libsnark/gadgetlib1/pb_variable.tcc | 330 --- src/snark/libsnark/gadgetlib1/protoboard.hpp | 75 - src/snark/libsnark/gadgetlib1/protoboard.tcc | 189 -- src/snark/libsnark/gtests.cpp | 12 - .../reductions/r1cs_to_qap/r1cs_to_qap.hpp | 70 - .../reductions/r1cs_to_qap/r1cs_to_qap.tcc | 338 --- .../relations/arithmetic_programs/qap/qap.hpp | 193 -- .../relations/arithmetic_programs/qap/qap.tcc | 324 --- .../qap/tests/test_qap.cpp | 109 - .../r1cs/examples/r1cs_examples.hpp | 73 - .../r1cs/examples/r1cs_examples.tcc | 164 -- .../r1cs/r1cs.hpp | 153 -- .../r1cs/r1cs.tcc | 310 --- src/snark/libsnark/relations/variable.hpp | 213 -- src/snark/libsnark/relations/variable.tcc | 512 ----- .../examples/run_r1cs_ppzksnark.hpp | 35 - .../examples/run_r1cs_ppzksnark.tcc | 114 -- .../profiling/profile_r1cs_ppzksnark.cpp | 71 - .../r1cs_ppzksnark/r1cs_ppzksnark.hpp | 485 ----- .../r1cs_ppzksnark/r1cs_ppzksnark.tcc | 886 -------- .../r1cs_ppzksnark/r1cs_ppzksnark_params.hpp | 34 - .../tests/test_r1cs_ppzksnark.cpp | 42 - 122 files changed, 22084 deletions(-) delete mode 100644 src/snark/.gitignore delete mode 100644 src/snark/AUTHORS delete mode 100644 src/snark/LICENSE delete mode 100644 src/snark/Makefile delete mode 100644 src/snark/README.md delete mode 100644 src/snark/doxygen.conf delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp delete mode 100644 src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp delete mode 100644 src/snark/libsnark/algebra/curves/curve_utils.hpp delete mode 100644 src/snark/libsnark/algebra/curves/curve_utils.tcc delete mode 100644 src/snark/libsnark/algebra/curves/public_params.hpp delete mode 100644 src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp delete mode 100644 src/snark/libsnark/algebra/curves/tests/test_groups.cpp delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp delete mode 100644 src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc delete mode 100644 src/snark/libsnark/algebra/exponentiation/exponentiation.hpp delete mode 100644 src/snark/libsnark/algebra/exponentiation/exponentiation.tcc delete mode 100644 src/snark/libsnark/algebra/fields/bigint.hpp delete mode 100644 src/snark/libsnark/algebra/fields/bigint.tcc delete mode 100644 src/snark/libsnark/algebra/fields/field_utils.hpp delete mode 100644 src/snark/libsnark/algebra/fields/field_utils.tcc delete mode 100644 src/snark/libsnark/algebra/fields/fp.hpp delete mode 100644 src/snark/libsnark/algebra/fields/fp.tcc delete mode 100644 src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp delete mode 100644 src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc delete mode 100644 src/snark/libsnark/algebra/fields/fp2.hpp delete mode 100644 src/snark/libsnark/algebra/fields/fp2.tcc delete mode 100644 src/snark/libsnark/algebra/fields/fp6_3over2.hpp delete mode 100644 src/snark/libsnark/algebra/fields/fp6_3over2.tcc delete mode 100644 src/snark/libsnark/algebra/fields/fp_aux.tcc delete mode 100644 src/snark/libsnark/algebra/fields/tests/test_bigint.cpp delete mode 100644 src/snark/libsnark/algebra/fields/tests/test_fields.cpp delete mode 100644 src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp delete mode 100644 src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp delete mode 100644 src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc delete mode 100644 src/snark/libsnark/common/assert_except.hpp delete mode 100644 src/snark/libsnark/common/data_structures/accumulation_vector.hpp delete mode 100644 src/snark/libsnark/common/data_structures/accumulation_vector.tcc delete mode 100644 src/snark/libsnark/common/data_structures/merkle_tree.hpp delete mode 100644 src/snark/libsnark/common/data_structures/merkle_tree.tcc delete mode 100644 src/snark/libsnark/common/data_structures/sparse_vector.hpp delete mode 100644 src/snark/libsnark/common/data_structures/sparse_vector.tcc delete mode 100644 src/snark/libsnark/common/default_types/ec_pp.hpp delete mode 100644 src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp delete mode 100644 src/snark/libsnark/common/profiling.cpp delete mode 100644 src/snark/libsnark/common/profiling.hpp delete mode 100644 src/snark/libsnark/common/serialization.hpp delete mode 100644 src/snark/libsnark/common/serialization.tcc delete mode 100644 src/snark/libsnark/common/template_utils.hpp delete mode 100644 src/snark/libsnark/common/utils.cpp delete mode 100644 src/snark/libsnark/common/utils.hpp delete mode 100644 src/snark/libsnark/common/utils.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/constraint_profiling.cpp delete mode 100644 src/snark/libsnark/gadgetlib1/constraint_profiling.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/examples/simple_example.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/examples/simple_example.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadget.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadget.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp delete mode 100644 src/snark/libsnark/gadgetlib1/pb_variable.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/pb_variable.tcc delete mode 100644 src/snark/libsnark/gadgetlib1/protoboard.hpp delete mode 100644 src/snark/libsnark/gadgetlib1/protoboard.tcc delete mode 100644 src/snark/libsnark/gtests.cpp delete mode 100644 src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp delete mode 100644 src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc delete mode 100644 src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp delete mode 100644 src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc delete mode 100644 src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp delete mode 100644 src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp delete mode 100644 src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc delete mode 100644 src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp delete mode 100644 src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc delete mode 100644 src/snark/libsnark/relations/variable.hpp delete mode 100644 src/snark/libsnark/relations/variable.tcc delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp delete mode 100644 src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp diff --git a/src/snark/.gitignore b/src/snark/.gitignore deleted file mode 100644 index ea2a20f44..000000000 --- a/src/snark/.gitignore +++ /dev/null @@ -1,51 +0,0 @@ -*.o -*.a -*.so -*.d -libsnark/gtests -depinst/ -depsrc/ -README.html -doxygen/ -libsnark/gtests -libsnark/gadgetlib2/examples/tutorial -libsnark/gadgetlib2/tests/gadgetlib2_test - -libsnark/algebra/curves/tests/test_bilinearity -libsnark/algebra/curves/tests/test_groups -libsnark/algebra/fields/tests/test_fields -libsnark/common/routing_algorithms/profiling/profile_routing_algorithms -libsnark/common/routing_algorithms/tests/test_routing_algorithms -libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram -libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget -libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget -libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets -libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets -libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget -libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget -libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization -libsnark/relations/arithmetic_programs/qap/tests/test_qap -libsnark/relations/arithmetic_programs/ssp/tests/test_ssp -libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd -libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd -libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd -libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd -libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark -libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark -libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark -libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark -libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark -libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark -libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark -libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark -libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark diff --git a/src/snark/AUTHORS b/src/snark/AUTHORS deleted file mode 100644 index cdc8d66af..000000000 --- a/src/snark/AUTHORS +++ /dev/null @@ -1,22 +0,0 @@ -SCIPR Lab: - Eli Ben-Sasson - Alessandro Chiesa - Daniel Genkin - Shaul Kfir - Eran Tromer - Madars Virza - -External contributors: - Michael Backes - Manuel Barbosa - Dario Fiore - Jens Groth - Joshua A. Kroll - Shigeo MITSUNARI - Raphael Reischuk - Tadanori TERUYA - Sean Bowe - Daira Hopwood - @mugatu on forum.z.cash - David Mercer - Joshua Yabut diff --git a/src/snark/LICENSE b/src/snark/LICENSE deleted file mode 100644 index 81cea11e1..000000000 --- a/src/snark/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -The libsnark library is developed by SCIPR Lab (http://scipr-lab.org) -and contributors. - -Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file). - -All files, with the exceptions below, are released under the MIT License: - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. diff --git a/src/snark/Makefile b/src/snark/Makefile deleted file mode 100644 index 3ef82ab87..000000000 --- a/src/snark/Makefile +++ /dev/null @@ -1,289 +0,0 @@ -#******************************************************************************** -# Makefile for the libsnark library. -#******************************************************************************** -#* @author This file is part of libsnark, developed by SCIPR Lab -#* and contributors (see AUTHORS). -#* @copyright MIT license (see LICENSE file) -#*******************************************************************************/ - -# Determine building operating system -ifeq ($(OS),Windows_NT) - uname_S := Windows -else - uname_S := $(shell uname -s) -endif - -# To override these, use "make OPTFLAGS=..." etc. -CURVE = BN128 -OPTFLAGS = -O2 -march=x86-64 -g -mtune=x86-64 - -ifneq ($(PLATFORM),darwin) - FEATUREFLAGS = -DUSE_ASM -DMONTGOMERY_OUTPUT -else - FEATUREFLAGS = -DUSE_ASM -DMONTGOMERY_OUTPUT -D__SIZE_TYPE__="unsigned long long" -endif - -# Initialize this using "CXXFLAGS=... make". The makefile appends to that. -CXXFLAGS += -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-comment -Wfatal-errors $(OPTFLAGS) $(FEATUREFLAGS) -DCURVE_$(CURVE) - -DEPSRC = depsrc -DEPINST = depinst - -CXXFLAGS += -I$(DEPINST)/include -Ilibsnark -LDFLAGS += -L$(DEPINST)/lib -Wl,-rpath,$(DEPINST)/lib -LDLIBS += -lgmpxx -lgmp -lboost_program_options -lsodium -# List of .a files to include within libsnark.a and libsnark.so: -AR_LIBS = -# List of library files to install: -INSTALL_LIBS = $(LIB_FILE) -# Sentinel file to check existence of this directory (since directories don't work as a Make dependency): -DEPINST_EXISTS = $(DEPINST)/.exists - -ifneq ($(NO_GTEST),1) - # Compile GTest from sourcecode if we can (e.g., Ubuntu). Otherwise use precompiled one (e.g., Fedora). - # See https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#why-is-it-not-recommended-to-install-a-pre-compiled-copy-of-google-test-for-example-into-usrlocal - ifneq ($(NO_COMPILE_LIBGTEST),1) - GTESTDIR=/usr/src/gtest - COMPILE_LIBGTEST = $(shell test -d $(GTESTDIR) && echo -n 1) - endif - GTEST_LDLIBS += -lgtest -lpthread -endif - -ifneq ($(NO_SUPERCOP),1) - SUPERCOP_LDLIBS += -lsupercop - INSTALL_LIBS += depinst/lib/libsupercop.a - # Would have been nicer to roll supercop into libsnark.a ("AR_LIBS += $(DEPINST)/lib/libsupercop.a"), but it doesn't support position-independent code (libsnark issue #20). -endif - -LIB_SRCS = \ - libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp \ - libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp \ - libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp \ - libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp \ - libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp \ - libsnark/common/profiling.cpp \ - libsnark/common/utils.cpp \ - libsnark/gadgetlib1/constraint_profiling.cpp \ - -ifeq ($(CURVE),BN128) - LIB_SRCS += \ - libsnark/algebra/curves/bn128/bn128_g1.cpp \ - libsnark/algebra/curves/bn128/bn128_g2.cpp \ - libsnark/algebra/curves/bn128/bn128_gt.cpp \ - libsnark/algebra/curves/bn128/bn128_init.cpp \ - libsnark/algebra/curves/bn128/bn128_pairing.cpp \ - libsnark/algebra/curves/bn128/bn128_pp.cpp - - CXXFLAGS += -DBN_SUPPORT_SNARK - AR_LIBS += $(DEPINST)/lib/libzm.a -endif - -# FIXME: most of these are broken due to removed code. -DISABLED_EXECUTABLES = \ - libsnark/common/routing_algorithms/profiling/profile_routing_algorithms \ - libsnark/common/routing_algorithms/tests/test_routing_algorithms \ - libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram \ - libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget \ - libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets \ - libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget \ - libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget \ - libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization \ - libsnark/relations/arithmetic_programs/ssp/tests/test_ssp \ - libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd \ - libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd \ - libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd \ - libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd \ - libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark \ - libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark \ - libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark \ - libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark - -EXECUTABLES = - -EXECUTABLES_WITH_GTEST = - -EXECUTABLES_WITH_SUPERCOP = \ - libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark - -GTEST_TESTS = - -GTEST_SRCS = - -DOCS = README.html - -LIBSNARK_A = libsnark.a - -# For documentation of the following options, see README.md . - -ifeq ($(NO_PROCPS),1) - CXXFLAGS += -DNO_PROCPS -else - LDLIBS += -lprocps -endif - -ifeq ($(LOWMEM),1) - CXXFLAGS += -DLOWMEM -endif - -ifeq ($(PROFILE_OP_COUNTS),1) - STATIC = 1 - CXXFLAGS += -DPROFILE_OP_COUNTS -endif - -ifeq ($(STATIC),1) -ifneq ($(PLATFORM),darwin) - CXXFLAGS += -static -endif - CXXFLAGS += -DSTATIC -else - CXXFLAGS += -fPIC -endif - -ifeq ($(MULTICORE),1) - CXXFLAGS += -DMULTICORE -fopenmp -endif - -ifeq ($(CPPDEBUG),1) - CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC - DEBUG = 1 -endif - -ifeq ($(DEBUG),1) - CXXFLAGS += -DDEBUG -ggdb3 -endif - -ifeq ($(PERFORMANCE),1) - OPTFLAGS = -O3 -march=x86-64 -g -mtune=x86-64 - CXXFLAGS += -DNDEBUG - # Enable link-time optimization: - CXXFLAGS += -flto -fuse-linker-plugin - LDFLAGS += -flto -endif - -LIB_OBJS =$(patsubst %.cpp,%.o,$(LIB_SRCS)) -EXEC_OBJS =$(patsubst %,%.o,$(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP)) -GTEST_OBJS =$(patsubst %.cpp,%.o,$(GTEST_SRCS)) - -all: \ - $(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \ - $(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \ - $(EXECUTABLES) \ - $(LIBSNARK_A) \ - $(if $(NO_DOCS),,doc) - -doc: $(DOCS) - -$(DEPINST_EXISTS): - # Create placeholder directories for installed dependencies. Some make settings (including the default) require actually running ./prepare-depends.sh to populate this directory. - mkdir -p $(DEPINST)/lib $(DEPINST)/include - touch $@ - -# In order to detect changes to #include dependencies. -MMD below generates a .d file for each .o file. Include the .d file. --include $(patsubst %.o,%.d, $(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) ) - -$(LIB_OBJS) $(if $(NO_GTEST),,$(GTEST_OBJS)) $(EXEC_OBJS): %.o: %.cpp - $(CXX) -o $@ $< -c -MMD $(CXXFLAGS) - -LIBGTEST_A = $(DEPINST)/lib/libgtest.a - -$(LIBGTEST_A): $(GTESTDIR)/libsnark/gtest-all.cc $(DEPINST_EXISTS) - $(CXX) -o $(DEPINST)/lib/gtest-all.o -I $(GTESTDIR) -c -isystem $(GTESTDIR)/include $< $(CXXFLAGS) - $(AR) -rv $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o - -# libsnark.a will contains all of our relevant object files, and we also mash in the .a files of relevant dependencies built by ./prepare-depends.sh -$(LIBSNARK_A): $(LIB_OBJS) $(AR_LIBS) - $(AR) q $(LIBSNARK_A) $(LIB_OBJS) - if [ -n "$(AR_LIBS)" ]; then mkdir -p tmp-ar; cd tmp-ar; for AR_LIB in $(AR_LIBS); do $(AR) x $$AR_LIB; done; $(AR) qc $(LIBSNARK_A) tmp-ar/*; cd ..; rm -r tmp-ar; fi; - $(AR) s $(LIBSNARK_A) - -libsnark.so: $(LIBSNARK_A) $(DEPINST_EXISTS) - $(CXX) -o $@ --shared -Wl,--whole-archive $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) -Wl,--no-whole-archive $(LDLIBS) - -libsnark/gadgetlib2/tests/gadgetlib2_test: \ - libsnark/gadgetlib2/tests/adapters_UTEST.cpp \ - libsnark/gadgetlib2/tests/constraint_UTEST.cpp \ - libsnark/gadgetlib2/tests/gadget_UTEST.cpp \ - libsnark/gadgetlib2/tests/integration_UTEST.cpp \ - libsnark/gadgetlib2/tests/protoboard_UTEST.cpp \ - libsnark/gadgetlib2/tests/variable_UTEST.cpp - -$(EXECUTABLES): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS) - $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) - -$(EXECUTABLES_WITH_GTEST): %: %.o $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS) - $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS) - -$(EXECUTABLES_WITH_SUPERCOP): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS) - $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(SUPERCOP_LDLIBS) $(LDLIBS) - -$(GTEST_TESTS): %: $(GTEST_OBJS) $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS) - $(CXX) -o $@ $(GTEST_OBJS) $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS) - - -ifeq ($(STATIC),1) -LIB_FILE = $(LIBSNARK_A) -else -LIB_FILE = libsnark.so -endif - -lib: $(LIB_FILE) - -$(DOCS): %.html: %.md - markdown_py -f $@ $^ -x toc -x extra --noisy -# TODO: Would be nice to enable "-x smartypants" but Ubuntu 12.04 doesn't support that. -# TODO: switch to redcarpet, to produce same output as GitHub's processing of README.md. But what about TOC? - -ifeq ($(PREFIX),) -install: - $(error Please provide PREFIX. E.g. make install PREFIX=/usr) -else -HEADERS_SRC=$(shell find libsnark -name '*.hpp' -o -name '*.tcc') -HEADERS_DEST=$(patsubst libsnark/%,$(PREFIX)/include/libsnark/%,$(HEADERS_SRC)) - -$(HEADERS_DEST): $(PREFIX)/include/libsnark/%: libsnark/% - mkdir -p $(shell dirname $@) - cp $< $@ - -install: $(INSTALL_LIBS) $(HEADERS_DEST) $(DEPINST_EXISTS) - mkdir -p $(PREFIX)/lib - cp -v $(INSTALL_LIBS) $(PREFIX)/lib/ -ifneq ($(NO_COPY_DEPINST),1) - cp -rv $(DEPINST)/include $(PREFIX) -endif -endif - -check: $(GTEST_TESTS) - $(GTEST_TESTS) - -doxy: - doxygen doxygen.conf - -# Clean generated files, except locally-compiled dependencies -clean: - $(RM) \ - $(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) \ - $(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP) $(GTEST_TESTS) \ - $(DOCS) \ - ${patsubst %.o,%.d,${LIB_OBJS} ${GTEST_OBJS} ${EXEC_OBJS}} \ - libsnark.so $(LIBSNARK_A) \ - $(RM) -fr doxygen/ \ - $(RM) $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o - -# Clean all, including locally-compiled dependencies -clean-all: clean - $(RM) -fr $(DEPSRC) $(DEPINST) - -.PHONY: all clean clean-all doc doxy lib install diff --git a/src/snark/README.md b/src/snark/README.md deleted file mode 100644 index d5aa34006..000000000 --- a/src/snark/README.md +++ /dev/null @@ -1,628 +0,0 @@ -libsnark: a C++ library for zkSNARK proofs -================================================================================ - --------------------------------------------------------------------------------- -Authors --------------------------------------------------------------------------------- - -The libsnark library is developed by the [SCIPR Lab] project and contributors -and is released under the MIT License (see the [LICENSE] file). - -Copyright (c) 2012-2014 SCIPR Lab and contributors (see [AUTHORS] file). - --------------------------------------------------------------------------------- -[TOC] - - - --------------------------------------------------------------------------------- -Overview --------------------------------------------------------------------------------- - -This library implements __zkSNARK__ schemes, which are a cryptographic method -for proving/verifying, in zero knowledge, the integrity of computations. - -A computation can be expressed as an NP statement, in forms such as the following: - -- "The C program _foo_, when executed, returns exit code 0 if given the input _bar_ and some additional input _qux_." -- "The Boolean circuit _foo_ is satisfiable by some input _qux_." -- "The arithmetic circuit _foo_ accepts the partial assignment _bar_, when extended into some full assignment _qux_." -- "The set of constraints _foo_ is satisfiable by the partial assignment _bar_, when extended into some full assignment _qux_." - -A prover who knows the witness for the NP statement (i.e., a satisfying input/assignment) can produce a short proof attesting to the truth of the NP statement. This proof can be verified by anyone, and offers the following properties. - -- __Zero knowledge:__ - the verifier learns nothing from the proof beside the truth of the statement (i.e., the value _qux_, in the above examples, remains secret). -- __Succinctness:__ - the proof is short and easy to verify. -- __Non-interactivity:__ - the proof is a string (i.e. it does not require back-and-forth interaction between the prover and the verifier). -- __Soundness:__ - the proof is computationally sound (i.e., it is infeasible to fake a proof of a false NP statement). Such a proof system is also called an _argument_. -- __Proof of knowledge:__ - the proof attests not just that the NP statement is true, but also that the - prover knows why (e.g., knows a valid _qux_). - -These properties are summarized by the _zkSNARK_ acronym, which stands for _Zero-Knowledge Succinct Non-interactive ARgument of Knowledge_ (though zkSNARKs are also knows as -_succinct non-interactive computationally-sound zero-knowledge proofs of knowledge_). -For formal definitions and theoretical discussions about these, see -\[BCCT12], \[BCIOP13], and the references therein. - -The libsnark library currently provides a C++ implementation of: - -1. General-purpose proof systems: - 1. A preprocessing zkSNARK for the NP-complete language "R1CS" - (_Rank-1 Constraint Systems_), which is a language that is similar to arithmetic - circuit satisfiability. - 2. A preprocessing SNARK for a language of arithmetic circuits, "BACS" - (_Bilinear Arithmetic Circuit Satisfiability_). This simplifies the writing - of NP statements when the additional flexibility of R1CS is not needed. - Internally, it reduces to R1CS. - 3. A preprocessing SNARK for the language "USCS" - (_Unitary-Square Constraint Systems_). This abstracts and implements the core - contribution of \[DFGK14] - 4. A preprocessing SNARK for a language of Boolean circuits, "TBCS" - (_Two-input Boolean Circuit Satisfiability_). Internally, it reduces to USCS. - This is much more efficient than going through R1CS. - 5. ADSNARK, a preprocessing SNARKs for proving statements on authenticated - data, as described in \[BBFR15]. - 6. Proof-Carrying Data (PCD). This uses recursive composition of SNARKs, as - explained in \[BCCT13] and optimized in \[BCTV14b]. -2. Gadget libraries (gadgetlib1 and gadgetlib2) for constructing R1CS - instances out of modular "gadget" classes. -3. Examples of applications that use the above proof systems to prove - statements about: - 1. Several toy examples. - 2. Execution of TinyRAM machine code, as explained in \[BCTV14a] and - \[BCGTV13]. (Such machine code can be obtained, e.g., by compiling from C.) - This is easily adapted to any other Random Access Machine that satisfies a - simple load-store interface. - 3. A scalable for TinyRAM using Proof-Carrying Data, as explained in \[BCTV14b] - 4. Zero-knowldge cluster MapReduce, as explained in \[CTV15]. - -The zkSNARK construction implemented by libsnark follows, extends, and -optimizes the approach described in \[BCTV14], itself an extension of -\[BCGTV13], following the approach of \[BCIOP13] and \[GGPR13]. An alternative -implementation of the basic approach is the _Pinocchio_ system of \[PGHR13]. -See these references for discussions of efficiency aspects that arise in -practical use of such constructions, as well as security and trust -considerations. - -This scheme is a _preprocessing zkSNARK_ (_ppzkSNARK_): before proofs can be -created and verified, one needs to first decide on a size/circuit/system -representing the NP statements to be proved, and run a _generator_ algorithm to -create corresponding public parameters (a long proving key and a short -verification key). - -Using the library involves the following high-level steps: - -1. Express the statements to be proved as an R1CS (or any of the other - languages above, such as arithmetic circuits, Boolean circuits, or TinyRAM). - This is done by writing C++ code that constructs an R1CS, and linking this code - together with libsnark -2. Use libsnark's generator algorithm to create the public parameters for this - statement (once and for all). -3. Use libsnark's prover algorithm to create proofs of true statements about - the satisfiability of the R1CS. -4. Use libsnark's verifier algorithm to check proofs for alleged statements. - - --------------------------------------------------------------------------------- -The NP-complete language R1CS --------------------------------------------------------------------------------- - -The ppzkSNARK supports proving/verifying membership in a specific NP-complete -language: R1CS (*rank-1 constraint systems*). An instance of the language is -specified by a set of equations over a prime field F, and each equation looks like: - < A, (1,X) > * < B , (1,X) > = < C, (1,X) > -where A,B,C are vectors over F, and X is a vector of variables. - -In particular, arithmetic (as well as boolean) circuits are easily reducible to -this language by converting each gate into a rank-1 constraint. See \[BCGTV13] -Appendix E (and "System of Rank 1 Quadratic Equations") for more details about this. - - --------------------------------------------------------------------------------- -Elliptic curve choices --------------------------------------------------------------------------------- - -The ppzkSNARK can be instantiated with different parameter choices, depending on -which elliptic curve is used. The libsnark library currently provides three -options: - -* "edwards": - an instantiation based on an Edwards curve, providing 80 bits of security. - -* "bn128": - an instantiation based on a Barreto-Naehrig curve, providing 128 - bits of security. The underlying curve implementation is - \[ate-pairing], which has incorporated our patch that changes the - BN curve to one suitable for SNARK applications. - - * This implementation uses dynamically-generated machine code for the curve - arithmetic. Some modern systems disallow execution of code on the heap, and - will thus block this implementation. - - For example, on Fedora 20 at its default settings, you will get the error - `zmInit ERR:can't protect` when running this code. To solve this, - run `sudo setsebool -P allow_execheap 1` to allow execution, - or use `make CURVE=ALT_BN128` instead. - -* "alt_bn128": - an alternative to "bn128", somewhat slower but avoids dynamic code generation. - -Note that bn128 requires an x86-64 CPU while the other curve choices -should be architecture-independent; see [portability](#portability). - - --------------------------------------------------------------------------------- -Gadget libraries --------------------------------------------------------------------------------- - -The libsnark library currently provides two libraries for conveniently constructing -R1CS instances out of reusable "gadgets". Both libraries provide a way to construct -gadgets on other gadgets as well as additional explicit equations. In this way, -complex R1CS instances can be built bottom up. - -### gadgetlib1 - -This is a low-level library which expose all features of the preprocessing -zkSNARK for R1CS. Its design is based on templates (as does the ppzkSNARK code) -to efficiently support working on multiple elliptic curves simultaneously. This -library is used for most of the constraint-building in libsnark, both internal -(reductions and Proof-Carrying Data) and examples applications. - -### gadgetlib2 - -This is an alternative library for constructing systems of polynomial equations -and, in particular, also R1CS instances. It is better documented and easier to -use than gadgetlib1, and its interface does not use templates. However, fewer -useful gadgets are provided. - - --------------------------------------------------------------------------------- -Security --------------------------------------------------------------------------------- - -The theoretical security of the underlying mathematical constructions, and the -requisite assumptions, are analyzed in detailed in the aforementioned research -papers. - -** -This code is a research-quality proof of concept, and has not -yet undergone extensive review or testing. It is thus not suitable, -as is, for use in critical or production systems. -** - -Known issues include the following: - -* The ppzkSNARK's generator and prover exhibit data-dependent running times - and memory usage. These form timing and cache-contention side channels, - which may be an issue in some applications. - -* Randomness is retrieved from /dev/urandom, but this should be - changed to a carefully considered (depending on system and threat - model) external, high-quality randomness source when creating - long-term proving/verification keys. - - --------------------------------------------------------------------------------- -Build instructions --------------------------------------------------------------------------------- - -The libsnark library relies on the following: - -- C++ build environment -- GMP for certain bit-integer arithmetic -- libprocps for reporting memory usage -- GTest for some of the unit tests - -So far we have tested these only on Linux, though we have been able to make the library work, -with some features disabled (such as memory profiling or GTest tests), on Windows via Cygwin -and on Mac OS X. (If you succeed in achieving more complete ports of the library, please -let us know!) See also the notes on [portability](#portability) below. - -For example, on a fresh install of Ubuntu 14.04, install the following packages: - - $ sudo apt-get install build-essential git libgmp3-dev libprocps3-dev libgtest-dev python-markdown libboost-all-dev libssl-dev - -Or, on Fedora 20: - - $ sudo yum install gcc-c++ make git gmp-devel procps-ng-devel gtest-devel python-markdown - -Run the following, to fetch dependencies from their GitHub repos and compile them. -(Not required if you set `CURVE` to other than the default `BN128` and also set `NO_SUPERCOP=1`.) - - $ ./prepare-depends.sh - -Then, to compile the library, tests, profiling harness and documentation, run: - - $ make - -To create just the HTML documentation, run - - $ make doc - -and then view the resulting `README.html` (which contains the very text you are reading now). - -To create Doxygen documentation summarizing all files, classes and functions, -with some (currently sparse) comments, install the `doxygen` and `graphviz` packages, then run - - $ make doxy - -(this may take a few minutes). Then view the resulting [`doxygen/index.html`](doxygen/index.html). - -### Using libsnark as a library - -To develop an application that uses libsnark, you could add it within the libsnark directory tree and adjust the Makefile, but it is far better to build libsnark as a (shared or static) library. You can then write your code in a separate directory tree, and link it against libsnark. - - -To build just the shared object library `libsnark.so`, run: - - $ make lib - -To build just the static library `libsnark.a`, run: - - $ make lib STATIC=1 - -Note that static compilation requires static versions of all libraries it depends on. -It may help to minize these dependencies by appending -`CURVE=ALT_BN128 NO_PROCPS=1 NO_GTEST=1 NO_SUPERCOP=1`. On Fedora 21, the requisite -library RPM dependencies are then: -`boost-static glibc-static gmp-static libstdc++-static openssl-static zlib-static - boost-devel glibc-devel gmp-devel gmp-devel libstdc++-devel openssl-devel openssl-devel`. - -To build *and install* the libsnark library: - - $ make install PREFIX=/install/path - -This will install `libsnark.so` into `/install/path/lib`; so your application should be linked using `-L/install/path/lib -lsnark`. It also installs the requisite headers into `/install/path/include`; so your application should be compiled using `-I/install/path/include`. - -In addition, unless you use `NO_SUPERCOP=1`, `libsupercop.a` will be installed and should be linked in using `-lsupercop`. - - -### Building on Windows using Cygwin -Install Cygwin using the graphical installer, including the `g++`, `libgmp` -and `git` packages. Then disable the dependencies not easily supported under CygWin, -using: - - $ make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 - - -### Building on Mac OS X - -On Mac OS X, install GMP from MacPorts (`port install gmp`). Then disable the -dependencies not easily supported under CygWin, using: - - $ make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 - -MacPorts does not write its libraries into standard system folders, so you -might need to explicitly provide the paths to the header files and libraries by -appending `CXXFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib` to the line -above. Similarly, to pass the paths to ate-pairing you would run -`INC_DIR=-I/opt/local/include LIB_DIR=-L/opt/local/lib ./prepare-depends.sh` -instead of `./prepare-depends.sh` above. - --------------------------------------------------------------------------------- -Tutorials --------------------------------------------------------------------------------- - -libsnark includes a tutorial, and some usage examples, for the high-level API. - -* `src/gadgetlib1/examples1` contains a simple example for constructing a - constraint system using gadgetlib1. - -* `src/gadgetlib2/examples` contains a tutorial for using gadgetlib2 to express - NP statements as constraint systems. It introduces basic terminology, design - overview, and recommended programming style. It also shows how to invoke - ppzkSNARKs on such constraint systems. The main file, `tutorial.cpp`, builds - into a standalone executable. - -* `src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp` - constructs a simple constraint system and runs the ppzksnark. See below for how to - run it. - - --------------------------------------------------------------------------------- -Executing profiling example --------------------------------------------------------------------------------- - -The command - - $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 Fr - -exercises the ppzkSNARK (first generator, then prover, then verifier) on an -R1CS instance with 1000 equations and an input consisting of 10 field elements. - -(If you get the error `zmInit ERR:can't protect`, see the discussion -[above](#elliptic-curve-choices).) - -The command - - $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 bytes - -does the same but now the input consists of 10 bytes. - - --------------------------------------------------------------------------------- -Build options --------------------------------------------------------------------------------- - -The following flags change the behavior of the compiled code. - -* `make FEATUREFLAGS='-Dname1 -Dname2 ...'` - - Override the active conditional #define names (you can see the default at the top of the Makefile). - The next bullets list the most important conditionally-#defined features. - For example, `make FEATUREFLAGS='-DBINARY_OUTPUT'` enables binary output and disables the default - assembly optimizations and Montgomery-representation output. - -* define `BINARY_OUTPUT` - - In serialization, output raw binary data (instead of decimal, when not set). - -* `make CURVE=choice` / define `CURVE_choice` (where `choice` is one of: - ALT_BN128, BN128, EDWARDS, MNT4, MNT6) - - Set the default curve to one of the above (see [elliptic curve choices](#elliptic-curve-choices)). - -* `make DEBUG=1` / define `DEBUG` - - Print additional information for debugging purposes. - -* `make LOWMEM=1` / define `LOWMEM` - - Limit the size of multi-exponentiation tables, for low-memory platforms. - -* `make NO_DOCS=1` - - Do not generate HTML documentation, e.g. on platforms where Markdown is not easily available. - -* `make NO_PROCPS=1` - - Do not link against libprocps. This disables memory profiling. - -* `make NO_GTEST=1` - - Do not link against GTest. The tutorial and test suite of gadgetlib2 tutorial won't be compiled. - -* `make NO_SUPERCOP=1` - - Do not link against SUPERCOP for optimized crypto. The ADSNARK executables will not be built. - -* `make MULTICORE=1` - - Enable parallelized execution of the ppzkSNARK generator and prover, using OpenMP. - This will utilize all cores on the CPU for heavyweight parallelizabe operations such as - FFT and multiexponentiation. The default is single-core. - - To override the maximum number of cores used, set the environment variable `OMP_NUM_THREADS` - at runtime (not compile time), e.g., `OMP_NUM_THREADS=8 test_r1cs_sp_ppzkpc`. It defaults - to the autodetected number of cores, but on some devices, dynamic core management confused - OpenMP's autodetection, so setting `OMP_NUM_THREADS` is necessary for full utilization. - -* define `NO_PT_COMPRESSION` - - Do not use point compression. - This gives much faster serialization times, at the expense of ~2x larger - sizes for serialized keys and proofs. - -* define `MONTGOMERY_OUTPUT` (on by default) - - Serialize Fp elements as their Montgomery representations. If this - option is disabled then Fp elements are serialized as their - equivalence classes, which is slower but produces human-readable - output. - -* `make PROFILE_OP_COUNTS=1` / define `PROFILE_OP_COUNTS` - - Collect counts for field and curve operations inside static variables - of the corresponding algebraic objects. This option works for all - curves except bn128. - -* define `USE_ASM` (on by default) - - Use unrolled assembly routines for F[p] arithmetic and faster heap in - multi-exponentiation. (When not set, use GMP's `mpn_*` routines instead.) - -* define `USE_MIXED_ADDITION` - - Convert each element of the proving key and verification key to - affine coordinates. This allows using mixed addition formulas in - multiexponentiation and results in slightly faster prover and - verifier runtime at expense of increased proving time. - -* `make PERFORMANCE=1` - - Enables compiler optimizations such as link-time optimization, and disables debugging aids. - (On some distributions this causes a `plugin needed to handle lto object` link error and `undefined reference`s, which can be remedied by `AR=gcc-ar make ...`.) - -Not all combinations are tested together or supported by every part of the codebase. - - --------------------------------------------------------------------------------- -Portability --------------------------------------------------------------------------------- - -libsnark is written in fairly standard C++11. - -However, having been developed on Linux on x86-64 CPUs, libsnark has some limitations -with respect to portability. Specifically: - -1. libsnark's algebraic data structures assume little-endian byte order. - -2. Profiling routines use `clock_gettime` and `readproc` calls, which are Linux-specific. - -3. Random-number generation is done by reading from `/dev/urandom`, which is - specific to Unix-like systems. - -4. libsnark binary serialization routines (see `BINARY_OUTPUT` above) assume - a fixed machine word size (i.e. sizeof(mp_limb_t) for GMP's limb data type). - Objects serialized in binary on a 64-bit system cannot be de-serialized on - a 32-bit system, and vice versa. - (The decimal serialization routines have no such limitation.) - -5. libsnark requires a C++ compiler with good C++11 support. It has been - tested with g++ 4.7, g++ 4.8, and clang 3.4. - -6. On x86-64, we by default use highly optimized assembly implementations for some - operations (see `USE_ASM` above). On other architectures we fall back to a - portable C++ implementation, which is slower. - -Tested configurations include: - -* Debian jessie with g++ 4.7 on x86-64 -* Debian jessie with clang 3.4 on x86-64 -* Fedora 20/21 with g++ 4.8.2/4.9.2 on x86-64 and i686 -* Ubuntu 14.04 LTS with g++ 4.8 on x86-64 -* Ubuntu 14.04 LTS with g++ 4.8 on x86-32, for EDWARDS and ALT_BN128 curve choices -* Debian wheezy with g++ 4.7 on ARM little endian (Debian armel port) inside QEMU, for EDWARDS and ALT_BN128 curve choices -* Windows 7 with g++ 4.8.3 under Cygwin 1.7.30 on x86-64 with NO_PROCPS=1, NO_GTEST=1 and NO_DOCS=1, for EDWARDS and ALT_BN128 curve choices -* Mac OS X 10.9.4 (Mavericks) with Apple LLVM version 5.1 (based on LLVM 3.4svn) on x86-64 with NO_PROCPS=1, NO_GTEST=1 and NO_DOCS=1 - - --------------------------------------------------------------------------------- -Directory structure --------------------------------------------------------------------------------- - -The directory structure of the libsnark library is as follows: - -* src/ --- main C++ source code, containing the following modules: - * algebra/ --- fields and elliptic curve groups - * common/ --- miscellaneous utilities - * gadgetlib1/ --- gadgetlib1, a library to construct R1CS instances - * gadgets/ --- basic gadgets for gadgetlib1 - * gadgetlib2/ --- gadgetlib2, a library to construct R1CS instances - * qap/ --- quadratic arithmetic program - * domains/ --- support for fast interpolation/evaluation, by providing - FFTs and Lagrange-coefficient computations for various domains - * relations/ --- interfaces for expressing statement (relations between instances and witnesses) as various NP-complete languages - * constraint_satisfaction_problems/ --- R1CS and USCS languages - * circuit_satisfaction_problems/ --- Boolean and arithmetic circuit satisfiability languages - * ram_computations/ --- RAM computation languages - * zk_proof_systems --- interfaces and implementations of the proof systems - * reductions --- reductions between languages (used internally, but contains many examples of building constraints) - - Some of these module directories have the following subdirectories: - - * ... - * examples/ --- example code and tutorials for this module - * tests/ --- unit tests for this module - - In particular, the top-level API examples are at `src/r1cs_ppzksnark/examples/` and `src/gadgetlib2/examples/`. - -* depsrc/ --- created by `prepare_depends.sh` for retrieved sourcecode and local builds of external code - (currently: \[ate-pairing], and its dependency xbyak). - -* depinst/ --- created by `prepare_depends.sh` and `Makefile` - for local installation of locally-compiled dependencies. - -* doxygen/ --- created by `make doxy` and contains a Doxygen summary of all files, classes etc. in libsnark. - - --------------------------------------------------------------------------------- -Further considerations --------------------------------------------------------------------------------- - -### Multiexponentiation window size - -The ppzkSNARK's generator has to solve a fixed-base multi-exponentiation -problem. We use a window-based method in which the optimal window size depends -on the size of the multiexponentiation instance *and* the platform. - -On our benchmarking platform (a 3.40 GHz Intel Core i7-4770 CPU), we have -computed for each curve optimal windows, provided as -"fixed_base_exp_window_table" initialization sequences, for each curve; see -`X_init.cpp` for X=edwards,bn128,alt_bn128. - -Performance on other platforms may not be optimal (but probably not be far off). -Future releases of the libsnark library will include a tool that generates -optimal window sizes. - - --------------------------------------------------------------------------------- -References --------------------------------------------------------------------------------- - -\[BBFR15] [ - _ADSNARK: nearly practical and privacy-preserving proofs on authenticated data_ -](https://eprint.iacr.org/2014/617), - Michael Backes, Manuel Barbosa, Dario Fiore, Raphael M. Reischuk, - IEEE Symposium on Security and Privacy (Oakland) 2015 - -\[BCCT12] [ - _From extractable collision resistance to succinct non-Interactive arguments of knowledge, and back again_ -](http://eprint.iacr.org/2011/443), - Nir Bitansky, Ran Canetti, Alessandro Chiesa, Eran Tromer, - Innovations in Computer Science (ITCS) 2012 - -\[BCCT13] [ - _Recursive composition and bootstrapping for SNARKs and proof-carrying data_ -](http://eprint.iacr.org/2012/095) - Nir Bitansky, Ran Canetti, Alessandro Chiesa, Eran Tromer, - Symposium on Theory of Computing (STOC) 13 - -\[BCGTV13] [ - _SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge_ -](http://eprint.iacr.org/2013/507), - Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, Madars Virza, - CRYPTO 2013 - -\[BCIOP13] [ - _Succinct Non-Interactive Arguments via Linear Interactive Proofs_ -](http://eprint.iacr.org/2012/718), - Nir Bitansky, Alessandro Chiesa, Yuval Ishai, Rafail Ostrovsky, Omer Paneth, - Theory of Cryptography Conference 2013 - -\[BCTV14a] [ - _Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture_ -](http://eprint.iacr.org/2013/879), - Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, - USENIX Security 2014 - -\[BCTV14b] [ - _Scalable succinct non-interactive arguments via cycles of elliptic curves_ -](https://eprint.iacr.org/2014/595), - Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, - CRYPTO 2014 - -\[CTV15] [ - _Cluster computing in zero knowledge_ -](https://eprint.iacr.org/2015/377), - Alessandro Chiesa, Eran Tromer, Madars Virza, - Eurocrypt 2015 - -\[DFGK14] [ - Square span programs with applications to succinct NIZK arguments -](https://eprint.iacr.org/2014/718), - George Danezis, Cedric Fournet, Jens Groth, Markulf Kohlweiss, - ASIACCS 2014 - -\[GGPR13] [ - _Quadratic span programs and succinct NIZKs without PCPs_ -](http://eprint.iacr.org/2012/215), - Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, - EUROCRYPT 2013 - -\[ate-pairing] [ - _High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves_ -](https://github.com/herumi/ate-pairing), - MITSUNARI Shigeo, TERUYA Tadanori - -\[PGHR13] [ - _Pinocchio: Nearly Practical Verifiable Computation_ -](http://eprint.iacr.org/2013/279), - Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova, - IEEE Symposium on Security and Privacy (Oakland) 2013 - -[SCIPR Lab]: http://www.scipr-lab.org/ (Succinct Computational Integrity and Privacy Research Lab) - -[LICENSE]: LICENSE (LICENSE file in top directory of libsnark distribution) - -[AUTHORS]: AUTHORS (AUTHORS file in top directory of libsnark distribution) diff --git a/src/snark/doxygen.conf b/src/snark/doxygen.conf deleted file mode 100644 index 5fbe61681..000000000 --- a/src/snark/doxygen.conf +++ /dev/null @@ -1,1807 +0,0 @@ -# Doxyfile 1.8.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = libsnark - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. - -STRIP_FROM_PATH = src - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. - -EXTENSION_MAPPING = tcc=C++ - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented classes, -# or namespaces to their corresponding documentation. Such a link can be -# prevented in individual cases by by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = src README.md - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.md *.c *.h *.cpp *.hpp *.tcc *.inc *.cc - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = Debug \ - Release - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = "perl -pe 's/^(libsnark: .*)$/$1 {#mainpage}/ if $.==1; s!//+ *(TODO|FIXME|XXX)!/// \\todo!'" - # The 1st replacement marks README.md as the main page. - # The 2nd replacement identifies additional TODO notations. - # These should be done with FILTER_PATTERNS instead, but it looks like shell escaping is different there. - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = YES - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. - -STRIP_CODE_COMMENTS = NO - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = doxygen - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. - -HTML_INDEX_NUM_ENTRIES = 0 - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = YES - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = amsfonts - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which -# doxygen is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = NO - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - -UML_LIMIT_NUM_FIELDS = 10 - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp deleted file mode 100644 index 7f329d659..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp +++ /dev/null @@ -1,525 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -#ifdef PROFILE_OP_COUNTS -int64_t alt_bn128_G1::add_cnt = 0; -int64_t alt_bn128_G1::dbl_cnt = 0; -#endif - -std::vector alt_bn128_G1::wnaf_window_table; -std::vector alt_bn128_G1::fixed_base_exp_window_table; -alt_bn128_G1 alt_bn128_G1::G1_zero; -alt_bn128_G1 alt_bn128_G1::G1_one; - -alt_bn128_G1::alt_bn128_G1() -{ - this->X = G1_zero.X; - this->Y = G1_zero.Y; - this->Z = G1_zero.Z; -} - -void alt_bn128_G1::print() const -{ - if (this->is_zero()) - { - printf("O\n"); - } - else - { - alt_bn128_G1 copy(*this); - copy.to_affine_coordinates(); - gmp_printf("(%Nd , %Nd)\n", - copy.X.as_bigint().data, alt_bn128_Fq::num_limbs, - copy.Y.as_bigint().data, alt_bn128_Fq::num_limbs); - } -} - -void alt_bn128_G1::print_coordinates() const -{ - if (this->is_zero()) - { - printf("O\n"); - } - else - { - gmp_printf("(%Nd : %Nd : %Nd)\n", - this->X.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Y.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Z.as_bigint().data, alt_bn128_Fq::num_limbs); - } -} - -void alt_bn128_G1::to_affine_coordinates() -{ - if (this->is_zero()) - { - this->X = alt_bn128_Fq::zero(); - this->Y = alt_bn128_Fq::one(); - this->Z = alt_bn128_Fq::zero(); - } - else - { - alt_bn128_Fq Z_inv = Z.inverse(); - alt_bn128_Fq Z2_inv = Z_inv.squared(); - alt_bn128_Fq Z3_inv = Z2_inv * Z_inv; - this->X = this->X * Z2_inv; - this->Y = this->Y * Z3_inv; - this->Z = alt_bn128_Fq::one(); - } -} - -void alt_bn128_G1::to_special() -{ - this->to_affine_coordinates(); -} - -bool alt_bn128_G1::is_special() const -{ - return (this->is_zero() || this->Z == alt_bn128_Fq::one()); -} - -bool alt_bn128_G1::is_zero() const -{ - return (this->Z.is_zero()); -} - -bool alt_bn128_G1::operator==(const alt_bn128_G1 &other) const -{ - if (this->is_zero()) - { - return other.is_zero(); - } - - if (other.is_zero()) - { - return false; - } - - /* now neither is O */ - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - alt_bn128_Fq Z1_squared = (this->Z).squared(); - alt_bn128_Fq Z2_squared = (other.Z).squared(); - - if ((this->X * Z2_squared) != (other.X * Z1_squared)) - { - return false; - } - - alt_bn128_Fq Z1_cubed = (this->Z) * Z1_squared; - alt_bn128_Fq Z2_cubed = (other.Z) * Z2_squared; - - if ((this->Y * Z2_cubed) != (other.Y * Z1_cubed)) - { - return false; - } - - return true; -} - -bool alt_bn128_G1::operator!=(const alt_bn128_G1& other) const -{ - return !(operator==(other)); -} - -alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const -{ - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - alt_bn128_Fq Z1Z1 = (this->Z).squared(); - alt_bn128_Fq Z2Z2 = (other.Z).squared(); - - alt_bn128_Fq U1 = this->X * Z2Z2; - alt_bn128_Fq U2 = other.X * Z1Z1; - - alt_bn128_Fq Z1_cubed = (this->Z) * Z1Z1; - alt_bn128_Fq Z2_cubed = (other.Z) * Z2Z2; - - alt_bn128_Fq S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 - - if (U1 == U2 && S1 == S2) - { - // dbl case; nothing of above can be reused - return this->dbl(); - } - - // rest of add case - alt_bn128_Fq H = U2 - U1; // H = U2-U1 - alt_bn128_Fq S2_minus_S1 = S2-S1; - alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq J = H * I; // J = H * I - alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq V = U1 * I; // V = U1 * I - alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq S1_J = S1 * J; - alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G1(X3, Y3, Z3); -} - -alt_bn128_G1 alt_bn128_G1::operator-() const -{ - return alt_bn128_G1(this->X, -(this->Y), this->Z); -} - - -alt_bn128_G1 alt_bn128_G1::operator-(const alt_bn128_G1 &other) const -{ - return (*this) + (-other); -} - -alt_bn128_G1 alt_bn128_G1::add(const alt_bn128_G1 &other) const -{ - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // handle double case - if (this->operator==(other)) - { - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl - - alt_bn128_Fq Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 - alt_bn128_Fq Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 - alt_bn128_Fq U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 - alt_bn128_Fq U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 - alt_bn128_Fq S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 - alt_bn128_Fq H = U2 - U1; // H = U2-U1 - alt_bn128_Fq S2_minus_S1 = S2-S1; - alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq J = H * I; // J = H * I - alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq V = U1 * I; // V = U1 * I - alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq S1_J = S1 * J; - alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G1(X3, Y3, Z3); -} - -alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const -{ -#ifdef DEBUG - assert_except(other.is_special()); -#endif - - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - // we know that Z2 = 1 - - const alt_bn128_Fq Z1Z1 = (this->Z).squared(); - - const alt_bn128_Fq &U1 = this->X; - const alt_bn128_Fq U2 = other.X * Z1Z1; - - const alt_bn128_Fq Z1_cubed = (this->Z) * Z1Z1; - - const alt_bn128_Fq &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 - const alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 - - if (U1 == U2 && S1 == S2) - { - // dbl case; nothing of above can be reused - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl - alt_bn128_Fq H = U2-(this->X); // H = U2-X1 - alt_bn128_Fq HH = H.squared() ; // HH = H&2 - alt_bn128_Fq I = HH+HH; // I = 4*HH - I = I + I; - alt_bn128_Fq J = H*I; // J = H*I - alt_bn128_Fq r = S2-(this->Y); // r = 2*(S2-Y1) - r = r + r; - alt_bn128_Fq V = (this->X) * I ; // V = X1*I - alt_bn128_Fq X3 = r.squared()-J-V-V; // X3 = r^2-J-2*V - alt_bn128_Fq Y3 = (this->Y)*J; // Y3 = r*(V-X3)-2*Y1*J - Y3 = r*(V-X3) - Y3 - Y3; - alt_bn128_Fq Z3 = ((this->Z)+H).squared() - Z1Z1 - HH; // Z3 = (Z1+H)^2-Z1Z1-HH - - return alt_bn128_G1(X3, Y3, Z3); -} - -alt_bn128_G1 alt_bn128_G1::dbl() const -{ -#ifdef PROFILE_OP_COUNTS - this->dbl_cnt++; -#endif - // handle point at infinity - if (this->is_zero()) - { - return (*this); - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - - alt_bn128_Fq A = (this->X).squared(); // A = X1^2 - alt_bn128_Fq B = (this->Y).squared(); // B = Y1^2 - alt_bn128_Fq C = B.squared(); // C = B^2 - alt_bn128_Fq D = (this->X + B).squared() - A - C; - D = D+D; // D = 2 * ((X1 + B)^2 - A - C) - alt_bn128_Fq E = A + A + A; // E = 3 * A - alt_bn128_Fq F = E.squared(); // F = E^2 - alt_bn128_Fq X3 = F - (D+D); // X3 = F - 2 D - alt_bn128_Fq eightC = C+C; - eightC = eightC + eightC; - eightC = eightC + eightC; - alt_bn128_Fq Y3 = E * (D - X3) - eightC; // Y3 = E * (D - X3) - 8 * C - alt_bn128_Fq Y1Z1 = (this->Y)*(this->Z); - alt_bn128_Fq Z3 = Y1Z1 + Y1Z1; // Z3 = 2 * Y1 * Z1 - - return alt_bn128_G1(X3, Y3, Z3); -} - -bool alt_bn128_G1::is_well_formed() const -{ - if (this->is_zero()) - { - return true; - } - else - { - /* - y^2 = x^3 + b - - We are using Jacobian coordinates, so equation we need to check is actually - - (y/z^3)^2 = (x/z^2)^3 + b - y^2 / z^6 = x^3 / z^6 + b - y^2 = x^3 + b z^6 - */ - alt_bn128_Fq X2 = this->X.squared(); - alt_bn128_Fq Y2 = this->Y.squared(); - alt_bn128_Fq Z2 = this->Z.squared(); - - alt_bn128_Fq X3 = this->X * X2; - alt_bn128_Fq Z3 = this->Z * Z2; - alt_bn128_Fq Z6 = Z3.squared(); - - return (Y2 == X3 + alt_bn128_coeff_b * Z6); - } -} - -alt_bn128_G1 alt_bn128_G1::zero() -{ - return G1_zero; -} - -alt_bn128_G1 alt_bn128_G1::one() -{ - return G1_one; -} - -alt_bn128_G1 alt_bn128_G1::random_element() -{ - return (scalar_field::random_element().as_bigint()) * G1_one; -} - -std::ostream& operator<<(std::ostream &out, const alt_bn128_G1 &g) -{ - alt_bn128_G1 copy(g); - copy.to_affine_coordinates(); - - out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR; -#ifdef NO_PT_COMPRESSION - out << copy.X << OUTPUT_SEPARATOR << copy.Y; -#else - /* storing LSB of Y */ - out << copy.X << OUTPUT_SEPARATOR << (copy.Y.as_bigint().data[0] & 1); -#endif - - return out; -} - -std::istream& operator>>(std::istream &in, alt_bn128_G1 &g) -{ - char is_zero; - alt_bn128_Fq tX, tY; - -#ifdef NO_PT_COMPRESSION - in >> is_zero >> tX >> tY; - is_zero -= '0'; -#else - in.read((char*)&is_zero, 1); // this reads is_zero; - is_zero -= '0'; - consume_OUTPUT_SEPARATOR(in); - - unsigned char Y_lsb; - in >> tX; - consume_OUTPUT_SEPARATOR(in); - in.read((char*)&Y_lsb, 1); - Y_lsb -= '0'; - - // y = +/- sqrt(x^3 + b) - if (!is_zero) - { - alt_bn128_Fq tX2 = tX.squared(); - alt_bn128_Fq tY2 = tX2*tX + alt_bn128_coeff_b; - tY = tY2.sqrt(); - - if ((tY.as_bigint().data[0] & 1) != Y_lsb) - { - tY = -tY; - } - } -#endif - // using Jacobian coordinates - if (!is_zero) - { - g.X = tX; - g.Y = tY; - g.Z = alt_bn128_Fq::one(); - } - else - { - g = alt_bn128_G1::zero(); - } - - return in; -} - -std::ostream& operator<<(std::ostream& out, const std::vector &v) -{ - out << v.size() << "\n"; - for (const alt_bn128_G1& t : v) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -std::istream& operator>>(std::istream& in, std::vector &v) -{ - v.clear(); - - size_t s; - in >> s; - consume_newline(in); - - v.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - alt_bn128_G1 g; - in >> g; - consume_OUTPUT_NEWLINE(in); - v.emplace_back(g); - } - - return in; -} - -template<> -void batch_to_special_all_non_zeros(std::vector &vec) -{ - std::vector Z_vec; - Z_vec.reserve(vec.size()); - - for (auto &el: vec) - { - Z_vec.emplace_back(el.Z); - } - batch_invert(Z_vec); - - const alt_bn128_Fq one = alt_bn128_Fq::one(); - - for (size_t i = 0; i < vec.size(); ++i) - { - alt_bn128_Fq Z2 = Z_vec[i].squared(); - alt_bn128_Fq Z3 = Z_vec[i] * Z2; - - vec[i].X = vec[i].X * Z2; - vec[i].Y = vec[i].Y * Z3; - vec[i].Z = one; - } -} - -} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp deleted file mode 100644 index 567f2fa3f..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ALT_BN128_G1_HPP_ -#define ALT_BN128_G1_HPP_ -#include -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" -#include "algebra/curves/curve_utils.hpp" - -namespace libsnark { - -class alt_bn128_G1; -std::ostream& operator<<(std::ostream &, const alt_bn128_G1&); -std::istream& operator>>(std::istream &, alt_bn128_G1&); - -class alt_bn128_G1 { -public: -#ifdef PROFILE_OP_COUNTS - static int64_t add_cnt; - static int64_t dbl_cnt; -#endif - static std::vector wnaf_window_table; - static std::vector fixed_base_exp_window_table; - static alt_bn128_G1 G1_zero; - static alt_bn128_G1 G1_one; - - typedef alt_bn128_Fq base_field; - typedef alt_bn128_Fr scalar_field; - - alt_bn128_Fq X, Y, Z; - - // using Jacobian coordinates - alt_bn128_G1(); - alt_bn128_G1(const alt_bn128_Fq& X, const alt_bn128_Fq& Y, const alt_bn128_Fq& Z) : X(X), Y(Y), Z(Z) {}; - - void print() const; - void print_coordinates() const; - - void to_affine_coordinates(); - void to_special(); - bool is_special() const; - - bool is_zero() const; - - bool operator==(const alt_bn128_G1 &other) const; - bool operator!=(const alt_bn128_G1 &other) const; - - alt_bn128_G1 operator+(const alt_bn128_G1 &other) const; - alt_bn128_G1 operator-() const; - alt_bn128_G1 operator-(const alt_bn128_G1 &other) const; - - alt_bn128_G1 add(const alt_bn128_G1 &other) const; - alt_bn128_G1 mixed_add(const alt_bn128_G1 &other) const; - alt_bn128_G1 dbl() const; - - bool is_well_formed() const; - - static alt_bn128_G1 zero(); - static alt_bn128_G1 one(); - static alt_bn128_G1 random_element(); - - static size_t size_in_bits() { return base_field::size_in_bits() + 1; } - static bigint base_field_char() { return base_field::field_char(); } - static bigint order() { return scalar_field::field_char(); } - - friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G1 &g); - friend std::istream& operator>>(std::istream &in, alt_bn128_G1 &g); -}; - -template -alt_bn128_G1 operator*(const bigint &lhs, const alt_bn128_G1 &rhs) -{ - return scalar_mul(rhs, lhs); -} - -template& modulus_p> -alt_bn128_G1 operator*(const Fp_model &lhs, const alt_bn128_G1 &rhs) -{ - return scalar_mul(rhs, lhs.as_bigint()); -} - -std::ostream& operator<<(std::ostream& out, const std::vector &v); -std::istream& operator>>(std::istream& in, std::vector &v); - -template -void batch_to_special_all_non_zeros(std::vector &vec); -template<> -void batch_to_special_all_non_zeros(std::vector &vec); - -} // libsnark -#endif // ALT_BN128_G1_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp deleted file mode 100644 index 98f471044..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -#ifdef PROFILE_OP_COUNTS -int64_t alt_bn128_G2::add_cnt = 0; -int64_t alt_bn128_G2::dbl_cnt = 0; -#endif - -std::vector alt_bn128_G2::wnaf_window_table; -std::vector alt_bn128_G2::fixed_base_exp_window_table; -alt_bn128_G2 alt_bn128_G2::G2_zero; -alt_bn128_G2 alt_bn128_G2::G2_one; - -alt_bn128_G2::alt_bn128_G2() -{ - this->X = G2_zero.X; - this->Y = G2_zero.Y; - this->Z = G2_zero.Z; -} - -alt_bn128_Fq2 alt_bn128_G2::mul_by_b(const alt_bn128_Fq2 &elt) -{ - return alt_bn128_Fq2(alt_bn128_twist_mul_by_b_c0 * elt.c0, alt_bn128_twist_mul_by_b_c1 * elt.c1); -} - -void alt_bn128_G2::print() const -{ - if (this->is_zero()) - { - printf("O\n"); - } - else - { - alt_bn128_G2 copy(*this); - copy.to_affine_coordinates(); - gmp_printf("(%Nd*z + %Nd , %Nd*z + %Nd)\n", - copy.X.c1.as_bigint().data, alt_bn128_Fq::num_limbs, - copy.X.c0.as_bigint().data, alt_bn128_Fq::num_limbs, - copy.Y.c1.as_bigint().data, alt_bn128_Fq::num_limbs, - copy.Y.c0.as_bigint().data, alt_bn128_Fq::num_limbs); - } -} - -void alt_bn128_G2::print_coordinates() const -{ - if (this->is_zero()) - { - printf("O\n"); - } - else - { - gmp_printf("(%Nd*z + %Nd : %Nd*z + %Nd : %Nd*z + %Nd)\n", - this->X.c1.as_bigint().data, alt_bn128_Fq::num_limbs, - this->X.c0.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Y.c1.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Y.c0.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Z.c1.as_bigint().data, alt_bn128_Fq::num_limbs, - this->Z.c0.as_bigint().data, alt_bn128_Fq::num_limbs); - } -} - -void alt_bn128_G2::to_affine_coordinates() -{ - if (this->is_zero()) - { - this->X = alt_bn128_Fq2::zero(); - this->Y = alt_bn128_Fq2::one(); - this->Z = alt_bn128_Fq2::zero(); - } - else - { - alt_bn128_Fq2 Z_inv = Z.inverse(); - alt_bn128_Fq2 Z2_inv = Z_inv.squared(); - alt_bn128_Fq2 Z3_inv = Z2_inv * Z_inv; - this->X = this->X * Z2_inv; - this->Y = this->Y * Z3_inv; - this->Z = alt_bn128_Fq2::one(); - } -} - -void alt_bn128_G2::to_special() -{ - this->to_affine_coordinates(); -} - -bool alt_bn128_G2::is_special() const -{ - return (this->is_zero() || this->Z == alt_bn128_Fq2::one()); -} - -bool alt_bn128_G2::is_zero() const -{ - return (this->Z.is_zero()); -} - -bool alt_bn128_G2::operator==(const alt_bn128_G2 &other) const -{ - if (this->is_zero()) - { - return other.is_zero(); - } - - if (other.is_zero()) - { - return false; - } - - /* now neither is O */ - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - alt_bn128_Fq2 Z1_squared = (this->Z).squared(); - alt_bn128_Fq2 Z2_squared = (other.Z).squared(); - - if ((this->X * Z2_squared) != (other.X * Z1_squared)) - { - return false; - } - - alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1_squared; - alt_bn128_Fq2 Z2_cubed = (other.Z) * Z2_squared; - - if ((this->Y * Z2_cubed) != (other.Y * Z1_cubed)) - { - return false; - } - - return true; -} - -bool alt_bn128_G2::operator!=(const alt_bn128_G2& other) const -{ - return !(operator==(other)); -} - -alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const -{ - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); - alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); - - alt_bn128_Fq2 U1 = this->X * Z2Z2; - alt_bn128_Fq2 U2 = other.X * Z1Z1; - - alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1Z1; - alt_bn128_Fq2 Z2_cubed = (other.Z) * Z2Z2; - - alt_bn128_Fq2 S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 - - if (U1 == U2 && S1 == S2) - { - // dbl case; nothing of above can be reused - return this->dbl(); - } - - // rest of add case - alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 - alt_bn128_Fq2 S2_minus_S1 = S2-S1; - alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq2 J = H * I; // J = H * I - alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq2 V = U1 * I; // V = U1 * I - alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq2 S1_J = S1 * J; - alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G2(X3, Y3, Z3); -} - -alt_bn128_G2 alt_bn128_G2::operator-() const -{ - return alt_bn128_G2(this->X, -(this->Y), this->Z); -} - - -alt_bn128_G2 alt_bn128_G2::operator-(const alt_bn128_G2 &other) const -{ - return (*this) + (-other); -} - -alt_bn128_G2 alt_bn128_G2::add(const alt_bn128_G2 &other) const -{ - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // handle double case - if (this->operator==(other)) - { - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2 - - alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 - alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 - alt_bn128_Fq2 U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 - alt_bn128_Fq2 U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 - alt_bn128_Fq2 S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq2 S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 - alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 - alt_bn128_Fq2 S2_minus_S1 = S2-S1; - alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq2 J = H * I; // J = H * I - alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq2 V = U1 * I; // V = U1 * I - alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq2 S1_J = S1 * J; - alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G2(X3, Y3, Z3); -} - -alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const -{ -#ifdef DEBUG - assert_except(other.is_special()); -#endif - - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) - // iff - // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 - // iff - // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - - // we know that Z2 = 1 - - const alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); - - const alt_bn128_Fq2 &U1 = this->X; - const alt_bn128_Fq2 U2 = other.X * Z1Z1; - - const alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1Z1; - - const alt_bn128_Fq2 &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 - const alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 - - if (U1 == U2 && S1 == S2) - { - // dbl case; nothing of above can be reused - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl - alt_bn128_Fq2 H = U2-(this->X); // H = U2-X1 - alt_bn128_Fq2 HH = H.squared() ; // HH = H&2 - alt_bn128_Fq2 I = HH+HH; // I = 4*HH - I = I + I; - alt_bn128_Fq2 J = H*I; // J = H*I - alt_bn128_Fq2 r = S2-(this->Y); // r = 2*(S2-Y1) - r = r + r; - alt_bn128_Fq2 V = (this->X) * I ; // V = X1*I - alt_bn128_Fq2 X3 = r.squared()-J-V-V; // X3 = r^2-J-2*V - alt_bn128_Fq2 Y3 = (this->Y)*J; // Y3 = r*(V-X3)-2*Y1*J - Y3 = r*(V-X3) - Y3 - Y3; - alt_bn128_Fq2 Z3 = ((this->Z)+H).squared() - Z1Z1 - HH; // Z3 = (Z1+H)^2-Z1Z1-HH - - return alt_bn128_G2(X3, Y3, Z3); -} - -alt_bn128_G2 alt_bn128_G2::dbl() const -{ -#ifdef PROFILE_OP_COUNTS - this->dbl_cnt++; -#endif - // handle point at infinity - if (this->is_zero()) - { - return (*this); - } - - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#doubling-dbl-2007-bl - - alt_bn128_Fq2 A = (this->X).squared(); // A = X1^2 - alt_bn128_Fq2 B = (this->Y).squared(); // B = Y1^2 - alt_bn128_Fq2 C = B.squared(); // C = B^2 - alt_bn128_Fq2 D = (this->X + B).squared() - A - C; - D = D+D; // D = 2 * ((X1 + B)^2 - A - C) - alt_bn128_Fq2 E = A + A + A; // E = 3 * A - alt_bn128_Fq2 F = E.squared(); // F = E^2 - alt_bn128_Fq2 X3 = F - (D+D); // X3 = F - 2 D - alt_bn128_Fq2 eightC = C+C; - eightC = eightC + eightC; - eightC = eightC + eightC; - alt_bn128_Fq2 Y3 = E * (D - X3) - eightC; // Y3 = E * (D - X3) - 8 * C - alt_bn128_Fq2 Y1Z1 = (this->Y)*(this->Z); - alt_bn128_Fq2 Z3 = Y1Z1 + Y1Z1; // Z3 = 2 * Y1 * Z1 - - return alt_bn128_G2(X3, Y3, Z3); -} - -alt_bn128_G2 alt_bn128_G2::mul_by_q() const -{ - return alt_bn128_G2(alt_bn128_twist_mul_by_q_X * (this->X).Frobenius_map(1), - alt_bn128_twist_mul_by_q_Y * (this->Y).Frobenius_map(1), - (this->Z).Frobenius_map(1)); -} - -bool alt_bn128_G2::is_well_formed() const -{ - if (this->is_zero()) - { - return true; - } - else - { - /* - y^2 = x^3 + b - - We are using Jacobian coordinates, so equation we need to check is actually - - (y/z^3)^2 = (x/z^2)^3 + b - y^2 / z^6 = x^3 / z^6 + b - y^2 = x^3 + b z^6 - */ - alt_bn128_Fq2 X2 = this->X.squared(); - alt_bn128_Fq2 Y2 = this->Y.squared(); - alt_bn128_Fq2 Z2 = this->Z.squared(); - - alt_bn128_Fq2 X3 = this->X * X2; - alt_bn128_Fq2 Z3 = this->Z * Z2; - alt_bn128_Fq2 Z6 = Z3.squared(); - - return (Y2 == X3 + alt_bn128_twist_coeff_b * Z6); - } -} - -alt_bn128_G2 alt_bn128_G2::zero() -{ - return G2_zero; -} - -alt_bn128_G2 alt_bn128_G2::one() -{ - return G2_one; -} - -alt_bn128_G2 alt_bn128_G2::random_element() -{ - return (alt_bn128_Fr::random_element().as_bigint()) * G2_one; -} - -std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g) -{ - alt_bn128_G2 copy(g); - copy.to_affine_coordinates(); - out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR; -#ifdef NO_PT_COMPRESSION - out << copy.X << OUTPUT_SEPARATOR << copy.Y; -#else - /* storing LSB of Y */ - out << copy.X << OUTPUT_SEPARATOR << (copy.Y.c0.as_bigint().data[0] & 1); -#endif - - return out; -} - -std::istream& operator>>(std::istream &in, alt_bn128_G2 &g) -{ - char is_zero; - alt_bn128_Fq2 tX, tY; - -#ifdef NO_PT_COMPRESSION - in >> is_zero >> tX >> tY; - is_zero -= '0'; -#else - in.read((char*)&is_zero, 1); // this reads is_zero; - is_zero -= '0'; - consume_OUTPUT_SEPARATOR(in); - - unsigned char Y_lsb; - in >> tX; - consume_OUTPUT_SEPARATOR(in); - in.read((char*)&Y_lsb, 1); - Y_lsb -= '0'; - - // y = +/- sqrt(x^3 + b) - if (!is_zero) - { - alt_bn128_Fq2 tX2 = tX.squared(); - alt_bn128_Fq2 tY2 = tX2 * tX + alt_bn128_twist_coeff_b; - tY = tY2.sqrt(); - - if ((tY.c0.as_bigint().data[0] & 1) != Y_lsb) - { - tY = -tY; - } - } -#endif - // using projective coordinates - if (!is_zero) - { - g.X = tX; - g.Y = tY; - g.Z = alt_bn128_Fq2::one(); - } - else - { - g = alt_bn128_G2::zero(); - } - - return in; -} - -template<> -void batch_to_special_all_non_zeros(std::vector &vec) -{ - std::vector Z_vec; - Z_vec.reserve(vec.size()); - - for (auto &el: vec) - { - Z_vec.emplace_back(el.Z); - } - batch_invert(Z_vec); - - const alt_bn128_Fq2 one = alt_bn128_Fq2::one(); - - for (size_t i = 0; i < vec.size(); ++i) - { - alt_bn128_Fq2 Z2 = Z_vec[i].squared(); - alt_bn128_Fq2 Z3 = Z_vec[i] * Z2; - - vec[i].X = vec[i].X * Z2; - vec[i].Y = vec[i].Y * Z3; - vec[i].Z = one; - } -} - -} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp deleted file mode 100644 index 57bad1a4b..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ALT_BN128_G2_HPP_ -#define ALT_BN128_G2_HPP_ -#include -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" -#include "algebra/curves/curve_utils.hpp" - -namespace libsnark { - -class alt_bn128_G2; -std::ostream& operator<<(std::ostream &, const alt_bn128_G2&); -std::istream& operator>>(std::istream &, alt_bn128_G2&); - -class alt_bn128_G2 { -public: -#ifdef PROFILE_OP_COUNTS - static int64_t add_cnt; - static int64_t dbl_cnt; -#endif - static std::vector wnaf_window_table; - static std::vector fixed_base_exp_window_table; - static alt_bn128_G2 G2_zero; - static alt_bn128_G2 G2_one; - - typedef alt_bn128_Fq base_field; - typedef alt_bn128_Fq2 twist_field; - typedef alt_bn128_Fr scalar_field; - - alt_bn128_Fq2 X, Y, Z; - - // using Jacobian coordinates - alt_bn128_G2(); - alt_bn128_G2(const alt_bn128_Fq2& X, const alt_bn128_Fq2& Y, const alt_bn128_Fq2& Z) : X(X), Y(Y), Z(Z) {}; - - static alt_bn128_Fq2 mul_by_b(const alt_bn128_Fq2 &elt); - - void print() const; - void print_coordinates() const; - - void to_affine_coordinates(); - void to_special(); - bool is_special() const; - - bool is_zero() const; - - bool operator==(const alt_bn128_G2 &other) const; - bool operator!=(const alt_bn128_G2 &other) const; - - alt_bn128_G2 operator+(const alt_bn128_G2 &other) const; - alt_bn128_G2 operator-() const; - alt_bn128_G2 operator-(const alt_bn128_G2 &other) const; - - alt_bn128_G2 add(const alt_bn128_G2 &other) const; - alt_bn128_G2 mixed_add(const alt_bn128_G2 &other) const; - alt_bn128_G2 dbl() const; - alt_bn128_G2 mul_by_q() const; - - bool is_well_formed() const; - - static alt_bn128_G2 zero(); - static alt_bn128_G2 one(); - static alt_bn128_G2 random_element(); - - static size_t size_in_bits() { return twist_field::size_in_bits() + 1; } - static bigint base_field_char() { return base_field::field_char(); } - static bigint order() { return scalar_field::field_char(); } - - friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g); - friend std::istream& operator>>(std::istream &in, alt_bn128_G2 &g); -}; - -template -alt_bn128_G2 operator*(const bigint &lhs, const alt_bn128_G2 &rhs) -{ - return scalar_mul(rhs, lhs); -} - -template& modulus_p> -alt_bn128_G2 operator*(const Fp_model &lhs, const alt_bn128_G2 &rhs) -{ - return scalar_mul(rhs, lhs.as_bigint()); -} - -template -void batch_to_special_all_non_zeros(std::vector &vec); -template<> -void batch_to_special_all_non_zeros(std::vector &vec); - -} // libsnark -#endif // ALT_BN128_G2_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp deleted file mode 100644 index 7c23773d6..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" - -namespace libsnark { - -bigint alt_bn128_modulus_r; -bigint alt_bn128_modulus_q; - -alt_bn128_Fq alt_bn128_coeff_b; -alt_bn128_Fq2 alt_bn128_twist; -alt_bn128_Fq2 alt_bn128_twist_coeff_b; -alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; -alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; -alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X; -alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y; - -bigint alt_bn128_ate_loop_count; -bool alt_bn128_ate_is_loop_count_neg; -bigint<12*alt_bn128_q_limbs> alt_bn128_final_exponent; -bigint alt_bn128_final_exponent_z; -bool alt_bn128_final_exponent_is_z_neg; - -void init_alt_bn128_params() -{ - typedef bigint bigint_r; - typedef bigint bigint_q; - - assert(sizeof(mp_limb_t) == 8 || sizeof(mp_limb_t) == 4); // Montgomery assumes this - - /* parameters for scalar field Fr */ - - alt_bn128_modulus_r = bigint_r("21888242871839275222246405745257275088548364400416034343698204186575808495617"); - assert(alt_bn128_Fr::modulus_is_valid()); - if (sizeof(mp_limb_t) == 8) - { - alt_bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); - alt_bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); - alt_bn128_Fr::inv = 0xc2e1f593efffffff; - } - if (sizeof(mp_limb_t) == 4) - { - alt_bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); - alt_bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); - alt_bn128_Fr::inv = 0xefffffff; - } - alt_bn128_Fr::num_bits = 254; - alt_bn128_Fr::euler = bigint_r("10944121435919637611123202872628637544274182200208017171849102093287904247808"); - alt_bn128_Fr::s = 28; - alt_bn128_Fr::t = bigint_r("81540058820840996586704275553141814055101440848469862132140264610111"); - alt_bn128_Fr::t_minus_1_over_2 = bigint_r("40770029410420498293352137776570907027550720424234931066070132305055"); - alt_bn128_Fr::multiplicative_generator = alt_bn128_Fr("5"); - alt_bn128_Fr::root_of_unity = alt_bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); - alt_bn128_Fr::nqr = alt_bn128_Fr("5"); - alt_bn128_Fr::nqr_to_t = alt_bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); - - /* parameters for base field Fq */ - - alt_bn128_modulus_q = bigint_q("21888242871839275222246405745257275088696311157297823662689037894645226208583"); - assert(alt_bn128_Fq::modulus_is_valid()); - if (sizeof(mp_limb_t) == 8) - { - alt_bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); - alt_bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); - alt_bn128_Fq::inv = 0x87d20782e4866389; - } - if (sizeof(mp_limb_t) == 4) - { - alt_bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); - alt_bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); - alt_bn128_Fq::inv = 0xe4866389; - } - alt_bn128_Fq::num_bits = 254; - alt_bn128_Fq::euler = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); - alt_bn128_Fq::s = 1; - alt_bn128_Fq::t = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); - alt_bn128_Fq::t_minus_1_over_2 = bigint_q("5472060717959818805561601436314318772174077789324455915672259473661306552145"); - alt_bn128_Fq::multiplicative_generator = alt_bn128_Fq("3"); - alt_bn128_Fq::root_of_unity = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - alt_bn128_Fq::nqr = alt_bn128_Fq("3"); - alt_bn128_Fq::nqr_to_t = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - - /* parameters for twist field Fq2 */ - alt_bn128_Fq2::euler = bigint<2*alt_bn128_q_limbs>("239547588008311421220994022608339370399626158265550411218223901127035046843189118723920525909718935985594116157406550130918127817069793474323196511433944"); - alt_bn128_Fq2::s = 4; - alt_bn128_Fq2::t = bigint<2*alt_bn128_q_limbs>("29943448501038927652624252826042421299953269783193801402277987640879380855398639840490065738714866998199264519675818766364765977133724184290399563929243"); - alt_bn128_Fq2::t_minus_1_over_2 = bigint<2*alt_bn128_q_limbs>("14971724250519463826312126413021210649976634891596900701138993820439690427699319920245032869357433499099632259837909383182382988566862092145199781964621"); - alt_bn128_Fq2::non_residue = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - alt_bn128_Fq2::nqr = alt_bn128_Fq2(alt_bn128_Fq("2"),alt_bn128_Fq("1")); - alt_bn128_Fq2::nqr_to_t = alt_bn128_Fq2(alt_bn128_Fq("5033503716262624267312492558379982687175200734934877598599011485707452665730"),alt_bn128_Fq("314498342015008975724433667930697407966947188435857772134235984660852259084")); - alt_bn128_Fq2::Frobenius_coeffs_c1[0] = alt_bn128_Fq("1"); - alt_bn128_Fq2::Frobenius_coeffs_c1[1] = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - - /* parameters for Fq6 */ - alt_bn128_Fq6::non_residue = alt_bn128_Fq2(alt_bn128_Fq("9"),alt_bn128_Fq("1")); - alt_bn128_Fq6::Frobenius_coeffs_c1[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c1[1] = alt_bn128_Fq2(alt_bn128_Fq("21575463638280843010398324269430826099269044274347216827212613867836435027261"),alt_bn128_Fq("10307601595873709700152284273816112264069230130616436755625194854815875713954")); - alt_bn128_Fq6::Frobenius_coeffs_c1[2] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c1[3] = alt_bn128_Fq2(alt_bn128_Fq("3772000881919853776433695186713858239009073593817195771773381919316419345261"),alt_bn128_Fq("2236595495967245188281701248203181795121068902605861227855261137820944008926")); - alt_bn128_Fq6::Frobenius_coeffs_c1[4] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c1[5] = alt_bn128_Fq2(alt_bn128_Fq("18429021223477853657660792034369865839114504446431234726392080002137598044644"),alt_bn128_Fq("9344045779998320333812420223237981029506012124075525679208581902008406485703")); - alt_bn128_Fq6::Frobenius_coeffs_c2[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c2[1] = alt_bn128_Fq2(alt_bn128_Fq("2581911344467009335267311115468803099551665605076196740867805258568234346338"),alt_bn128_Fq("19937756971775647987995932169929341994314640652964949448313374472400716661030")); - alt_bn128_Fq6::Frobenius_coeffs_c2[2] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c2[3] = alt_bn128_Fq2(alt_bn128_Fq("5324479202449903542726783395506214481928257762400643279780343368557297135718"),alt_bn128_Fq("16208900380737693084919495127334387981393726419856888799917914180988844123039")); - alt_bn128_Fq6::Frobenius_coeffs_c2[4] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); - alt_bn128_Fq6::Frobenius_coeffs_c2[5] = alt_bn128_Fq2(alt_bn128_Fq("13981852324922362344252311234282257507216387789820983642040889267519694726527"),alt_bn128_Fq("7629828391165209371577384193250820201684255241773809077146787135900891633097")); - - /* parameters for Fq12 */ - - alt_bn128_Fq12::non_residue = alt_bn128_Fq2(alt_bn128_Fq("9"),alt_bn128_Fq("1")); - alt_bn128_Fq12::Frobenius_coeffs_c1[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[1] = alt_bn128_Fq2(alt_bn128_Fq("8376118865763821496583973867626364092589906065868298776909617916018768340080"),alt_bn128_Fq("16469823323077808223889137241176536799009286646108169935659301613961712198316")); - alt_bn128_Fq12::Frobenius_coeffs_c1[2] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556617"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[3] = alt_bn128_Fq2(alt_bn128_Fq("11697423496358154304825782922584725312912383441159505038794027105778954184319"),alt_bn128_Fq("303847389135065887422783454877609941456349188919719272345083954437860409601")); - alt_bn128_Fq12::Frobenius_coeffs_c1[4] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[5] = alt_bn128_Fq2(alt_bn128_Fq("3321304630594332808241809054958361220322477375291206261884409189760185844239"),alt_bn128_Fq("5722266937896532885780051958958348231143373700109372999374820235121374419868")); - alt_bn128_Fq12::Frobenius_coeffs_c1[6] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[7] = alt_bn128_Fq2(alt_bn128_Fq("13512124006075453725662431877630910996106405091429524885779419978626457868503"),alt_bn128_Fq("5418419548761466998357268504080738289687024511189653727029736280683514010267")); - alt_bn128_Fq12::Frobenius_coeffs_c1[8] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[9] = alt_bn128_Fq2(alt_bn128_Fq("10190819375481120917420622822672549775783927716138318623895010788866272024264"),alt_bn128_Fq("21584395482704209334823622290379665147239961968378104390343953940207365798982")); - alt_bn128_Fq12::Frobenius_coeffs_c1[10] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651967"),alt_bn128_Fq("0")); - alt_bn128_Fq12::Frobenius_coeffs_c1[11] = alt_bn128_Fq2(alt_bn128_Fq("18566938241244942414004596690298913868373833782006617400804628704885040364344"),alt_bn128_Fq("16165975933942742336466353786298926857552937457188450663314217659523851788715")); - - /* choice of short Weierstrass curve and its twist */ - - alt_bn128_coeff_b = alt_bn128_Fq("3"); - alt_bn128_twist = alt_bn128_Fq2(alt_bn128_Fq("9"), alt_bn128_Fq("1")); - alt_bn128_twist_coeff_b = alt_bn128_coeff_b * alt_bn128_twist.inverse(); - alt_bn128_twist_mul_by_b_c0 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue; - alt_bn128_twist_mul_by_b_c1 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue; - alt_bn128_twist_mul_by_q_X = alt_bn128_Fq2(alt_bn128_Fq("21575463638280843010398324269430826099269044274347216827212613867836435027261"), - alt_bn128_Fq("10307601595873709700152284273816112264069230130616436755625194854815875713954")); - alt_bn128_twist_mul_by_q_Y = alt_bn128_Fq2(alt_bn128_Fq("2821565182194536844548159561693502659359617185244120367078079554186484126554"), - alt_bn128_Fq("3505843767911556378687030309984248845540243509899259641013678093033130930403")); - - /* choice of group G1 */ - alt_bn128_G1::G1_zero = alt_bn128_G1(alt_bn128_Fq::zero(), - alt_bn128_Fq::one(), - alt_bn128_Fq::zero()); - alt_bn128_G1::G1_one = alt_bn128_G1(alt_bn128_Fq("1"), - alt_bn128_Fq("2"), - alt_bn128_Fq::one()); - alt_bn128_G1::wnaf_window_table.push_back(11); - alt_bn128_G1::wnaf_window_table.push_back(24); - alt_bn128_G1::wnaf_window_table.push_back(60); - alt_bn128_G1::wnaf_window_table.push_back(127); - - alt_bn128_G1::fixed_base_exp_window_table.resize(0); - // window 1 is unbeaten in [-inf, 4.99] - alt_bn128_G1::fixed_base_exp_window_table.push_back(1); - // window 2 is unbeaten in [4.99, 10.99] - alt_bn128_G1::fixed_base_exp_window_table.push_back(5); - // window 3 is unbeaten in [10.99, 32.29] - alt_bn128_G1::fixed_base_exp_window_table.push_back(11); - // window 4 is unbeaten in [32.29, 55.23] - alt_bn128_G1::fixed_base_exp_window_table.push_back(32); - // window 5 is unbeaten in [55.23, 162.03] - alt_bn128_G1::fixed_base_exp_window_table.push_back(55); - // window 6 is unbeaten in [162.03, 360.15] - alt_bn128_G1::fixed_base_exp_window_table.push_back(162); - // window 7 is unbeaten in [360.15, 815.44] - alt_bn128_G1::fixed_base_exp_window_table.push_back(360); - // window 8 is unbeaten in [815.44, 2373.07] - alt_bn128_G1::fixed_base_exp_window_table.push_back(815); - // window 9 is unbeaten in [2373.07, 6977.75] - alt_bn128_G1::fixed_base_exp_window_table.push_back(2373); - // window 10 is unbeaten in [6977.75, 7122.23] - alt_bn128_G1::fixed_base_exp_window_table.push_back(6978); - // window 11 is unbeaten in [7122.23, 57818.46] - alt_bn128_G1::fixed_base_exp_window_table.push_back(7122); - // window 12 is never the best - alt_bn128_G1::fixed_base_exp_window_table.push_back(0); - // window 13 is unbeaten in [57818.46, 169679.14] - alt_bn128_G1::fixed_base_exp_window_table.push_back(57818); - // window 14 is never the best - alt_bn128_G1::fixed_base_exp_window_table.push_back(0); - // window 15 is unbeaten in [169679.14, 439758.91] - alt_bn128_G1::fixed_base_exp_window_table.push_back(169679); - // window 16 is unbeaten in [439758.91, 936073.41] - alt_bn128_G1::fixed_base_exp_window_table.push_back(439759); - // window 17 is unbeaten in [936073.41, 4666554.74] - alt_bn128_G1::fixed_base_exp_window_table.push_back(936073); - // window 18 is never the best - alt_bn128_G1::fixed_base_exp_window_table.push_back(0); - // window 19 is unbeaten in [4666554.74, 7580404.42] - alt_bn128_G1::fixed_base_exp_window_table.push_back(4666555); - // window 20 is unbeaten in [7580404.42, 34552892.20] - alt_bn128_G1::fixed_base_exp_window_table.push_back(7580404); - // window 21 is never the best - alt_bn128_G1::fixed_base_exp_window_table.push_back(0); - // window 22 is unbeaten in [34552892.20, inf] - alt_bn128_G1::fixed_base_exp_window_table.push_back(34552892); - - /* choice of group G2 */ - - alt_bn128_G2::G2_zero = alt_bn128_G2(alt_bn128_Fq2::zero(), - alt_bn128_Fq2::one(), - alt_bn128_Fq2::zero()); - - alt_bn128_G2::G2_one = alt_bn128_G2(alt_bn128_Fq2(alt_bn128_Fq("10857046999023057135944570762232829481370756359578518086990519993285655852781"), - alt_bn128_Fq("11559732032986387107991004021392285783925812861821192530917403151452391805634")), - alt_bn128_Fq2(alt_bn128_Fq("8495653923123431417604973247489272438418190587263600148770280649306958101930"), - alt_bn128_Fq("4082367875863433681332203403145435568316851327593401208105741076214120093531")), - alt_bn128_Fq2::one()); - alt_bn128_G2::wnaf_window_table.push_back(5); - alt_bn128_G2::wnaf_window_table.push_back(15); - alt_bn128_G2::wnaf_window_table.push_back(39); - alt_bn128_G2::wnaf_window_table.push_back(109); - - alt_bn128_G2::fixed_base_exp_window_table.resize(0); - // window 1 is unbeaten in [-inf, 5.10] - alt_bn128_G2::fixed_base_exp_window_table.push_back(1); - // window 2 is unbeaten in [5.10, 10.43] - alt_bn128_G2::fixed_base_exp_window_table.push_back(5); - // window 3 is unbeaten in [10.43, 25.28] - alt_bn128_G2::fixed_base_exp_window_table.push_back(10); - // window 4 is unbeaten in [25.28, 59.00] - alt_bn128_G2::fixed_base_exp_window_table.push_back(25); - // window 5 is unbeaten in [59.00, 154.03] - alt_bn128_G2::fixed_base_exp_window_table.push_back(59); - // window 6 is unbeaten in [154.03, 334.25] - alt_bn128_G2::fixed_base_exp_window_table.push_back(154); - // window 7 is unbeaten in [334.25, 742.58] - alt_bn128_G2::fixed_base_exp_window_table.push_back(334); - // window 8 is unbeaten in [742.58, 2034.40] - alt_bn128_G2::fixed_base_exp_window_table.push_back(743); - // window 9 is unbeaten in [2034.40, 4987.56] - alt_bn128_G2::fixed_base_exp_window_table.push_back(2034); - // window 10 is unbeaten in [4987.56, 8888.27] - alt_bn128_G2::fixed_base_exp_window_table.push_back(4988); - // window 11 is unbeaten in [8888.27, 26271.13] - alt_bn128_G2::fixed_base_exp_window_table.push_back(8888); - // window 12 is unbeaten in [26271.13, 39768.20] - alt_bn128_G2::fixed_base_exp_window_table.push_back(26271); - // window 13 is unbeaten in [39768.20, 106275.75] - alt_bn128_G2::fixed_base_exp_window_table.push_back(39768); - // window 14 is unbeaten in [106275.75, 141703.40] - alt_bn128_G2::fixed_base_exp_window_table.push_back(106276); - // window 15 is unbeaten in [141703.40, 462422.97] - alt_bn128_G2::fixed_base_exp_window_table.push_back(141703); - // window 16 is unbeaten in [462422.97, 926871.84] - alt_bn128_G2::fixed_base_exp_window_table.push_back(462423); - // window 17 is unbeaten in [926871.84, 4873049.17] - alt_bn128_G2::fixed_base_exp_window_table.push_back(926872); - // window 18 is never the best - alt_bn128_G2::fixed_base_exp_window_table.push_back(0); - // window 19 is unbeaten in [4873049.17, 5706707.88] - alt_bn128_G2::fixed_base_exp_window_table.push_back(4873049); - // window 20 is unbeaten in [5706707.88, 31673814.95] - alt_bn128_G2::fixed_base_exp_window_table.push_back(5706708); - // window 21 is never the best - alt_bn128_G2::fixed_base_exp_window_table.push_back(0); - // window 22 is unbeaten in [31673814.95, inf] - alt_bn128_G2::fixed_base_exp_window_table.push_back(31673815); - - /* pairing parameters */ - - alt_bn128_ate_loop_count = bigint_q("29793968203157093288"); - alt_bn128_ate_is_loop_count_neg = false; - alt_bn128_final_exponent = bigint<12*alt_bn128_q_limbs>("552484233613224096312617126783173147097382103762957654188882734314196910839907541213974502761540629817009608548654680343627701153829446747810907373256841551006201639677726139946029199968412598804882391702273019083653272047566316584365559776493027495458238373902875937659943504873220554161550525926302303331747463515644711876653177129578303191095900909191624817826566688241804408081892785725967931714097716709526092261278071952560171111444072049229123565057483750161460024353346284167282452756217662335528813519139808291170539072125381230815729071544861602750936964829313608137325426383735122175229541155376346436093930287402089517426973178917569713384748081827255472576937471496195752727188261435633271238710131736096299798168852925540549342330775279877006784354801422249722573783561685179618816480037695005515426162362431072245638324744480"); - alt_bn128_final_exponent_z = bigint_q("4965661367192848881"); - alt_bn128_final_exponent_is_z_neg = false; - -} -} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp deleted file mode 100644 index c3bea7673..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ALT_BN128_INIT_HPP_ -#define ALT_BN128_INIT_HPP_ -#include "algebra/curves/public_params.hpp" -#include "algebra/fields/fp.hpp" -#include "algebra/fields/fp2.hpp" -#include "algebra/fields/fp6_3over2.hpp" -#include "algebra/fields/fp12_2over3over2.hpp" - -namespace libsnark { - -const mp_size_t alt_bn128_r_bitcount = 254; -const mp_size_t alt_bn128_q_bitcount = 254; - -const mp_size_t alt_bn128_r_limbs = (alt_bn128_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; -const mp_size_t alt_bn128_q_limbs = (alt_bn128_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; - -extern bigint alt_bn128_modulus_r; -extern bigint alt_bn128_modulus_q; - -typedef Fp_model alt_bn128_Fr; -typedef Fp_model alt_bn128_Fq; -typedef Fp2_model alt_bn128_Fq2; -typedef Fp6_3over2_model alt_bn128_Fq6; -typedef Fp12_2over3over2_model alt_bn128_Fq12; -typedef alt_bn128_Fq12 alt_bn128_GT; - -// parameters for Barreto--Naehrig curve E/Fq : y^2 = x^3 + b -extern alt_bn128_Fq alt_bn128_coeff_b; -// parameters for twisted Barreto--Naehrig curve E'/Fq2 : y^2 = x^3 + b/xi -extern alt_bn128_Fq2 alt_bn128_twist; -extern alt_bn128_Fq2 alt_bn128_twist_coeff_b; -extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; -extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; -extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X; -extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y; - -// parameters for pairing -extern bigint alt_bn128_ate_loop_count; -extern bool alt_bn128_ate_is_loop_count_neg; -extern bigint<12*alt_bn128_q_limbs> alt_bn128_final_exponent; -extern bigint alt_bn128_final_exponent_z; -extern bool alt_bn128_final_exponent_is_z_neg; - -void init_alt_bn128_params(); - -class alt_bn128_G1; -class alt_bn128_G2; - -} // libsnark -#endif // ALT_BN128_INIT_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp deleted file mode 100644 index 07b6a8c71..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp +++ /dev/null @@ -1,547 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" -#include -#include "common/profiling.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -bool alt_bn128_ate_G1_precomp::operator==(const alt_bn128_ate_G1_precomp &other) const -{ - return (this->PX == other.PX && - this->PY == other.PY); -} - -std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P) -{ - out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY; - - return out; -} - -std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P) -{ - in >> prec_P.PX; - consume_OUTPUT_SEPARATOR(in); - in >> prec_P.PY; - - return in; -} - -bool alt_bn128_ate_ell_coeffs::operator==(const alt_bn128_ate_ell_coeffs &other) const -{ - return (this->ell_0 == other.ell_0 && - this->ell_VW == other.ell_VW && - this->ell_VV == other.ell_VV); -} - -std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &c) -{ - out << c.ell_0 << OUTPUT_SEPARATOR << c.ell_VW << OUTPUT_SEPARATOR << c.ell_VV; - return out; -} - -std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &c) -{ - in >> c.ell_0; - consume_OUTPUT_SEPARATOR(in); - in >> c.ell_VW; - consume_OUTPUT_SEPARATOR(in); - in >> c.ell_VV; - - return in; -} - -bool alt_bn128_ate_G2_precomp::operator==(const alt_bn128_ate_G2_precomp &other) const -{ - return (this->QX == other.QX && - this->QY == other.QY && - this->coeffs == other.coeffs); -} - -std::ostream& operator<<(std::ostream& out, const alt_bn128_ate_G2_precomp &prec_Q) -{ - out << prec_Q.QX << OUTPUT_SEPARATOR << prec_Q.QY << "\n"; - out << prec_Q.coeffs.size() << "\n"; - for (const alt_bn128_ate_ell_coeffs &c : prec_Q.coeffs) - { - out << c << OUTPUT_NEWLINE; - } - return out; -} - -std::istream& operator>>(std::istream& in, alt_bn128_ate_G2_precomp &prec_Q) -{ - in >> prec_Q.QX; - consume_OUTPUT_SEPARATOR(in); - in >> prec_Q.QY; - consume_newline(in); - - prec_Q.coeffs.clear(); - size_t s; - in >> s; - - consume_newline(in); - - prec_Q.coeffs.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - alt_bn128_ate_ell_coeffs c; - in >> c; - consume_OUTPUT_NEWLINE(in); - prec_Q.coeffs.emplace_back(c); - } - - return in; -} - -/* final exponentiations */ - -alt_bn128_Fq12 alt_bn128_final_exponentiation_first_chunk(const alt_bn128_Fq12 &elt) -{ - enter_block("Call to alt_bn128_final_exponentiation_first_chunk"); - - /* - Computes result = elt^((q^6-1)*(q^2+1)). - Follows, e.g., Beuchat et al page 9, by computing result as follows: - elt^((q^6-1)*(q^2+1)) = (conj(elt) * elt^(-1))^(q^2+1) - More precisely: - A = conj(elt) - B = elt.inverse() - C = A * B - D = C.Frobenius_map(2) - result = D * C - */ - - const alt_bn128_Fq12 A = alt_bn128_Fq12(elt.c0,-elt.c1); - const alt_bn128_Fq12 B = elt.inverse(); - const alt_bn128_Fq12 C = A * B; - const alt_bn128_Fq12 D = C.Frobenius_map(2); - const alt_bn128_Fq12 result = D * C; - - leave_block("Call to alt_bn128_final_exponentiation_first_chunk"); - - return result; -} - -alt_bn128_Fq12 alt_bn128_exp_by_neg_z(const alt_bn128_Fq12 &elt) -{ - enter_block("Call to alt_bn128_exp_by_neg_z"); - - alt_bn128_Fq12 result = elt.cyclotomic_exp(alt_bn128_final_exponent_z); - if (!alt_bn128_final_exponent_is_z_neg) - { - result = result.unitary_inverse(); - } - - leave_block("Call to alt_bn128_exp_by_neg_z"); - - return result; -} - -alt_bn128_Fq12 alt_bn128_final_exponentiation_last_chunk(const alt_bn128_Fq12 &elt) -{ - enter_block("Call to alt_bn128_final_exponentiation_last_chunk"); - - /* - Follows Laura Fuentes-Castaneda et al. "Faster hashing to G2" - by computing: - - result = elt^(q^3 * (12*z^3 + 6z^2 + 4z - 1) + - q^2 * (12*z^3 + 6z^2 + 6z) + - q * (12*z^3 + 6z^2 + 4z) + - 1 * (12*z^3 + 12z^2 + 6z + 1)) - which equals - - result = elt^( 2z * ( 6z^2 + 3z + 1 ) * (q^4 - q^2 + 1)/r ). - - Using the following addition chain: - - A = exp_by_neg_z(elt) // = elt^(-z) - B = A^2 // = elt^(-2*z) - C = B^2 // = elt^(-4*z) - D = C * B // = elt^(-6*z) - E = exp_by_neg_z(D) // = elt^(6*z^2) - F = E^2 // = elt^(12*z^2) - G = epx_by_neg_z(F) // = elt^(-12*z^3) - H = conj(D) // = elt^(6*z) - I = conj(G) // = elt^(12*z^3) - J = I * E // = elt^(12*z^3 + 6*z^2) - K = J * H // = elt^(12*z^3 + 6*z^2 + 6*z) - L = K * B // = elt^(12*z^3 + 6*z^2 + 4*z) - M = K * E // = elt^(12*z^3 + 12*z^2 + 6*z) - N = M * elt // = elt^(12*z^3 + 12*z^2 + 6*z + 1) - O = L.Frobenius_map(1) // = elt^(q*(12*z^3 + 6*z^2 + 4*z)) - P = O * N // = elt^(q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) - Q = K.Frobenius_map(2) // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z)) - R = Q * P // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) - S = conj(elt) // = elt^(-1) - T = S * L // = elt^(12*z^3 + 6*z^2 + 4*z - 1) - U = T.Frobenius_map(3) // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1)) - V = U * R // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1) + q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) - result = V - - */ - - const alt_bn128_Fq12 A = alt_bn128_exp_by_neg_z(elt); - const alt_bn128_Fq12 B = A.cyclotomic_squared(); - const alt_bn128_Fq12 C = B.cyclotomic_squared(); - const alt_bn128_Fq12 D = C * B; - const alt_bn128_Fq12 E = alt_bn128_exp_by_neg_z(D); - const alt_bn128_Fq12 F = E.cyclotomic_squared(); - const alt_bn128_Fq12 G = alt_bn128_exp_by_neg_z(F); - const alt_bn128_Fq12 H = D.unitary_inverse(); - const alt_bn128_Fq12 I = G.unitary_inverse(); - const alt_bn128_Fq12 J = I * E; - const alt_bn128_Fq12 K = J * H; - const alt_bn128_Fq12 L = K * B; - const alt_bn128_Fq12 M = K * E; - const alt_bn128_Fq12 N = M * elt; - const alt_bn128_Fq12 O = L.Frobenius_map(1); - const alt_bn128_Fq12 P = O * N; - const alt_bn128_Fq12 Q = K.Frobenius_map(2); - const alt_bn128_Fq12 R = Q * P; - const alt_bn128_Fq12 S = elt.unitary_inverse(); - const alt_bn128_Fq12 T = S * L; - const alt_bn128_Fq12 U = T.Frobenius_map(3); - const alt_bn128_Fq12 V = U * R; - - const alt_bn128_Fq12 result = V; - - leave_block("Call to alt_bn128_final_exponentiation_last_chunk"); - - return result; -} - -alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt) -{ - enter_block("Call to alt_bn128_final_exponentiation"); - /* OLD naive version: - alt_bn128_GT result = elt^alt_bn128_final_exponent; - */ - alt_bn128_Fq12 A = alt_bn128_final_exponentiation_first_chunk(elt); - alt_bn128_GT result = alt_bn128_final_exponentiation_last_chunk(A); - - leave_block("Call to alt_bn128_final_exponentiation"); - return result; -} - -/* ate pairing */ - -void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv, - alt_bn128_G2 ¤t, - alt_bn128_ate_ell_coeffs &c) -{ - const alt_bn128_Fq2 X = current.X, Y = current.Y, Z = current.Z; - - const alt_bn128_Fq2 A = two_inv * (X * Y); // A = X1 * Y1 / 2 - const alt_bn128_Fq2 B = Y.squared(); // B = Y1^2 - const alt_bn128_Fq2 C = Z.squared(); // C = Z1^2 - const alt_bn128_Fq2 D = C+C+C; // D = 3 * C - const alt_bn128_Fq2 E = alt_bn128_twist_coeff_b * D; // E = twist_b * D - const alt_bn128_Fq2 F = E+E+E; // F = 3 * E - const alt_bn128_Fq2 G = two_inv * (B+F); // G = (B+F)/2 - const alt_bn128_Fq2 H = (Y+Z).squared() - (B+C); // H = (Y1+Z1)^2-(B+C) - const alt_bn128_Fq2 I = E-B; // I = E-B - const alt_bn128_Fq2 J = X.squared(); // J = X1^2 - const alt_bn128_Fq2 E_squared = E.squared(); // E_squared = E^2 - - current.X = A * (B-F); // X3 = A * (B-F) - current.Y = G.squared() - (E_squared+E_squared+E_squared); // Y3 = G^2 - 3*E^2 - current.Z = B * H; // Z3 = B * H - c.ell_0 = alt_bn128_twist * I; // ell_0 = xi * I - c.ell_VW = -H; // ell_VW = - H (later: * yP) - c.ell_VV = J+J+J; // ell_VV = 3*J (later: * xP) -} - -void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base, - alt_bn128_G2 ¤t, - alt_bn128_ate_ell_coeffs &c) -{ - const alt_bn128_Fq2 X1 = current.X, Y1 = current.Y, Z1 = current.Z; - const alt_bn128_Fq2 &x2 = base.X, &y2 = base.Y; - - const alt_bn128_Fq2 D = X1 - x2 * Z1; // D = X1 - X2*Z1 - const alt_bn128_Fq2 E = Y1 - y2 * Z1; // E = Y1 - Y2*Z1 - const alt_bn128_Fq2 F = D.squared(); // F = D^2 - const alt_bn128_Fq2 G = E.squared(); // G = E^2 - const alt_bn128_Fq2 H = D*F; // H = D*F - const alt_bn128_Fq2 I = X1 * F; // I = X1 * F - const alt_bn128_Fq2 J = H + Z1*G - (I+I); // J = H + Z1*G - (I+I) - - current.X = D * J; // X3 = D*J - current.Y = E * (I-J)-(H * Y1); // Y3 = E*(I-J)-(H*Y1) - current.Z = Z1 * H; // Z3 = Z1*H - c.ell_0 = alt_bn128_twist * (E * x2 - D * y2); // ell_0 = xi * (E * X2 - D * Y2) - c.ell_VV = - E; // ell_VV = - E (later: * xP) - c.ell_VW = D; // ell_VW = D (later: * yP ) -} - -alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P) -{ - enter_block("Call to alt_bn128_ate_precompute_G1"); - - alt_bn128_G1 Pcopy = P; - Pcopy.to_affine_coordinates(); - - alt_bn128_ate_G1_precomp result; - result.PX = Pcopy.X; - result.PY = Pcopy.Y; - - leave_block("Call to alt_bn128_ate_precompute_G1"); - return result; -} - -alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q) -{ - enter_block("Call to alt_bn128_ate_precompute_G2"); - - alt_bn128_G2 Qcopy(Q); - Qcopy.to_affine_coordinates(); - - alt_bn128_Fq two_inv = (alt_bn128_Fq("2").inverse()); // could add to global params if needed - - alt_bn128_ate_G2_precomp result; - result.QX = Qcopy.X; - result.QY = Qcopy.Y; - - alt_bn128_G2 R; - R.X = Qcopy.X; - R.Y = Qcopy.Y; - R.Z = alt_bn128_Fq2::one(); - - const bigint &loop_count = alt_bn128_ate_loop_count; - bool found_one = false; - alt_bn128_ate_ell_coeffs c; - - for (int64_t i = loop_count.max_bits(); i >= 0; --i) - { - const bool bit = loop_count.test_bit(i); - if (!found_one) - { - /* this skips the MSB itself */ - found_one |= bit; - continue; - } - - doubling_step_for_flipped_miller_loop(two_inv, R, c); - result.coeffs.push_back(c); - - if (bit) - { - mixed_addition_step_for_flipped_miller_loop(Qcopy, R, c); - result.coeffs.push_back(c); - } - } - - alt_bn128_G2 Q1 = Qcopy.mul_by_q(); - assert_except(Q1.Z == alt_bn128_Fq2::one()); - alt_bn128_G2 Q2 = Q1.mul_by_q(); - assert_except(Q2.Z == alt_bn128_Fq2::one()); - - if (alt_bn128_ate_is_loop_count_neg) - { - R.Y = - R.Y; - } - Q2.Y = - Q2.Y; - - mixed_addition_step_for_flipped_miller_loop(Q1, R, c); - result.coeffs.push_back(c); - - mixed_addition_step_for_flipped_miller_loop(Q2, R, c); - result.coeffs.push_back(c); - - leave_block("Call to alt_bn128_ate_precompute_G2"); - return result; -} - -alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P, - const alt_bn128_ate_G2_precomp &prec_Q) -{ - enter_block("Call to alt_bn128_ate_miller_loop"); - - alt_bn128_Fq12 f = alt_bn128_Fq12::one(); - - bool found_one = false; - size_t idx = 0; - - const bigint &loop_count = alt_bn128_ate_loop_count; - alt_bn128_ate_ell_coeffs c; - - for (int64_t i = loop_count.max_bits(); i >= 0; --i) - { - const bool bit = loop_count.test_bit(i); - if (!found_one) - { - /* this skips the MSB itself */ - found_one |= bit; - continue; - } - - /* code below gets executed for all bits (EXCEPT the MSB itself) of - alt_bn128_param_p (skipping leading zeros) in MSB to LSB - order */ - - c = prec_Q.coeffs[idx++]; - f = f.squared(); - f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV); - - if (bit) - { - c = prec_Q.coeffs[idx++]; - f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV); - } - - } - - if (alt_bn128_ate_is_loop_count_neg) - { - f = f.inverse(); - } - - c = prec_Q.coeffs[idx++]; - f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV); - - c = prec_Q.coeffs[idx++]; - f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV); - - leave_block("Call to alt_bn128_ate_miller_loop"); - return f; -} - -alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1, - const alt_bn128_ate_G2_precomp &prec_Q1, - const alt_bn128_ate_G1_precomp &prec_P2, - const alt_bn128_ate_G2_precomp &prec_Q2) -{ - enter_block("Call to alt_bn128_ate_double_miller_loop"); - - alt_bn128_Fq12 f = alt_bn128_Fq12::one(); - - bool found_one = false; - size_t idx = 0; - - const bigint &loop_count = alt_bn128_ate_loop_count; - for (int64_t i = loop_count.max_bits(); i >= 0; --i) - { - const bool bit = loop_count.test_bit(i); - if (!found_one) - { - /* this skips the MSB itself */ - found_one |= bit; - continue; - } - - /* code below gets executed for all bits (EXCEPT the MSB itself) of - alt_bn128_param_p (skipping leading zeros) in MSB to LSB - order */ - - alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; - alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; - ++idx; - - f = f.squared(); - - f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); - f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); - - if (bit) - { - alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; - alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; - ++idx; - - f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); - f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); - } - } - - if (alt_bn128_ate_is_loop_count_neg) - { - f = f.inverse(); - } - - alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; - alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; - ++idx; - f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); - f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); - - c1 = prec_Q1.coeffs[idx]; - c2 = prec_Q2.coeffs[idx]; - ++idx; - f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); - f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); - - leave_block("Call to alt_bn128_ate_double_miller_loop"); - - return f; -} - -alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, const alt_bn128_G2 &Q) -{ - enter_block("Call to alt_bn128_ate_pairing"); - alt_bn128_ate_G1_precomp prec_P = alt_bn128_ate_precompute_G1(P); - alt_bn128_ate_G2_precomp prec_Q = alt_bn128_ate_precompute_G2(Q); - alt_bn128_Fq12 result = alt_bn128_ate_miller_loop(prec_P, prec_Q); - leave_block("Call to alt_bn128_ate_pairing"); - return result; -} - -alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, const alt_bn128_G2 &Q) -{ - enter_block("Call to alt_bn128_ate_reduced_pairing"); - const alt_bn128_Fq12 f = alt_bn128_ate_pairing(P, Q); - const alt_bn128_GT result = alt_bn128_final_exponentiation(f); - leave_block("Call to alt_bn128_ate_reduced_pairing"); - return result; -} - -/* choice of pairing */ - -alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P) -{ - return alt_bn128_ate_precompute_G1(P); -} - -alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q) -{ - return alt_bn128_ate_precompute_G2(Q); -} - -alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P, - const alt_bn128_G2_precomp &prec_Q) -{ - return alt_bn128_ate_miller_loop(prec_P, prec_Q); -} - -alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1, - const alt_bn128_G2_precomp &prec_Q1, - const alt_bn128_G1_precomp &prec_P2, - const alt_bn128_G2_precomp &prec_Q2) -{ - return alt_bn128_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); -} - -alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P, - const alt_bn128_G2 &Q) -{ - return alt_bn128_ate_pairing(P, Q); -} - -alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q) -{ - return alt_bn128_ate_reduced_pairing(P, Q); -} -} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp deleted file mode 100644 index 15d325485..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ALT_BN128_PAIRING_HPP_ -#define ALT_BN128_PAIRING_HPP_ -#include -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" - -namespace libsnark { - -/* final exponentiation */ - -alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt); - -/* ate pairing */ - -struct alt_bn128_ate_G1_precomp { - alt_bn128_Fq PX; - alt_bn128_Fq PY; - - bool operator==(const alt_bn128_ate_G1_precomp &other) const; - friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P); - friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P); -}; - -struct alt_bn128_ate_ell_coeffs { - alt_bn128_Fq2 ell_0; - alt_bn128_Fq2 ell_VW; - alt_bn128_Fq2 ell_VV; - - bool operator==(const alt_bn128_ate_ell_coeffs &other) const; - friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &dc); - friend std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &dc); -}; - -struct alt_bn128_ate_G2_precomp { - alt_bn128_Fq2 QX; - alt_bn128_Fq2 QY; - std::vector coeffs; - - bool operator==(const alt_bn128_ate_G2_precomp &other) const; - friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G2_precomp &prec_Q); - friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G2_precomp &prec_Q); -}; - -alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P); -alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q); - -alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P, - const alt_bn128_ate_G2_precomp &prec_Q); -alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1, - const alt_bn128_ate_G2_precomp &prec_Q1, - const alt_bn128_ate_G1_precomp &prec_P2, - const alt_bn128_ate_G2_precomp &prec_Q2); - -alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, - const alt_bn128_G2 &Q); -alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q); - -/* choice of pairing */ - -typedef alt_bn128_ate_G1_precomp alt_bn128_G1_precomp; -typedef alt_bn128_ate_G2_precomp alt_bn128_G2_precomp; - -alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P); - -alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q); - -alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P, - const alt_bn128_G2_precomp &prec_Q); - -alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1, - const alt_bn128_G2_precomp &prec_Q1, - const alt_bn128_G1_precomp &prec_P2, - const alt_bn128_G2_precomp &prec_Q2); - -alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P, - const alt_bn128_G2 &Q); - -alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q); - -alt_bn128_GT alt_bn128_affine_reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q); - -} // libsnark -#endif // ALT_BN128_PAIRING_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp deleted file mode 100644 index 25ea924d8..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" - -namespace libsnark { - -void alt_bn128_pp::init_public_params() -{ - init_alt_bn128_params(); -} - -alt_bn128_GT alt_bn128_pp::final_exponentiation(const alt_bn128_Fq12 &elt) -{ - return alt_bn128_final_exponentiation(elt); -} - -alt_bn128_G1_precomp alt_bn128_pp::precompute_G1(const alt_bn128_G1 &P) -{ - return alt_bn128_precompute_G1(P); -} - -alt_bn128_G2_precomp alt_bn128_pp::precompute_G2(const alt_bn128_G2 &Q) -{ - return alt_bn128_precompute_G2(Q); -} - -alt_bn128_Fq12 alt_bn128_pp::miller_loop(const alt_bn128_G1_precomp &prec_P, - const alt_bn128_G2_precomp &prec_Q) -{ - return alt_bn128_miller_loop(prec_P, prec_Q); -} - -alt_bn128_Fq12 alt_bn128_pp::double_miller_loop(const alt_bn128_G1_precomp &prec_P1, - const alt_bn128_G2_precomp &prec_Q1, - const alt_bn128_G1_precomp &prec_P2, - const alt_bn128_G2_precomp &prec_Q2) -{ - return alt_bn128_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); -} - -alt_bn128_Fq12 alt_bn128_pp::pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q) -{ - return alt_bn128_pairing(P, Q); -} - -alt_bn128_Fq12 alt_bn128_pp::reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q) -{ - return alt_bn128_reduced_pairing(P, Q); -} - -} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp deleted file mode 100644 index ec8059dcb..000000000 --- a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/** @file -***************************************************************************** -* @author This file is part of libsnark, developed by SCIPR Lab -* and contributors (see AUTHORS). -* @copyright MIT license (see LICENSE file) -*****************************************************************************/ - -#ifndef ALT_BN128_PP_HPP_ -#define ALT_BN128_PP_HPP_ -#include "algebra/curves/public_params.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp" - -namespace libsnark { - -class alt_bn128_pp { -public: - typedef alt_bn128_Fr Fp_type; - typedef alt_bn128_G1 G1_type; - typedef alt_bn128_G2 G2_type; - typedef alt_bn128_G1_precomp G1_precomp_type; - typedef alt_bn128_G2_precomp G2_precomp_type; - typedef alt_bn128_Fq Fq_type; - typedef alt_bn128_Fq2 Fqe_type; - typedef alt_bn128_Fq12 Fqk_type; - typedef alt_bn128_GT GT_type; - - static const bool has_affine_pairing = false; - - static void init_public_params(); - static alt_bn128_GT final_exponentiation(const alt_bn128_Fq12 &elt); - static alt_bn128_G1_precomp precompute_G1(const alt_bn128_G1 &P); - static alt_bn128_G2_precomp precompute_G2(const alt_bn128_G2 &Q); - static alt_bn128_Fq12 miller_loop(const alt_bn128_G1_precomp &prec_P, - const alt_bn128_G2_precomp &prec_Q); - static alt_bn128_Fq12 double_miller_loop(const alt_bn128_G1_precomp &prec_P1, - const alt_bn128_G2_precomp &prec_Q1, - const alt_bn128_G1_precomp &prec_P2, - const alt_bn128_G2_precomp &prec_Q2); - static alt_bn128_Fq12 pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q); - static alt_bn128_Fq12 reduced_pairing(const alt_bn128_G1 &P, - const alt_bn128_G2 &Q); -}; - -} // libsnark - -#endif // ALT_BN128_PP_HPP_ diff --git a/src/snark/libsnark/algebra/curves/curve_utils.hpp b/src/snark/libsnark/algebra/curves/curve_utils.hpp deleted file mode 100644 index 33a8e1e17..000000000 --- a/src/snark/libsnark/algebra/curves/curve_utils.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef CURVE_UTILS_HPP_ -#define CURVE_UTILS_HPP_ -#include - -#include "algebra/fields/bigint.hpp" - -namespace libsnark { - -template -GroupT scalar_mul(const GroupT &base, const bigint &scalar); - -} // libsnark -#include "algebra/curves/curve_utils.tcc" - -#endif // CURVE_UTILS_HPP_ diff --git a/src/snark/libsnark/algebra/curves/curve_utils.tcc b/src/snark/libsnark/algebra/curves/curve_utils.tcc deleted file mode 100644 index 38140cd48..000000000 --- a/src/snark/libsnark/algebra/curves/curve_utils.tcc +++ /dev/null @@ -1,37 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef CURVE_UTILS_TCC_ -#define CURVE_UTILS_TCC_ - -namespace libsnark { - -template -GroupT scalar_mul(const GroupT &base, const bigint &scalar) -{ - GroupT result = GroupT::zero(); - - bool found_one = false; - for (int64_t i = scalar.max_bits() - 1; i >= 0; --i) - { - if (found_one) - { - result = result.dbl(); - } - - if (scalar.test_bit(i)) - { - found_one = true; - result = result + base; - } - } - - return result; -} - -} // libsnark -#endif // CURVE_UTILS_TCC_ diff --git a/src/snark/libsnark/algebra/curves/public_params.hpp b/src/snark/libsnark/algebra/curves/public_params.hpp deleted file mode 100644 index 07e047560..000000000 --- a/src/snark/libsnark/algebra/curves/public_params.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PUBLIC_PARAMS_HPP_ -#define PUBLIC_PARAMS_HPP_ -#include - -namespace libsnark { - -/* - for every curve the user should define corresponding - public_params with the following typedefs: - - Fp_type - G1_type - G2_type - G1_precomp_type - G2_precomp_type - affine_ate_G1_precomp_type - affine_ate_G2_precomp_type - Fq_type - Fqe_type - Fqk_type - GT_type - - one should also define the following static methods: - - void init_public_params(); - - GT final_exponentiation(const Fqk &elt); - - G1_precomp precompute_G1(const G1 &P); - G2_precomp precompute_G2(const G2 &Q); - - Fqk miller_loop(const G1_precomp &prec_P, - const G2_precomp &prec_Q); - - affine_ate_G1_precomp affine_ate_precompute_G1(const G1 &P); - affine_ate_G2_precomp affine_ate_precompute_G2(const G2 &Q); - - - Fqk affine_ate_miller_loop(const affine_ate_G1_precomp &prec_P, - const affine_ate_G2_precomp &prec_Q); - Fqk affine_ate_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, - const affine_ate_G2_precomp &prec_Q1, - const affine_ate_G1_precomp &prec_P2, - const affine_ate_G2_precomp &prec_Q2); - Fqk affine_ate_e_times_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, - const affine_ate_G2_precomp &prec_Q1, - const affine_ate_G1_precomp &prec_P2, - const affine_ate_G2_precomp &prec_Q2, - const affine_ate_G1_precomp &prec_P3, - const affine_ate_G2_precomp &prec_Q3); - Fqk double_miller_loop(const G1_precomp &prec_P1, - const G2_precomp &prec_Q1, - const G1_precomp &prec_P2, - const G2_precomp &prec_Q2); - - Fqk pairing(const G1 &P, - const G2 &Q); - GT reduced_pairing(const G1 &P, - const G2 &Q); - GT affine_reduced_pairing(const G1 &P, - const G2 &Q); -*/ - -template -using Fr = typename EC_ppT::Fp_type; -template -using G1 = typename EC_ppT::G1_type; -template -using G2 = typename EC_ppT::G2_type; -template -using G1_precomp = typename EC_ppT::G1_precomp_type; -template -using G2_precomp = typename EC_ppT::G2_precomp_type; -template -using affine_ate_G1_precomp = typename EC_ppT::affine_ate_G1_precomp_type; -template -using affine_ate_G2_precomp = typename EC_ppT::affine_ate_G2_precomp_type; -template -using Fq = typename EC_ppT::Fq_type; -template -using Fqe = typename EC_ppT::Fqe_type; -template -using Fqk = typename EC_ppT::Fqk_type; -template -using GT = typename EC_ppT::GT_type; - -template -using Fr_vector = std::vector >; -template -using G1_vector = std::vector >; -template -using G2_vector = std::vector >; - -} // libsnark - -#endif // PUBLIC_PARAMS_HPP_ diff --git a/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp b/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp deleted file mode 100644 index 18e68f7bb..000000000 --- a/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include -#include "common/profiling.hpp" -//#include "algebra/curves/edwards/edwards_pp.hpp" -#ifdef CURVE_BN128 -#include "algebra/curves/bn128/bn128_pp.hpp" -#endif -#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" -//#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" -//#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp" -#include "algebra/curves/alt_bn128/alt_bn128_pairing.cpp" - -using namespace libsnark; - -template -void pairing_test() -{ - GT GT_one = GT::one(); - - printf("Running bilinearity tests:\n"); - G1 P = (Fr::random_element()) * G1::one(); - //G1 P = Fr("2") * G1::one(); - G2 Q = (Fr::random_element()) * G2::one(); - //G2 Q = Fr("3") * G2::one(); - - printf("P:\n"); - P.print(); - P.print_coordinates(); - printf("Q:\n"); - Q.print(); - Q.print_coordinates(); - printf("\n\n"); - - Fr s = Fr::random_element(); - //Fr s = Fr("2"); - G1 sP = s * P; - G2 sQ = s * Q; - - printf("Pairing bilinearity tests (three must match):\n"); - GT ans1 = ppT::reduced_pairing(sP, Q); - GT ans2 = ppT::reduced_pairing(P, sQ); - GT ans3 = ppT::reduced_pairing(P, Q)^s; - ans1.print(); - ans2.print(); - ans3.print(); - assert(ans1 == ans2); - assert(ans2 == ans3); - - assert(ans1 != GT_one); - assert((ans1^Fr::field_char()) == GT_one); - printf("\n\n"); -} - -template -void double_miller_loop_test() -{ - const G1 P1 = (Fr::random_element()) * G1::one(); - const G1 P2 = (Fr::random_element()) * G1::one(); - const G2 Q1 = (Fr::random_element()) * G2::one(); - const G2 Q2 = (Fr::random_element()) * G2::one(); - - const G1_precomp prec_P1 = ppT::precompute_G1(P1); - const G1_precomp prec_P2 = ppT::precompute_G1(P2); - const G2_precomp prec_Q1 = ppT::precompute_G2(Q1); - const G2_precomp prec_Q2 = ppT::precompute_G2(Q2); - - const Fqk ans_1 = ppT::miller_loop(prec_P1, prec_Q1); - const Fqk ans_2 = ppT::miller_loop(prec_P2, prec_Q2); - const Fqk ans_12 = ppT::double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); - assert(ans_1 * ans_2 == ans_12); -} - -template -void affine_pairing_test() -{ - GT GT_one = GT::one(); - - printf("Running bilinearity tests:\n"); - G1 P = (Fr::random_element()) * G1::one(); - G2 Q = (Fr::random_element()) * G2::one(); - - printf("P:\n"); - P.print(); - printf("Q:\n"); - Q.print(); - printf("\n\n"); - - Fr s = Fr::random_element(); - G1 sP = s * P; - G2 sQ = s * Q; - - printf("Pairing bilinearity tests (three must match):\n"); - GT ans1 = ppT::affine_reduced_pairing(sP, Q); - GT ans2 = ppT::affine_reduced_pairing(P, sQ); - GT ans3 = ppT::affine_reduced_pairing(P, Q)^s; - ans1.print(); - ans2.print(); - ans3.print(); - assert(ans1 == ans2); - assert(ans2 == ans3); - - assert(ans1 != GT_one); - assert((ans1^Fr::field_char()) == GT_one); - printf("\n\n"); -} - -int main(void) -{ - start_profiling(); - edwards_pp::init_public_params(); - pairing_test(); - double_miller_loop_test(); - - mnt6_pp::init_public_params(); - pairing_test(); - double_miller_loop_test(); - affine_pairing_test(); - - mnt4_pp::init_public_params(); - pairing_test(); - double_miller_loop_test(); - affine_pairing_test(); - - alt_bn128_pp::init_public_params(); - pairing_test(); - double_miller_loop_test(); - -#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled - bn128_pp::init_public_params(); - pairing_test(); - double_miller_loop_test(); -#endif -} diff --git a/src/snark/libsnark/algebra/curves/tests/test_groups.cpp b/src/snark/libsnark/algebra/curves/tests/test_groups.cpp deleted file mode 100644 index 4f64334ba..000000000 --- a/src/snark/libsnark/algebra/curves/tests/test_groups.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include "common/profiling.hpp" -//#include "algebra/curves/edwards/edwards_pp.hpp" -//#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" -//#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -#ifdef CURVE_BN128 -#include "algebra/curves/bn128/bn128_pp.hpp" -#endif -#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" -#include - -using namespace libsnark; - -template -void test_mixed_add() -{ - GroupT base, el, result; - - base = GroupT::zero(); - el = GroupT::zero(); - el.to_special(); - result = base.mixed_add(el); - assert(result == base + el); - - base = GroupT::zero(); - el = GroupT::random_element(); - el.to_special(); - result = base.mixed_add(el); - assert(result == base + el); - - base = GroupT::random_element(); - el = GroupT::zero(); - el.to_special(); - result = base.mixed_add(el); - assert(result == base + el); - - base = GroupT::random_element(); - el = GroupT::random_element(); - el.to_special(); - result = base.mixed_add(el); - assert(result == base + el); - - base = GroupT::random_element(); - el = base; - el.to_special(); - result = base.mixed_add(el); - assert(result == base.dbl()); -} - -template -void test_group() -{ - bigint<1> rand1 = bigint<1>("76749407"); - bigint<1> rand2 = bigint<1>("44410867"); - bigint<1> randsum = bigint<1>("121160274"); - - GroupT zero = GroupT::zero(); - assert(zero == zero); - GroupT one = GroupT::one(); - assert(one == one); - GroupT two = bigint<1>(2l) * GroupT::one(); - assert(two == two); - GroupT five = bigint<1>(5l) * GroupT::one(); - - GroupT three = bigint<1>(3l) * GroupT::one(); - GroupT four = bigint<1>(4l) * GroupT::one(); - - assert(two+five == three+four); - - GroupT a = GroupT::random_element(); - GroupT b = GroupT::random_element(); - - assert(one != zero); - assert(a != zero); - assert(a != one); - - assert(b != zero); - assert(b != one); - - assert(a.dbl() == a + a); - assert(b.dbl() == b + b); - assert(one.add(two) == three); - assert(two.add(one) == three); - assert(a + b == b + a); - assert(a - a == zero); - assert(a - b == a + (-b)); - assert(a - b == (-b) + a); - - // handle special cases - assert(zero + (-a) == -a); - assert(zero - a == -a); - assert(a - zero == a); - assert(a + zero == a); - assert(zero + a == a); - - assert((a + b).dbl() == (a + b) + (b + a)); - assert(bigint<1>("2") * (a + b) == (a + b) + (b + a)); - - assert((rand1 * a) + (rand2 * a) == (randsum * a)); - - assert(GroupT::order() * a == zero); - assert(GroupT::order() * one == zero); - assert((GroupT::order() * a) - a != zero); - assert((GroupT::order() * one) - one != zero); - - test_mixed_add(); -} - -template -void test_mul_by_q() -{ - GroupT a = GroupT::random_element(); - assert((GroupT::base_field_char()*a) == a.mul_by_q()); -} - -template -void test_output() -{ - GroupT g = GroupT::zero(); - - for (size_t i = 0; i < 1000; ++i) - { - std::stringstream ss; - ss << g; - GroupT gg; - ss >> gg; - assert(g == gg); - /* use a random point in next iteration */ - g = GroupT::random_element(); - } -} - -int main(void) -{ -/* - edwards_pp::init_public_params(); - test_group >(); - test_output >(); - test_group >(); - test_output >(); - test_mul_by_q >(); - - mnt4_pp::init_public_params(); - test_group >(); - test_output >(); - test_group >(); - test_output >(); - test_mul_by_q >(); - - mnt6_pp::init_public_params(); - test_group >(); - test_output >(); - test_group >(); - test_output >(); - test_mul_by_q >(); -*/ - alt_bn128_pp::init_public_params(); - test_group >(); - test_output >(); - test_group >(); - test_output >(); - test_mul_by_q >(); - -#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled - bn128_pp::init_public_params(); - test_group >(); - test_output >(); - test_group >(); - test_output >(); -#endif -} diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp deleted file mode 100644 index 3e127a063..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for the "basic radix-2" evaluation domain. - - Roughly, the domain has size m = 2^k and consists of the m-th roots of unity. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_RADIX2_DOMAIN_HPP_ -#define BASIC_RADIX2_DOMAIN_HPP_ - -#include "algebra/evaluation_domain/evaluation_domain.hpp" - -namespace libsnark { - -template -class basic_radix2_domain : public evaluation_domain { -public: - - FieldT omega; - - basic_radix2_domain(const size_t m); - - void FFT(std::vector &a); - void iFFT(std::vector &a); - void cosetFFT(std::vector &a, const FieldT &g); - void icosetFFT(std::vector &a, const FieldT &g); - std::vector lagrange_coeffs(const FieldT &t); - FieldT get_element(const size_t idx); - FieldT compute_Z(const FieldT &t); - void add_poly_Z(const FieldT &coeff, std::vector &H); - void divide_by_Z_on_coset(std::vector &P); - -}; - -} // libsnark - -#include "algebra/evaluation_domain/domains/basic_radix2_domain.tcc" - -#endif // BASIC_RADIX2_DOMAIN_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc deleted file mode 100644 index 16dcd54fc..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc +++ /dev/null @@ -1,113 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for the "basic radix-2" evaluation domain. - - See basic_radix2_domain.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_RADIX2_DOMAIN_TCC_ -#define BASIC_RADIX2_DOMAIN_TCC_ - -#include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -template -basic_radix2_domain::basic_radix2_domain(const size_t m) : evaluation_domain(m) -{ - assert_except(m > 1); - const size_t logm = log2(m); - assert_except(logm <= (FieldT::s)); - - omega = get_root_of_unity(m); -} - -template -void basic_radix2_domain::FFT(std::vector &a) -{ - enter_block("Execute FFT"); - assert_except(a.size() == this->m); - _basic_radix2_FFT(a, omega); - leave_block("Execute FFT"); -} - -template -void basic_radix2_domain::iFFT(std::vector &a) -{ - enter_block("Execute inverse FFT"); - assert_except(a.size() == this->m); - _basic_radix2_FFT(a, omega.inverse()); - - const FieldT sconst = FieldT(a.size()).inverse(); - for (size_t i = 0; i < a.size(); ++i) - { - a[i] *= sconst; - } - leave_block("Execute inverse FFT"); -} - -template -void basic_radix2_domain::cosetFFT(std::vector &a, const FieldT &g) -{ - enter_block("Execute coset FFT"); - _multiply_by_coset(a, g); - FFT(a); - leave_block("Execute coset FFT"); -} - -template -void basic_radix2_domain::icosetFFT(std::vector &a, const FieldT &g) -{ - enter_block("Execute inverse coset IFFT"); - iFFT(a); - _multiply_by_coset(a, g.inverse()); - leave_block("Execute inverse coset IFFT"); -} - -template -std::vector basic_radix2_domain::lagrange_coeffs(const FieldT &t) -{ - return _basic_radix2_lagrange_coeffs(this->m, t); -} - -template -FieldT basic_radix2_domain::get_element(const size_t idx) -{ - return omega^idx; -} - -template -FieldT basic_radix2_domain::compute_Z(const FieldT &t) -{ - return (t^this->m) - FieldT::one(); -} - -template -void basic_radix2_domain::add_poly_Z(const FieldT &coeff, std::vector &H) -{ - assert_except(H.size() == this->m+1); - H[this->m] += coeff; - H[0] -= coeff; -} - -template -void basic_radix2_domain::divide_by_Z_on_coset(std::vector &P) -{ - const FieldT coset = FieldT::multiplicative_generator; - const FieldT Z_inverse_at_coset = this->compute_Z(coset).inverse(); - for (size_t i = 0; i < this->m; ++i) - { - P[i] *= Z_inverse_at_coset; - } -} - -} // libsnark - -#endif // BASIC_RADIX2_DOMAIN_TCC_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp deleted file mode 100644 index c42ab2f6f..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for auxiliary functions for the "basic radix-2" evaluation domain. - - These functions compute the radix-2 FFT (in single- or multi-thread mode) and, - also compute Lagrange coefficients. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_RADIX2_DOMAIN_AUX_HPP_ -#define BASIC_RADIX2_DOMAIN_AUX_HPP_ - -namespace libsnark { - -/** - * Compute the radix-2 FFT of the vector a over the set S={omega^{0},...,omega^{m-1}}. - */ -template -void _basic_radix2_FFT(std::vector &a, const FieldT &omega); - -/** - * A multi-thread version of _basic_radix2_FFT. - */ -template -void _parallel_basic_radix2_FFT(std::vector &a, const FieldT &omega); - -/** - * Translate the vector a to a coset defined by g. - */ -template -void _multiply_by_coset(std::vector &a, const FieldT &g); - -/** - * Compute the m Lagrange coefficients, relative to the set S={omega^{0},...,omega^{m-1}}, at the field element t. - */ -template -std::vector _basic_radix2_lagrange_coeffs(const size_t m, const FieldT &t); - -} // libsnark - -#include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc" - -#endif // BASIC_RADIX2_DOMAIN_AUX_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc deleted file mode 100644 index 4b03b1f9b..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc +++ /dev/null @@ -1,243 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for auxiliary functions for the "basic radix-2" evaluation domain. - - See basic_radix2_domain_aux.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_RADIX2_DOMAIN_AUX_TCC_ -#define BASIC_RADIX2_DOMAIN_AUX_TCC_ - -#include -#ifdef MULTICORE -#include -#endif -#include "algebra/fields/field_utils.hpp" -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -#ifdef MULTICORE -#define _basic_radix2_FFT _basic_parallel_radix2_FFT -#else -#define _basic_radix2_FFT _basic_serial_radix2_FFT -#endif - -/* - Below we make use of pseudocode from [CLRS 2n Ed, pp. 864]. - Also, note that it's the caller's responsibility to multiply by 1/N. - */ -template -void _basic_serial_radix2_FFT(std::vector &a, const FieldT &omega) -{ - const size_t n = a.size(), logn = log2(n); - assert_except(n == (1u << logn)); - - /* swapping in place (from Storer's book) */ - for (size_t k = 0; k < n; ++k) - { - const size_t rk = bitreverse(k, logn); - if (k < rk) - std::swap(a[k], a[rk]); - } - - size_t m = 1; // invariant: m = 2^{s-1} - for (size_t s = 1; s <= logn; ++s) - { - // w_m is 2^s-th root of unity now - const FieldT w_m = omega^(n/(2*m)); - - asm volatile ("/* pre-inner */"); - for (size_t k = 0; k < n; k += 2*m) - { - FieldT w = FieldT::one(); - for (size_t j = 0; j < m; ++j) - { - const FieldT t = w * a[k+j+m]; - a[k+j+m] = a[k+j] - t; - a[k+j] += t; - w *= w_m; - } - } - asm volatile ("/* post-inner */"); - m *= 2; - } -} - -template -void _basic_parallel_radix2_FFT_inner(std::vector &a, const FieldT &omega, const size_t log_cpus) -{ - const size_t num_cpus = UINT64_C(1)< > tmp(num_cpus); - for (size_t j = 0; j < num_cpus; ++j) - { - tmp[j].resize(UINT64_C(1)<<(log_m-log_cpus), FieldT::zero()); - } - -#ifdef MULTICORE - #pragma omp parallel for -#endif - for (size_t j = 0; j < num_cpus; ++j) - { - const FieldT omega_j = omega^j; - const FieldT omega_step = omega^(j<<(log_m - log_cpus)); - - FieldT elt = FieldT::one(); - for (size_t i = 0; i < UINT64_C(1)<<(log_m - log_cpus); ++i) - { - for (size_t s = 0; s < num_cpus; ++s) - { - // invariant: elt is omega^(j*idx) - const size_t idx = (i + (s<<(log_m - log_cpus))) % (1u << log_m); - tmp[j][i] += a[idx] * elt; - elt *= omega_step; - } - elt *= omega_j; - } - } - leave_block("Shuffle inputs"); - - enter_block("Execute sub-FFTs"); - const FieldT omega_num_cpus = omega^num_cpus; - -#ifdef MULTICORE - #pragma omp parallel for -#endif - for (size_t j = 0; j < num_cpus; ++j) - { - _basic_serial_radix2_FFT(tmp[j], omega_num_cpus); - } - leave_block("Execute sub-FFTs"); - - enter_block("Re-shuffle outputs"); - -#ifdef MULTICORE - #pragma omp parallel for -#endif - for (size_t i = 0; i < num_cpus; ++i) - { - for (size_t j = 0; j < UINT64_C(1)<<(log_m - log_cpus); ++j) - { - // now: i = idx >> (log_m - log_cpus) and j = idx % (1u << (log_m - log_cpus)), for idx = ((i<<(log_m-log_cpus))+j) % (1u << log_m) - a[(j< -void _basic_parallel_radix2_FFT(std::vector &a, const FieldT &omega) -{ -#ifdef MULTICORE - const size_t num_cpus = omp_get_max_threads(); -#else - const size_t num_cpus = 1; -#endif - const size_t log_cpus = ((num_cpus & (num_cpus - 1)) == 0 ? log2(num_cpus) : log2(num_cpus) - 1); - -#ifdef DEBUG - print_indent(); printf("* Invoking parallel FFT on 2^%zu CPUs (omp_get_max_threads = %zu)\n", log_cpus, num_cpus); -#endif - - if (log_cpus == 0) - { - _basic_serial_radix2_FFT(a, omega); - } - else - { - _basic_parallel_radix2_FFT_inner(a, omega, log_cpus); - } -} - -template -void _multiply_by_coset(std::vector &a, const FieldT &g) -{ - //enter_block("Multiply by coset"); - FieldT u = g; - for (size_t i = 1; i < a.size(); ++i) - { - a[i] *= u; - u *= g; - } - //leave_block("Multiply by coset"); -} - -template -std::vector _basic_radix2_lagrange_coeffs(const size_t m, const FieldT &t) -{ - if (m == 1) - { - return std::vector(1, FieldT::one()); - } - - assert_except(m == (1u << log2(m))); - - const FieldT omega = get_root_of_unity(m); - - std::vector u(m, FieldT::zero()); - - /* - If t equals one of the roots of unity in S={omega^{0},...,omega^{m-1}} - then output 1 at the right place, and 0 elsewhere - */ - - if ((t^m) == (FieldT::one())) - { - FieldT omega_i = FieldT::one(); - for (size_t i = 0; i < m; ++i) - { - if (omega_i == t) // i.e., t equals omega^i - { - u[i] = FieldT::one(); - return u; - } - - omega_i *= omega; - } - } - - /* - Otherwise, if t does not equal any of the roots of unity in S, - then compute each L_{i,S}(t) as Z_{S}(t) * v_i / (t-\omega^i) - where: - - Z_{S}(t) = \prod_{j} (t-\omega^j) = (t^m-1), and - - v_{i} = 1 / \prod_{j \neq i} (\omega^i-\omega^j). - Below we use the fact that v_{0} = 1/m and v_{i+1} = \omega * v_{i}. - */ - - const FieldT Z = (t^m)-FieldT::one(); - FieldT l = Z * FieldT(m).inverse(); - FieldT r = FieldT::one(); - for (size_t i = 0; i < m; ++i) - { - u[i] = l * (t - r).inverse(); - l *= omega; - r *= omega; - } - - return u; -} - -} // libsnark - -#endif // BASIC_RADIX2_DOMAIN_AUX_TCC_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp deleted file mode 100644 index 358db9798..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp +++ /dev/null @@ -1,125 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for evaluation domains. - - Roughly, given a desired size m for the domain, the constructor selects - a choice of domain S with size ~m that has been selected so to optimize - - computations of Lagrange polynomials, and - - FFT/iFFT computations. - An evaluation domain also provides other other functions, e.g., accessing - individual elements in S or evaluating its vanishing polynomial. - - The descriptions below make use of the definition of a *Lagrange polynomial*, - which we recall. Given a field F, a subset S=(a_i)_i of F, and an index idx - in {0,...,|S-1|}, the idx-th Lagrange polynomial (wrt to subset S) is defined to be - \f[ L_{idx,S}(z) := prod_{k \neq idx} (z - a_k) / prod_{k \neq idx} (a_{idx} - a_k) \f] - Note that, by construction: - \f[ \forall j \neq idx: L_{idx,S}(a_{idx}) = 1 \text{ and } L_{idx,S}(a_j) = 0 \f] - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef EVALUATION_DOMAIN_HPP_ -#define EVALUATION_DOMAIN_HPP_ - -#include - -namespace libsnark { - -/** - * An evaluation domain. - */ -template -class evaluation_domain { -public: - - const size_t m; - - /** - * Construct an evaluation domain S of size m, if possible. - * - * (See the function get_evaluation_domain below.) - */ - evaluation_domain(const size_t m) : m(m) {}; - - /** - * Get the idx-th element in S. - */ - virtual FieldT get_element(const size_t idx) = 0; - - /** - * Compute the FFT, over the domain S, of the vector a. - */ - virtual void FFT(std::vector &a) = 0; - - /** - * Compute the inverse FFT, over the domain S, of the vector a. - */ - virtual void iFFT(std::vector &a) = 0; - - /** - * Compute the FFT, over the domain g*S, of the vector a. - */ - virtual void cosetFFT(std::vector &a, const FieldT &g) = 0; - - /** - * Compute the inverse FFT, over the domain g*S, of the vector a. - */ - virtual void icosetFFT(std::vector &a, const FieldT &g) = 0; - - /** - * Evaluate all Lagrange polynomials. - * - * The inputs are: - * - an integer m - * - an element t - * The output is a vector (b_{0},...,b_{m-1}) - * where b_{i} is the evaluation of L_{i,S}(z) at z = t. - */ - virtual std::vector lagrange_coeffs(const FieldT &t) = 0; - - /** - * Evaluate the vanishing polynomial of S at the field element t. - */ - virtual FieldT compute_Z(const FieldT &t) = 0; - - /** - * Add the coefficients of the vanishing polynomial of S to the coefficients of the polynomial H. - */ - virtual void add_poly_Z(const FieldT &coeff, std::vector &H) = 0; - - /** - * Multiply by the evaluation, on a coset of S, of the inverse of the vanishing polynomial of S. - */ - virtual void divide_by_Z_on_coset(std::vector &P) = 0; -}; - -/** - * Return an evaluation domain object in which the domain S has size |S| >= min_size. - * The function chooses from different supported domains, depending on min_size. - */ -template -std::shared_ptr > get_evaluation_domain(const size_t min_size); - -/** - * Naive evaluation of a *single* Lagrange polynomial, used for testing purposes. - * - * The inputs are: - * - an integer m - * - a domain S = (a_{0},...,a_{m-1}) of size m - * - a field element element t - * - an index idx in {0,...,m-1} - * The output is the polynomial L_{idx,S}(z) evaluated at z = t. - */ -template -FieldT lagrange_eval(const size_t m, const std::vector &domain, const FieldT &t, const size_t idx); - -} // libsnark - -#include "algebra/evaluation_domain/evaluation_domain.tcc" - -#endif // EVALUATION_DOMAIN_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc deleted file mode 100644 index d0e28c8ce..000000000 --- a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc +++ /dev/null @@ -1,118 +0,0 @@ -/** @file - ***************************************************************************** - - Imeplementation of interfaces for evaluation domains. - - See evaluation_domain.hpp . - - We currently implement, and select among, three types of domains: - - "basic radix-2": the domain has size m = 2^k and consists of the m-th roots of unity - - "extended radix-2": the domain has size m = 2^{k+1} and consists of "the m-th roots of unity" union "a coset" - - "step radix-2": the domain has size m = 2^k + 2^r and consists of "the 2^k-th roots of unity" union "a coset of 2^r-th roots of unity" - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef EVALUATION_DOMAIN_TCC_ -#define EVALUATION_DOMAIN_TCC_ - -#include -#include "algebra/fields/field_utils.hpp" -#include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -template -std::shared_ptr > get_evaluation_domain(const size_t min_size) -{ - assert_except(min_size > 1); - const size_t log_min_size = log2(min_size); - assert_except(log_min_size <= (FieldT::s+1)); - - std::shared_ptr > result; - if (min_size == (1u << log_min_size)) - { - if (log_min_size == FieldT::s+1) - { - if (!inhibit_profiling_info) - { - print_indent(); printf("* Selected domain: extended_radix2\n"); - } - assert_except(0); - } - else - { - if (!inhibit_profiling_info) - { - print_indent(); printf("* Selected domain: basic_radix2\n"); - } - result.reset(new basic_radix2_domain(min_size)); - } - } - else - { - const size_t big = UINT64_C(1)<<(log2(min_size)-1); - const size_t small = min_size - big; - const size_t rounded_small = (UINT64_C(1)<(big + rounded_small)); - } - else - { - if (!inhibit_profiling_info) - { - print_indent(); printf("* Selected domain: extended_radix2\n"); - } - assert_except(0); - } - } - else - { - if (!inhibit_profiling_info) - { - print_indent(); printf("* Selected domain: step_radix2\n"); - } - assert_except(0); - } - } - - return result; -} - -template -FieldT lagrange_eval(const size_t m, const std::vector &domain, const FieldT &t, const size_t idx) -{ - assert_except(m == domain.size()); - assert_except(idx < m); - - FieldT num = FieldT::one(); - FieldT denom = FieldT::one(); - - for (size_t k = 0; k < m; ++k) - { - if (k == idx) - { - continue; - } - - num *= t - domain[k]; - denom *= domain[idx] - domain[k]; - } - - return num * denom.inverse(); -} - -} // libsnark - -#endif // EVALUATION_DOMAIN_TCC_ diff --git a/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp b/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp deleted file mode 100644 index 836ebf002..000000000 --- a/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for (square-and-multiply) exponentiation. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef EXPONENTIATION_HPP_ -#define EXPONENTIATION_HPP_ - -#include - -#include "algebra/fields/bigint.hpp" - -namespace libsnark { - -template -FieldT power(const FieldT &base, const bigint &exponent); - -template -FieldT power(const FieldT &base, const uint64_t exponent); - -} // libsnark - -#include "algebra/exponentiation/exponentiation.tcc" - -#endif // EXPONENTIATION_HPP_ diff --git a/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc b/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc deleted file mode 100644 index 7ac3bf5d3..000000000 --- a/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc +++ /dev/null @@ -1,53 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for (square-and-multiply) exponentiation. - - See exponentiation.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef EXPONENTIATION_TCC_ -#define EXPONENTIATION_TCC_ - -#include "common/utils.hpp" - -namespace libsnark { - -template -FieldT power(const FieldT &base, const bigint &exponent) -{ - FieldT result = FieldT::one(); - - bool found_one = false; - - for (int64_t i = exponent.max_bits() - 1; i >= 0; --i) - { - if (found_one) - { - result = result * result; - } - - if (exponent.test_bit(i)) - { - found_one = true; - result = result * base; - } - } - - return result; -} - -template -FieldT power(const FieldT &base, const uint64_t exponent) -{ - return power(base, bigint<1>(exponent)); -} - -} // libsnark - -#endif // EXPONENTIATION_TCC_ diff --git a/src/snark/libsnark/algebra/fields/bigint.hpp b/src/snark/libsnark/algebra/fields/bigint.hpp deleted file mode 100644 index d17e9a7bb..000000000 --- a/src/snark/libsnark/algebra/fields/bigint.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/** @file - ***************************************************************************** - Declaration of bigint wrapper class around GMP's MPZ long integers. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BIGINT_HPP_ -#define BIGINT_HPP_ -#include -#include -#include -#include "common/serialization.hpp" - -namespace libsnark { - -template class bigint; -template std::ostream& operator<<(std::ostream &, const bigint&); -template std::istream& operator>>(std::istream &, bigint&); - -/** - * Wrapper class around GMP's MPZ long integers. It supports arithmetic operations, - * serialization and randomization. Serialization is fragile, see common/serialization.hpp. - */ - -template -class bigint { -public: - static const mp_size_t N = n; - - mp_limb_t data[n] = {0}; - - bigint() = default; - bigint(const uint64_t x); /// Initalize from a small integer - bigint(const char* s); /// Initialize from a string containing an integer in decimal notation - bigint(const mpz_t r); /// Initialize from MPZ element - - void print() const; - void print_hex() const; - bool operator==(const bigint& other) const; - bool operator!=(const bigint& other) const; - void clear(); - bool is_zero() const; - size_t max_bits() const { return n * GMP_NUMB_BITS; } - size_t num_bits() const; - - uint64_t as_uint64() const; /* return the last limb of the integer */ - void to_mpz(mpz_t r) const; - bool test_bit(const std::size_t bitno) const; - - template inline void operator+=(const bigint& other); - template inline bigint operator*(const bigint& other) const; - template static inline void div_qr(bigint& quotient, bigint& remainder, - const bigint& dividend, const bigint& divisor); - template inline bigint shorten(const bigint& q, const char *msg) const; - - inline void limit(const bigint& q, const char *msg) const; - bool operator>(const bigint& other) const; - - bigint& randomize(); - - friend std::ostream& operator<< (std::ostream &out, const bigint &b); - friend std::istream& operator>> (std::istream &in, bigint &b); -}; - -} // libsnark -#include "algebra/fields/bigint.tcc" -#endif diff --git a/src/snark/libsnark/algebra/fields/bigint.tcc b/src/snark/libsnark/algebra/fields/bigint.tcc deleted file mode 100644 index fada2d06b..000000000 --- a/src/snark/libsnark/algebra/fields/bigint.tcc +++ /dev/null @@ -1,280 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of bigint wrapper class around GMP's MPZ long integers. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BIGINT_TCC_ -#define BIGINT_TCC_ -#include -#include -#include -#include "sodium.h" -#include "common/assert_except.hpp" - -namespace libsnark { - -template -bigint::bigint(const uint64_t x) /// Initialize from a small integer -{ - static_assert(UINT64_MAX <= GMP_NUMB_MAX, "uint64_t does not fit in a GMP limb"); - this->data[0] = x; -} - -template -bigint::bigint(const char* s) /// Initialize from a string containing an integer in decimal notation -{ - size_t l = strlen(s); - unsigned char* s_copy = new unsigned char[l]; - - for (size_t i = 0; i < l; ++i) - { - assert_except(s[i] >= '0' && s[i] <= '9'); - s_copy[i] = s[i] - '0'; - } - - mp_size_t limbs_written = mpn_set_str(this->data, s_copy, l, 10); - assert_except(limbs_written <= n); - - delete[] s_copy; -} - -template -bigint::bigint(const mpz_t r) /// Initialize from MPZ element -{ - mpz_t k; - mpz_init_set(k, r); - - for (size_t i = 0; i < n; ++i) - { - data[i] = mpz_get_ui(k); - mpz_fdiv_q_2exp(k, k, GMP_NUMB_BITS); - } - - assert_except(mpz_sgn(k) == 0); - mpz_clear(k); -} - -template -void bigint::print() const -{ - gmp_printf("%Nd\n", this->data, n); -} - -template -void bigint::print_hex() const -{ - gmp_printf("%Nx\n", this->data, n); -} - -template -bool bigint::operator==(const bigint& other) const -{ - return (mpn_cmp(this->data, other.data, n) == 0); -} - -template -bool bigint::operator!=(const bigint& other) const -{ - return !(operator==(other)); -} - -template -void bigint::clear() -{ - mpn_zero(this->data, n); -} - -template -bool bigint::is_zero() const -{ - for (mp_size_t i = 0; i < n; ++i) - { - if (this->data[i]) - { - return false; - } - } - - return true; -} - -template -size_t bigint::num_bits() const -{ -/* - for (int64_t i = max_bits(); i >= 0; --i) - { - if (this->test_bit(i)) - { - return i+1; - } - } - - return 0; -*/ - for (int64_t i = n-1; i >= 0; --i) - { - mp_limb_t x = this->data[i]; - if (x == 0) - { - continue; - } - else - { - static_assert(GMP_NUMB_MAX <= ULLONG_MAX, "coercing limb to unsigned long long might truncate"); - return ((i+1) * GMP_NUMB_BITS) - __builtin_clzll(x); - } - } - return 0; -} - -template -uint64_t bigint::as_uint64() const -{ - return this->data[0]; -} - -template -void bigint::to_mpz(mpz_t r) const -{ - mpz_set_ui(r, 0); - - for (int i = n-1; i >= 0; --i) - { - mpz_mul_2exp(r, r, GMP_NUMB_BITS); - mpz_add_ui(r, r, this->data[i]); - } -} - -template -bool bigint::test_bit(const std::size_t bitno) const -{ - if (bitno >= n * GMP_NUMB_BITS) - { - return false; - } - else - { - const std::size_t part = bitno/GMP_NUMB_BITS; - const std::size_t bit = bitno - (GMP_NUMB_BITS*part); - const mp_limb_t one = 1; - return (this->data[part] & (one< template -inline void bigint::operator+=(const bigint& other) -{ - static_assert(n >= m, "first arg must not be smaller than second arg for bigint in-place add"); - mpn_add(data, data, n, other.data, m); -} - -template template -inline bigint bigint::operator*(const bigint& other) const -{ - static_assert(n >= m, "first arg must not be smaller than second arg for bigint mul"); - bigint res; - mpn_mul(res.data, data, n, other.data, m); - return res; -} - -template template -inline void bigint::div_qr(bigint& quotient, bigint& remainder, - const bigint& dividend, const bigint& divisor) -{ - static_assert(n >= d, "dividend must not be smaller than divisor for bigint::div_qr"); - assert_except(divisor.data[d-1] != 0); - mpn_tdiv_qr(quotient.data, remainder.data, 0, dividend.data, n, divisor.data, d); -} - -// Return a copy shortened to m limbs provided it is less than limit, throwing std::domain_error if not in range. -template template -inline bigint bigint::shorten(const bigint& q, const char *msg) const -{ - static_assert(m <= n, "number of limbs must not increase for bigint::shorten"); - for (mp_size_t i = m; i < n; i++) { // high-order limbs - if (data[i] != 0) { - throw std::domain_error(msg); - } - } - bigint res; - mpn_copyi(res.data, data, m); - res.limit(q, msg); - return res; -} - -template -inline void bigint::limit(const bigint& q, const char *msg) const -{ - if (!(q > *this)) { - throw std::domain_error(msg); - } -} - -template -inline bool bigint::operator>(const bigint& other) const -{ - return mpn_cmp(this->data, other.data, n) > 0; -} - -template -bigint& bigint::randomize() -{ - assert_except(GMP_NUMB_BITS == sizeof(mp_limb_t) * 8); - - randombytes_buf(this->data, sizeof(mp_limb_t) * n); - - return (*this); -} - - -template -std::ostream& operator<<(std::ostream &out, const bigint &b) -{ -#ifdef BINARY_OUTPUT - out.write((char*)b.data, sizeof(b.data[0]) * n); -#else - mpz_t t; - mpz_init(t); - b.to_mpz(t); - - out << t; - - mpz_clear(t); -#endif - return out; -} - -template -std::istream& operator>>(std::istream &in, bigint &b) -{ -#ifdef BINARY_OUTPUT - in.read((char*)b.data, sizeof(b.data[0]) * n); -#else - std::string s; - in >> s; - - size_t l = s.size(); - unsigned char* s_copy = new unsigned char[l]; - - for (size_t i = 0; i < l; ++i) - { - assert_except(s[i] >= '0' && s[i] <= '9'); - s_copy[i] = s[i] - '0'; - } - - mp_size_t limbs_written = mpn_set_str(b.data, s_copy, l, 10); - assert_except(limbs_written <= n); - - delete[] s_copy; -#endif - return in; -} - -} // libsnark -#endif // BIGINT_TCC_ diff --git a/src/snark/libsnark/algebra/fields/field_utils.hpp b/src/snark/libsnark/algebra/fields/field_utils.hpp deleted file mode 100644 index 8358e48b3..000000000 --- a/src/snark/libsnark/algebra/fields/field_utils.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FIELD_UTILS_HPP_ -#define FIELD_UTILS_HPP_ -#include - -#include "common/utils.hpp" -#include "algebra/fields/bigint.hpp" - -namespace libsnark { - -// returns root of unity of order n (for n a power of 2), if one exists -template -FieldT get_root_of_unity(const uint64_t n); - -template -std::vector pack_int_vector_into_field_element_vector(const std::vector &v, const uint64_t w); - -template -std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v, const uint64_t chunk_bits); - -template -std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v); - -template -std::vector convert_bit_vector_to_field_element_vector(const bit_vector &v); - -template -bit_vector convert_field_element_vector_to_bit_vector(const std::vector &v); - -template -bit_vector convert_field_element_to_bit_vector(const FieldT &el); - -template -bit_vector convert_field_element_to_bit_vector(const FieldT &el, const uint64_t bitcount); - -template -FieldT convert_bit_vector_to_field_element(const bit_vector &v); - -template -void batch_invert(std::vector &vec); - -} // libsnark -#include "algebra/fields/field_utils.tcc" - -#endif // FIELD_UTILS_HPP_ diff --git a/src/snark/libsnark/algebra/fields/field_utils.tcc b/src/snark/libsnark/algebra/fields/field_utils.tcc deleted file mode 100644 index a0928605d..000000000 --- a/src/snark/libsnark/algebra/fields/field_utils.tcc +++ /dev/null @@ -1,184 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of misc. math and serialization utility functions - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FIELD_UTILS_TCC_ -#define FIELD_UTILS_TCC_ - -#include "common/utils.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -template -FieldT coset_shift() -{ - return FieldT::multiplicative_generator.squared(); -} - -template -FieldT get_root_of_unity(const uint64_t n) -{ - const uint64_t logn = log2(n); - assert_except(n == (1u << logn)); - assert_except(logn <= FieldT::s); - - FieldT omega = FieldT::root_of_unity; - for (uint64_t i = FieldT::s; i > logn; --i) - { - omega *= omega; - } - - return omega; -} - -template -std::vector pack_int_vector_into_field_element_vector(const std::vector &v, const uint64_t w) -{ - const uint64_t chunk_bits = FieldT::capacity(); - const uint64_t repacked_size = div_ceil(v.size() * w, chunk_bits); - std::vector result(repacked_size); - - for (uint64_t i = 0; i < repacked_size; ++i) - { - bigint b; - for (uint64_t j = 0; j < chunk_bits; ++j) - { - const uint64_t word_index = (i * chunk_bits + j) / w; - const uint64_t pos_in_word = (i * chunk_bits + j) % w; - const uint64_t word_or_0 = (word_index < v.size() ? v[word_index] : 0); - const uint64_t bit = (word_or_0 >> pos_in_word) & 1; - - b.data[j / GMP_NUMB_BITS] |= bit << (j % GMP_NUMB_BITS); - } - result[i] = FieldT(b); - } - - return result; -} - -template -std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v, const uint64_t chunk_bits) -{ - assert_except(chunk_bits <= FieldT::capacity()); - - const uint64_t repacked_size = div_ceil(v.size(), chunk_bits); - std::vector result(repacked_size); - - for (size_t i = 0; i < repacked_size; ++i) - { - bigint b; - for (size_t j = 0; j < chunk_bits; ++j) - { - b.data[j / GMP_NUMB_BITS] |= ((i * chunk_bits + j) < v.size() && v[i * chunk_bits + j] ? 1ll : 0ll) << (j % GMP_NUMB_BITS); - } - result[i] = FieldT(b); - } - - return result; -} - -template -std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v) -{ - return pack_bit_vector_into_field_element_vector(v, FieldT::capacity()); -} - -template -std::vector convert_bit_vector_to_field_element_vector(const bit_vector &v) -{ - std::vector result; - result.reserve(v.size()); - - for (const bool b : v) - { - result.emplace_back(b ? FieldT::one() : FieldT::zero()); - } - - return result; -} - -template -bit_vector convert_field_element_vector_to_bit_vector(const std::vector &v) -{ - bit_vector result; - - for (const FieldT &el : v) - { - const bit_vector el_bits = convert_field_element_to_bit_vector(el); - result.insert(result.end(), el_bits.begin(), el_bits.end()); - } - - return result; -} - -template -bit_vector convert_field_element_to_bit_vector(const FieldT &el) -{ - bit_vector result; - - bigint b = el.as_bigint(); - for (size_t i = 0; i < FieldT::size_in_bits(); ++i) - { - result.push_back(b.test_bit(i)); - } - - return result; -} - -template -bit_vector convert_field_element_to_bit_vector(const FieldT &el, const uint64_t bitcount) -{ - bit_vector result = convert_field_element_to_bit_vector(el); - result.resize(bitcount); - - return result; -} - -template -FieldT convert_bit_vector_to_field_element(const bit_vector &v) -{ - assert_except(v.size() <= FieldT::size_in_bits()); - - FieldT res = FieldT::zero(); - FieldT c = FieldT::one(); - for (bool b : v) - { - res += b ? c : FieldT::zero(); - c += c; - } - return res; -} - -template -void batch_invert(std::vector &vec) -{ - std::vector prod; - prod.reserve(vec.size()); - - FieldT acc = FieldT::one(); - - for (auto el : vec) - { - assert_except(!el.is_zero()); - prod.emplace_back(acc); - acc = acc * el; - } - - FieldT acc_inverse = acc.inverse(); - - for (int64_t i = vec.size()-1; i >= 0; --i) - { - const FieldT old_el = vec[i]; - vec[i] = acc_inverse * prod[i]; - acc_inverse = acc_inverse * old_el; - } -} - -} // libsnark -#endif // FIELD_UTILS_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp.hpp b/src/snark/libsnark/algebra/fields/fp.hpp deleted file mode 100644 index eae4634b6..000000000 --- a/src/snark/libsnark/algebra/fields/fp.hpp +++ /dev/null @@ -1,182 +0,0 @@ -/** @file - ***************************************************************************** - Declaration of arithmetic in the finite field F[p], for prime p of fixed length. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP_HPP_ -#define FP_HPP_ - -#include "algebra/fields/bigint.hpp" -#include "algebra/exponentiation/exponentiation.hpp" - -namespace libsnark { - -template& modulus> -class Fp_model; - -template& modulus> -std::ostream& operator<<(std::ostream &, const Fp_model&); - -template& modulus> -std::istream& operator>>(std::istream &, Fp_model &); - -/** - * Arithmetic in the finite field F[p], for prime p of fixed length. - * - * This class implements Fp-arithmetic, for a large prime p, using a fixed number - * of words. It is optimized for tight memory consumption, so the modulus p is - * passed as a template parameter, to avoid per-element overheads. - * - * The implementation is mostly a wrapper around GMP's MPN (constant-size integers). - * But for the integer sizes of interest for libsnark (3 to 5 limbs of 64 bits each), - * we implement performance-critical routines, like addition and multiplication, - * using hand-optimzied assembly code. -*/ -template& modulus> -class Fp_model { -public: - bigint mont_repr; -public: - static const mp_size_t num_limbs = n; - static const constexpr bigint& mod = modulus; -#ifdef PROFILE_OP_COUNTS - static int64_t add_cnt; - static int64_t sub_cnt; - static int64_t mul_cnt; - static int64_t sqr_cnt; - static int64_t inv_cnt; -#endif - static uint64_t num_bits; - static bigint euler; // (modulus-1)/2 - static uint64_t s; // modulus = 2^s * t + 1 - static bigint t; // with t odd - static bigint t_minus_1_over_2; // (t-1)/2 - static Fp_model nqr; // a quadratic nonresidue - static Fp_model nqr_to_t; // nqr^t - static Fp_model multiplicative_generator; // generator of Fp^* - static Fp_model root_of_unity; // generator^((modulus-1)/2^s) - static mp_limb_t inv; // modulus^(-1) mod W, where W = 2^(word size) - static bigint Rsquared; // R^2, where R = W^k, where k = ?? - static bigint Rcubed; // R^3 - - static bool modulus_is_valid() { return modulus.data[n-1] != 0; } // mpn inverse assumes that highest limb is non-zero - - Fp_model() {}; - Fp_model(const bigint &b); - Fp_model(const int64_t x, const bool is_unsigned=false); - - void set_uint64(const uint64_t x); - - void mul_reduce(const bigint &other); - - void clear(); - - /* Return the standard (not Montgomery) representation of the - Field element's requivalence class. I.e. Fp(2).as_bigint() - would return bigint(2) */ - bigint as_bigint() const; - /* Return the last limb of the standard representation of the - field element. E.g. on 64-bit architectures Fp(123).as_uint64() - and Fp(2^64+123).as_uint64() would both return 123. */ - uint64_t as_uint64() const; - - bool operator==(const Fp_model& other) const; - bool operator!=(const Fp_model& other) const; - bool is_zero() const; - - void print() const; - - Fp_model& operator+=(const Fp_model& other); - Fp_model& operator-=(const Fp_model& other); - Fp_model& operator*=(const Fp_model& other); - Fp_model& operator^=(const uint64_t pow); - - template - Fp_model& operator^=(const bigint &pow); - - Fp_model operator+(const Fp_model& other) const; - Fp_model operator-(const Fp_model& other) const; - Fp_model operator*(const Fp_model& other) const; - Fp_model operator-() const; - Fp_model squared() const; - Fp_model& invert(); - Fp_model inverse() const; - Fp_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) - - Fp_model operator^(const uint64_t pow) const; - template - Fp_model operator^(const bigint &pow) const; - - static uint64_t size_in_bits() { return num_bits; } - static uint64_t capacity() { return num_bits - 1; } - static bigint field_char() { return modulus; } - - static Fp_model zero(); - static Fp_model one(); - static Fp_model random_element(); - - friend std::ostream& operator<< (std::ostream &out, const Fp_model &p); - friend std::istream& operator>> (std::istream &in, Fp_model &p); -}; - -#ifdef PROFILE_OP_COUNTS -template& modulus> -int64_t Fp_model::add_cnt = 0; - -template& modulus> -int64_t Fp_model::sub_cnt = 0; - -template& modulus> -int64_t Fp_model::mul_cnt = 0; - -template& modulus> -int64_t Fp_model::sqr_cnt = 0; - -template& modulus> -int64_t Fp_model::inv_cnt = 0; -#endif - -template& modulus> -uint64_t Fp_model::num_bits; - -template& modulus> -bigint Fp_model::euler; - -template& modulus> -uint64_t Fp_model::s; - -template& modulus> -bigint Fp_model::t; - -template& modulus> -bigint Fp_model::t_minus_1_over_2; - -template& modulus> -Fp_model Fp_model::nqr; - -template& modulus> -Fp_model Fp_model::nqr_to_t; - -template& modulus> -Fp_model Fp_model::multiplicative_generator; - -template& modulus> -Fp_model Fp_model::root_of_unity; - -template& modulus> -mp_limb_t Fp_model::inv; - -template& modulus> -bigint Fp_model::Rsquared; - -template& modulus> -bigint Fp_model::Rcubed; - -} // libsnark -#include "algebra/fields/fp.tcc" - -#endif // FP_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp.tcc b/src/snark/libsnark/algebra/fields/fp.tcc deleted file mode 100644 index f1d97153f..000000000 --- a/src/snark/libsnark/algebra/fields/fp.tcc +++ /dev/null @@ -1,790 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of arithmetic in the finite field F[p], for prime p of fixed length. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP_TCC_ -#define FP_TCC_ -#include -#include -#include - -#include "algebra/fields/fp_aux.tcc" -#include "algebra/fields/field_utils.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -template& modulus> -void Fp_model::mul_reduce(const bigint &other) -{ - /* stupid pre-processor tricks; beware */ -#if defined(__x86_64__) && defined(USE_ASM) - if (n == 3) - { // Use asm-optimized Comba multiplication and reduction - mp_limb_t res[2*n]; - mp_limb_t c0, c1, c2; - COMBA_3_BY_3_MUL(c0, c1, c2, res, this->mont_repr.data, other.data); - - mp_limb_t k; - mp_limb_t tmp1, tmp2, tmp3; - REDUCE_6_LIMB_PRODUCT(k, tmp1, tmp2, tmp3, inv, res, modulus.data); - - /* subtract t > mod */ - __asm__ - ("/* check for overflow */ \n\t" - MONT_CMP(16) - MONT_CMP(8) - MONT_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - MONT_FIRSTSUB - MONT_NEXTSUB(8) - MONT_NEXTSUB(16) - "done%=: \n\t" - : - : [tmp] "r" (res+n), [M] "r" (modulus.data) - : "cc", "memory", "%rax"); - mpn_copyi(this->mont_repr.data, res+n, n); - } - else if (n == 4) - { // use asm-optimized "CIOS method" - - mp_limb_t tmp[n+1]; - mp_limb_t T0=0, T1=1, cy=2, u=3; // TODO: fix this - - __asm__ (MONT_PRECOMPUTE - MONT_FIRSTITER(1) - MONT_FIRSTITER(2) - MONT_FIRSTITER(3) - MONT_FINALIZE(3) - MONT_ITERFIRST(1) - MONT_ITERITER(1, 1) - MONT_ITERITER(1, 2) - MONT_ITERITER(1, 3) - MONT_FINALIZE(3) - MONT_ITERFIRST(2) - MONT_ITERITER(2, 1) - MONT_ITERITER(2, 2) - MONT_ITERITER(2, 3) - MONT_FINALIZE(3) - MONT_ITERFIRST(3) - MONT_ITERITER(3, 1) - MONT_ITERITER(3, 2) - MONT_ITERITER(3, 3) - MONT_FINALIZE(3) - "/* check for overflow */ \n\t" - MONT_CMP(24) - MONT_CMP(16) - MONT_CMP(8) - MONT_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - MONT_FIRSTSUB - MONT_NEXTSUB(8) - MONT_NEXTSUB(16) - MONT_NEXTSUB(24) - "done%=: \n\t" - : - : [tmp] "r" (tmp), [A] "r" (this->mont_repr.data), [B] "r" (other.data), [inv] "r" (inv), [M] "r" (modulus.data), - [T0] "r" (T0), [T1] "r" (T1), [cy] "r" (cy), [u] "r" (u) - : "cc", "memory", "%rax", "%rdx" - ); - mpn_copyi(this->mont_repr.data, tmp, n); - } - else if (n == 5) - { // use asm-optimized "CIOS method" - - mp_limb_t tmp[n+1]; - mp_limb_t T0=0, T1=1, cy=2, u=3; // TODO: fix this - - __asm__ (MONT_PRECOMPUTE - MONT_FIRSTITER(1) - MONT_FIRSTITER(2) - MONT_FIRSTITER(3) - MONT_FIRSTITER(4) - MONT_FINALIZE(4) - MONT_ITERFIRST(1) - MONT_ITERITER(1, 1) - MONT_ITERITER(1, 2) - MONT_ITERITER(1, 3) - MONT_ITERITER(1, 4) - MONT_FINALIZE(4) - MONT_ITERFIRST(2) - MONT_ITERITER(2, 1) - MONT_ITERITER(2, 2) - MONT_ITERITER(2, 3) - MONT_ITERITER(2, 4) - MONT_FINALIZE(4) - MONT_ITERFIRST(3) - MONT_ITERITER(3, 1) - MONT_ITERITER(3, 2) - MONT_ITERITER(3, 3) - MONT_ITERITER(3, 4) - MONT_FINALIZE(4) - MONT_ITERFIRST(4) - MONT_ITERITER(4, 1) - MONT_ITERITER(4, 2) - MONT_ITERITER(4, 3) - MONT_ITERITER(4, 4) - MONT_FINALIZE(4) - "/* check for overflow */ \n\t" - MONT_CMP(32) - MONT_CMP(24) - MONT_CMP(16) - MONT_CMP(8) - MONT_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - MONT_FIRSTSUB - MONT_NEXTSUB(8) - MONT_NEXTSUB(16) - MONT_NEXTSUB(24) - MONT_NEXTSUB(32) - "done%=: \n\t" - : - : [tmp] "r" (tmp), [A] "r" (this->mont_repr.data), [B] "r" (other.data), [inv] "r" (inv), [M] "r" (modulus.data), - [T0] "r" (T0), [T1] "r" (T1), [cy] "r" (cy), [u] "r" (u) - : "cc", "memory", "%rax", "%rdx" - ); - mpn_copyi(this->mont_repr.data, tmp, n); - } - else -#endif - { - mp_limb_t res[2*n]; - mpn_mul_n(res, this->mont_repr.data, other.data, n); - - /* - The Montgomery reduction here is based on Algorithm 14.32 in - Handbook of Applied Cryptography - . - */ - for (size_t i = 0; i < n; ++i) - { - mp_limb_t k = inv * res[i]; - /* calculate res = res + k * mod * b^i */ - mp_limb_t carryout = mpn_addmul_1(res+i, modulus.data, n, k); - carryout = mpn_add_1(res+n+i, res+n+i, n-i, carryout); - assert_except(carryout == 0); - } - - if (mpn_cmp(res+n, modulus.data, n) >= 0) - { - const mp_limb_t borrow = mpn_sub(res+n, res+n, n, modulus.data, n); - assert_except(borrow == 0); - } - - mpn_copyi(this->mont_repr.data, res+n, n); - } -} - -template& modulus> -Fp_model::Fp_model(const bigint &b) -{ - mpn_copyi(this->mont_repr.data, Rsquared.data, n); - mul_reduce(b); -} - -template& modulus> -Fp_model::Fp_model(const int64_t x, const bool is_unsigned) -{ - if (is_unsigned || x >= 0) - { - this->mont_repr.data[0] = x; - } - else - { - const mp_limb_t borrow = mpn_sub_1(this->mont_repr.data, modulus.data, n, -x); - assert_except(borrow == 0); - } - - mul_reduce(Rsquared); -} - -template& modulus> -void Fp_model::set_uint64(const uint64_t x) -{ - this->mont_repr.clear(); - this->mont_repr.data[0] = x; - mul_reduce(Rsquared); -} - -template& modulus> -void Fp_model::clear() -{ - this->mont_repr.clear(); -} - -template& modulus> -bigint Fp_model::as_bigint() const -{ - bigint one; - one.clear(); - one.data[0] = 1; - - Fp_model res(*this); - res.mul_reduce(one); - - return (res.mont_repr); -} - -template& modulus> -uint64_t Fp_model::as_uint64() const -{ - return this->as_bigint().as_uint64(); -} - -template& modulus> -bool Fp_model::operator==(const Fp_model& other) const -{ - return (this->mont_repr == other.mont_repr); -} - -template& modulus> -bool Fp_model::operator!=(const Fp_model& other) const -{ - return (this->mont_repr != other.mont_repr); -} - -template& modulus> -bool Fp_model::is_zero() const -{ - return (this->mont_repr.is_zero()); // zero maps to zero -} - -template& modulus> -void Fp_model::print() const -{ - Fp_model tmp; - tmp.mont_repr.data[0] = 1; - tmp.mul_reduce(this->mont_repr); - - tmp.mont_repr.print(); -} - -template& modulus> -Fp_model Fp_model::zero() -{ - Fp_model res; - res.mont_repr.clear(); - return res; -} - -template& modulus> -Fp_model Fp_model::one() -{ - Fp_model res; - res.mont_repr.data[0] = 1; - res.mul_reduce(Rsquared); - return res; -} - -template& modulus> -Fp_model& Fp_model::operator+=(const Fp_model& other) -{ -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif -#if defined(__x86_64__) && defined(USE_ASM) - if (n == 3) - { - __asm__ - ("/* perform bignum addition */ \n\t" - ADD_FIRSTADD - ADD_NEXTADD(8) - ADD_NEXTADD(16) - "/* if overflow: subtract */ \n\t" - "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" - "jc subtract%= \n\t" - - "/* check for overflow */ \n\t" - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - ADD_FIRSTSUB - ADD_NEXTSUB(8) - ADD_NEXTSUB(16) - "done%=: \n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else if (n == 4) - { - __asm__ - ("/* perform bignum addition */ \n\t" - ADD_FIRSTADD - ADD_NEXTADD(8) - ADD_NEXTADD(16) - ADD_NEXTADD(24) - "/* if overflow: subtract */ \n\t" - "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" - "jc subtract%= \n\t" - - "/* check for overflow */ \n\t" - ADD_CMP(24) - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - ADD_FIRSTSUB - ADD_NEXTSUB(8) - ADD_NEXTSUB(16) - ADD_NEXTSUB(24) - "done%=: \n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else if (n == 5) - { - __asm__ - ("/* perform bignum addition */ \n\t" - ADD_FIRSTADD - ADD_NEXTADD(8) - ADD_NEXTADD(16) - ADD_NEXTADD(24) - ADD_NEXTADD(32) - "/* if overflow: subtract */ \n\t" - "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" - "jc subtract%= \n\t" - - "/* check for overflow */ \n\t" - ADD_CMP(32) - ADD_CMP(24) - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - ADD_FIRSTSUB - ADD_NEXTSUB(8) - ADD_NEXTSUB(16) - ADD_NEXTSUB(24) - ADD_NEXTSUB(32) - "done%=: \n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else -#endif - { - mp_limb_t scratch[n+1]; - const mp_limb_t carry = mpn_add_n(scratch, this->mont_repr.data, other.mont_repr.data, n); - scratch[n] = carry; - - if (carry || mpn_cmp(scratch, modulus.data, n) >= 0) - { - const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, modulus.data, n); - assert_except(borrow == 0); - } - - mpn_copyi(this->mont_repr.data, scratch, n); - } - - return *this; -} - -template& modulus> -Fp_model& Fp_model::operator-=(const Fp_model& other) -{ -#ifdef PROFILE_OP_COUNTS - this->sub_cnt++; -#endif -#if defined(__x86_64__) && defined(USE_ASM) - if (n == 3) - { - __asm__ - (SUB_FIRSTSUB - SUB_NEXTSUB(8) - SUB_NEXTSUB(16) - - "jnc done%=\n\t" - - SUB_FIRSTADD - SUB_NEXTADD(8) - SUB_NEXTADD(16) - - "done%=:\n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else if (n == 4) - { - __asm__ - (SUB_FIRSTSUB - SUB_NEXTSUB(8) - SUB_NEXTSUB(16) - SUB_NEXTSUB(24) - - "jnc done%=\n\t" - - SUB_FIRSTADD - SUB_NEXTADD(8) - SUB_NEXTADD(16) - SUB_NEXTADD(24) - - "done%=:\n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else if (n == 5) - { - __asm__ - (SUB_FIRSTSUB - SUB_NEXTSUB(8) - SUB_NEXTSUB(16) - SUB_NEXTSUB(24) - SUB_NEXTSUB(32) - - "jnc done%=\n\t" - - SUB_FIRSTADD - SUB_NEXTADD(8) - SUB_NEXTADD(16) - SUB_NEXTADD(24) - SUB_NEXTADD(32) - - "done%=:\n\t" - : - : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) - : "cc", "memory", "%rax"); - } - else -#endif - { - mp_limb_t scratch[n+1]; - if (mpn_cmp(this->mont_repr.data, other.mont_repr.data, n) < 0) - { - const mp_limb_t carry = mpn_add_n(scratch, this->mont_repr.data, modulus.data, n); - scratch[n] = carry; - } - else - { - mpn_copyi(scratch, this->mont_repr.data, n); - scratch[n] = 0; - } - - const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, other.mont_repr.data, n); - assert_except(borrow == 0); - - mpn_copyi(this->mont_repr.data, scratch, n); - } - return *this; -} - -template& modulus> -Fp_model& Fp_model::operator*=(const Fp_model& other) -{ -#ifdef PROFILE_OP_COUNTS - this->mul_cnt++; -#endif - - mul_reduce(other.mont_repr); - return *this; -} - -template& modulus> -Fp_model& Fp_model::operator^=(const uint64_t pow) -{ - (*this) = power >(*this, pow); - return (*this); -} - -template& modulus> -template -Fp_model& Fp_model::operator^=(const bigint &pow) -{ - (*this) = power, m>(*this, pow); - return (*this); -} - -template& modulus> -Fp_model Fp_model::operator+(const Fp_model& other) const -{ - Fp_model r(*this); - return (r += other); -} - -template& modulus> -Fp_model Fp_model::operator-(const Fp_model& other) const -{ - Fp_model r(*this); - return (r -= other); -} - -template& modulus> -Fp_model Fp_model::operator*(const Fp_model& other) const -{ - Fp_model r(*this); - return (r *= other); -} - -template& modulus> -Fp_model Fp_model::operator^(const uint64_t pow) const -{ - Fp_model r(*this); - return (r ^= pow); -} - -template& modulus> -template -Fp_model Fp_model::operator^(const bigint &pow) const -{ - Fp_model r(*this); - return (r ^= pow); -} - -template& modulus> -Fp_model Fp_model::operator-() const -{ -#ifdef PROFILE_OP_COUNTS - this->sub_cnt++; -#endif - - if (this->is_zero()) - { - return (*this); - } - else - { - Fp_model r; - mpn_sub_n(r.mont_repr.data, modulus.data, this->mont_repr.data, n); - return r; - } -} - -template& modulus> -Fp_model Fp_model::squared() const -{ -#ifdef PROFILE_OP_COUNTS - this->sqr_cnt++; - this->mul_cnt--; // zero out the upcoming mul -#endif - /* stupid pre-processor tricks; beware */ -#if defined(__x86_64__) && defined(USE_ASM) - if (n == 3) - { // use asm-optimized Comba squaring - mp_limb_t res[2*n]; - mp_limb_t c0, c1, c2; - COMBA_3_BY_3_SQR(c0, c1, c2, res, this->mont_repr.data); - - mp_limb_t k; - mp_limb_t tmp1, tmp2, tmp3; - REDUCE_6_LIMB_PRODUCT(k, tmp1, tmp2, tmp3, inv, res, modulus.data); - - /* subtract t > mod */ - __asm__ volatile - ("/* check for overflow */ \n\t" - MONT_CMP(16) - MONT_CMP(8) - MONT_CMP(0) - - "/* subtract mod if overflow */ \n\t" - "subtract%=: \n\t" - MONT_FIRSTSUB - MONT_NEXTSUB(8) - MONT_NEXTSUB(16) - "done%=: \n\t" - : - : [tmp] "r" (res+n), [M] "r" (modulus.data) - : "cc", "memory", "%rax"); - - Fp_model r; - mpn_copyi(r.mont_repr.data, res+n, n); - return r; - } - else -#endif - { - Fp_model r(*this); - return (r *= r); - } -} - -template& modulus> -Fp_model& Fp_model::invert() -{ -#ifdef PROFILE_OP_COUNTS - this->inv_cnt++; -#endif - - assert_except(!this->is_zero()); - - bigint g; /* gp should have room for vn = n limbs */ - - mp_limb_t s[n+1]; /* sp should have room for vn+1 limbs */ - mp_size_t sn; - - bigint v = modulus; // both source operands are destroyed by mpn_gcdext - - /* computes gcd(u, v) = g = u*s + v*t, so s*u will be 1 (mod v) */ - const mp_size_t gn = mpn_gcdext(g.data, s, &sn, this->mont_repr.data, n, v.data, n); - assert_except(gn == 1 && g.data[0] == 1); /* inverse exists */ - - mp_limb_t q; /* division result fits into q, as sn <= n+1 */ - /* sn < 0 indicates negative sn; will fix up later */ - - if (std::abs(sn) >= n) - { - /* if sn could require modulus reduction, do it here */ - mpn_tdiv_qr(&q, this->mont_repr.data, 0, s, std::abs(sn), modulus.data, n); - } - else - { - /* otherwise just copy it over */ - mpn_zero(this->mont_repr.data, n); - mpn_copyi(this->mont_repr.data, s, std::abs(sn)); - } - - /* fix up the negative sn */ - if (sn < 0) - { - const mp_limb_t borrow = mpn_sub_n(this->mont_repr.data, modulus.data, this->mont_repr.data, n); - assert_except(borrow == 0); - } - - mul_reduce(Rcubed); - return *this; -} - -template& modulus> -Fp_model Fp_model::inverse() const -{ - Fp_model r(*this); - return (r.invert()); -} - -template& modulus> -Fp_model Fp_model::random_element() /// returns random element of Fp_model -{ - /* note that as Montgomery representation is a bijection then - selecting a random element of {xR} is the same as selecting a - random element of {x} */ - Fp_model r; - do - { - r.mont_repr.randomize(); - - /* clear all bits higher than MSB of modulus */ - uint64_t bitno = GMP_NUMB_BITS * n - 1; - while (modulus.test_bit(bitno) == false) - { - const uint64_t part = bitno/GMP_NUMB_BITS; - const uint64_t bit = bitno - (GMP_NUMB_BITS*part); - - r.mont_repr.data[part] &= ~(UINT64_C(1)<= modulus -- repeat (rejection sampling) */ - while (mpn_cmp(r.mont_repr.data, modulus.data, n) >= 0); - - return r; -} - -template& modulus> -Fp_model Fp_model::sqrt() const -{ - if (is_zero()) { - return *this; - } - - Fp_model one = Fp_model::one(); - - uint64_t v = Fp_model::s; - Fp_model z = Fp_model::nqr_to_t; - Fp_model w = (*this)^Fp_model::t_minus_1_over_2; - Fp_model x = (*this) * w; - Fp_model b = x * w; // b = (*this)^t - - - // check if square with euler's criterion - Fp_model check = b; - for (size_t i = 0; i < v-1; ++i) - { - check = check.squared(); - } - if (check != one) - { - assert_except(0); - } - - - // compute square root with Tonelli--Shanks - // (does not terminate if not a square!) - - while (b != one) - { - uint64_t m = 0; - Fp_model b2m = b; - while (b2m != one) - { - /* invariant: b2m = b^(2^m) after entering this loop */ - b2m = b2m.squared(); - m += 1; - } - - int j = v-m-1; - w = z; - while (j > 0) - { - w = w.squared(); - --j; - } // w = z^2^(v-m-1) - - z = w.squared(); - b = b * z; - x = x * w; - v = m; - } - - return x; -} - -template& modulus> -std::ostream& operator<<(std::ostream &out, const Fp_model &p) -{ -#ifndef MONTGOMERY_OUTPUT - Fp_model tmp; - tmp.mont_repr.data[0] = 1; - tmp.mul_reduce(p.mont_repr); - out << tmp.mont_repr; -#else - out << p.mont_repr; -#endif - return out; -} - -template& modulus> -std::istream& operator>>(std::istream &in, Fp_model &p) -{ -#ifndef MONTGOMERY_OUTPUT - in >> p.mont_repr; - p.mul_reduce(Fp_model::Rsquared); -#else - in >> p.mont_repr; -#endif - return in; -} - -} // libsnark -#endif // FP_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp b/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp deleted file mode 100644 index 69d057a05..000000000 --- a/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/** @file - ***************************************************************************** - Declaration of arithmetic in the finite field F[((p^2)^3)^2]. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP12_2OVER3OVER2_HPP_ -#define FP12_2OVER3OVER2_HPP_ -#include "algebra/fields/fp.hpp" -#include "algebra/fields/fp2.hpp" -#include "algebra/fields/fp6_3over2.hpp" -#include - -namespace libsnark { - -template& modulus> -class Fp12_2over3over2_model; - -template& modulus> -std::ostream& operator<<(std::ostream &, const Fp12_2over3over2_model &); - -template& modulus> -std::istream& operator>>(std::istream &, Fp12_2over3over2_model &); - -/** - * Arithmetic in the finite field F[((p^2)^3)^2]. - * - * Let p := modulus. This interface provides arithmetic for the extension field - * Fp12 = Fp6[W]/(W^2-V) where Fp6 = Fp2[V]/(V^3-non_residue) and non_residue is in Fp2 - * - * ASSUMPTION: p = 1 (mod 6) - */ -template& modulus> -class Fp12_2over3over2_model { -public: - typedef Fp_model my_Fp; - typedef Fp2_model my_Fp2; - typedef Fp6_3over2_model my_Fp6; - - static Fp2_model non_residue; - static Fp2_model Frobenius_coeffs_c1[12]; // non_residue^((modulus^i-1)/6) for i=0,...,11 - - my_Fp6 c0, c1; - Fp12_2over3over2_model() {}; - Fp12_2over3over2_model(const my_Fp6& c0, const my_Fp6& c1) : c0(c0), c1(c1) {}; - - void clear() { c0.clear(); c1.clear(); } - void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); } - - static Fp12_2over3over2_model zero(); - static Fp12_2over3over2_model one(); - static Fp12_2over3over2_model random_element(); - - bool is_zero() const { return c0.is_zero() && c1.is_zero(); } - bool operator==(const Fp12_2over3over2_model &other) const; - bool operator!=(const Fp12_2over3over2_model &other) const; - - Fp12_2over3over2_model operator+(const Fp12_2over3over2_model &other) const; - Fp12_2over3over2_model operator-(const Fp12_2over3over2_model &other) const; - Fp12_2over3over2_model operator*(const Fp12_2over3over2_model &other) const; - Fp12_2over3over2_model operator-() const; - Fp12_2over3over2_model squared() const; // default is squared_complex - Fp12_2over3over2_model squared_karatsuba() const; - Fp12_2over3over2_model squared_complex() const; - Fp12_2over3over2_model inverse() const; - Fp12_2over3over2_model Frobenius_map(uint64_t power) const; - Fp12_2over3over2_model unitary_inverse() const; - Fp12_2over3over2_model cyclotomic_squared() const; - - Fp12_2over3over2_model mul_by_024(const my_Fp2 &ell_0, const my_Fp2 &ell_VW, const my_Fp2 &ell_VV) const; - - static my_Fp6 mul_by_non_residue(const my_Fp6 &elt); - - template - Fp12_2over3over2_model cyclotomic_exp(const bigint &exponent) const; - - static bigint base_field_char() { return modulus; } - static uint64_t extension_degree() { return 12; } - - friend std::ostream& operator<< (std::ostream &out, const Fp12_2over3over2_model &el); - friend std::istream& operator>> (std::istream &in, Fp12_2over3over2_model &el); -}; - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v); - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v); - -template& modulus> -Fp12_2over3over2_model operator*(const Fp_model &lhs, const Fp12_2over3over2_model &rhs); - -template& modulus> -Fp12_2over3over2_model operator*(const Fp2_model &lhs, const Fp12_2over3over2_model &rhs); - -template& modulus> -Fp12_2over3over2_model operator*(const Fp6_3over2_model &lhs, const Fp12_2over3over2_model &rhs); - -template& modulus, mp_size_t m> -Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const bigint &exponent); - -template& modulus, mp_size_t m, const bigint& exp_modulus> -Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const Fp_model &exponent); - -template& modulus> -Fp2_model Fp12_2over3over2_model::non_residue; - -template& modulus> -Fp2_model Fp12_2over3over2_model::Frobenius_coeffs_c1[12]; - -} // libsnark -#include "algebra/fields/fp12_2over3over2.tcc" -#endif // FP12_2OVER3OVER2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc b/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc deleted file mode 100644 index 64d2cf97c..000000000 --- a/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc +++ /dev/null @@ -1,412 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of arithmetic in the finite field F[((p^2)^3)^2]. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP12_2OVER3OVER2_TCC_ -#define FP12_2OVER3OVER2_TCC_ - -namespace libsnark { - -template& modulus> -Fp6_3over2_model Fp12_2over3over2_model::mul_by_non_residue(const Fp6_3over2_model &elt) -{ - return Fp6_3over2_model(non_residue * elt.c2, elt.c0, elt.c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::zero() -{ - return Fp12_2over3over2_model(my_Fp6::zero(), my_Fp6::zero()); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::one() -{ - return Fp12_2over3over2_model(my_Fp6::one(), my_Fp6::zero()); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::random_element() -{ - Fp12_2over3over2_model r; - r.c0 = my_Fp6::random_element(); - r.c1 = my_Fp6::random_element(); - - return r; -} - -template& modulus> -bool Fp12_2over3over2_model::operator==(const Fp12_2over3over2_model &other) const -{ - return (this->c0 == other.c0 && this->c1 == other.c1); -} - -template& modulus> -bool Fp12_2over3over2_model::operator!=(const Fp12_2over3over2_model &other) const -{ - return !(operator==(other)); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::operator+(const Fp12_2over3over2_model &other) const -{ - return Fp12_2over3over2_model(this->c0 + other.c0, - this->c1 + other.c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::operator-(const Fp12_2over3over2_model &other) const -{ - return Fp12_2over3over2_model(this->c0 - other.c0, - this->c1 - other.c1); -} - -template& modulus> -Fp12_2over3over2_model operator*(const Fp_model &lhs, const Fp12_2over3over2_model &rhs) -{ - return Fp12_2over3over2_model(lhs*rhs.c0, - lhs*rhs.c1); -} - -template& modulus> -Fp12_2over3over2_model operator*(const Fp2_model &lhs, const Fp12_2over3over2_model &rhs) -{ - return Fp12_2over3over2_model(lhs*rhs.c0, - lhs*rhs.c1); -} - -template& modulus> -Fp12_2over3over2_model operator*(const Fp6_3over2_model &lhs, const Fp12_2over3over2_model &rhs) -{ - return Fp12_2over3over2_model(lhs*rhs.c0, - lhs*rhs.c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::operator*(const Fp12_2over3over2_model &other) const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba) */ - - const my_Fp6 &A = other.c0, &B = other.c1, - &a = this->c0, &b = this->c1; - const my_Fp6 aA = a * A; - const my_Fp6 bB = b * B; - - return Fp12_2over3over2_model(aA + Fp12_2over3over2_model::mul_by_non_residue(bB), - (a + b)*(A+B) - aA - bB); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::operator-() const -{ - return Fp12_2over3over2_model(-this->c0, - -this->c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::squared() const -{ - return squared_complex(); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::squared_karatsuba() const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba squaring) */ - - const my_Fp6 &a = this->c0, &b = this->c1; - const my_Fp6 asq = a.squared(); - const my_Fp6 bsq = b.squared(); - - return Fp12_2over3over2_model(asq + Fp12_2over3over2_model::mul_by_non_residue(bsq), - (a + b).squared() - asq - bsq); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::squared_complex() const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Complex squaring) */ - - const my_Fp6 &a = this->c0, &b = this->c1; - const my_Fp6 ab = a * b; - - return Fp12_2over3over2_model((a + b) * (a + Fp12_2over3over2_model::mul_by_non_residue(b)) - ab - Fp12_2over3over2_model::mul_by_non_residue(ab), - ab + ab); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::inverse() const -{ - /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8 */ - - const my_Fp6 &a = this->c0, &b = this->c1; - const my_Fp6 t0 = a.squared(); - const my_Fp6 t1 = b.squared(); - const my_Fp6 t2 = t0 - Fp12_2over3over2_model::mul_by_non_residue(t1); - const my_Fp6 t3 = t2.inverse(); - const my_Fp6 c0 = a * t3; - const my_Fp6 c1 = - (b * t3); - - return Fp12_2over3over2_model(c0, c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::Frobenius_map(uint64_t power) const -{ - return Fp12_2over3over2_model(c0.Frobenius_map(power), - Frobenius_coeffs_c1[power % 12] * c1.Frobenius_map(power)); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::unitary_inverse() const -{ - return Fp12_2over3over2_model(this->c0, - -this->c1); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::cyclotomic_squared() const -{ - /* OLD: naive implementation - return (*this).squared(); - */ - my_Fp2 z0 = this->c0.c0; - my_Fp2 z4 = this->c0.c1; - my_Fp2 z3 = this->c0.c2; - my_Fp2 z2 = this->c1.c0; - my_Fp2 z1 = this->c1.c1; - my_Fp2 z5 = this->c1.c2; - - my_Fp2 t0, t1, t2, t3, t4, t5, tmp; - - // t0 + t1*y = (z0 + z1*y)^2 = a^2 - tmp = z0 * z1; - t0 = (z0 + z1) * (z0 + my_Fp6::non_residue * z1) - tmp - my_Fp6::non_residue * tmp; - t1 = tmp + tmp; - // t2 + t3*y = (z2 + z3*y)^2 = b^2 - tmp = z2 * z3; - t2 = (z2 + z3) * (z2 + my_Fp6::non_residue * z3) - tmp - my_Fp6::non_residue * tmp; - t3 = tmp + tmp; - // t4 + t5*y = (z4 + z5*y)^2 = c^2 - tmp = z4 * z5; - t4 = (z4 + z5) * (z4 + my_Fp6::non_residue * z5) - tmp - my_Fp6::non_residue * tmp; - t5 = tmp + tmp; - - // for A - - // z0 = 3 * t0 - 2 * z0 - z0 = t0 - z0; - z0 = z0 + z0; - z0 = z0 + t0; - // z1 = 3 * t1 + 2 * z1 - z1 = t1 + z1; - z1 = z1 + z1; - z1 = z1 + t1; - - // for B - - // z2 = 3 * (xi * t5) + 2 * z2 - tmp = my_Fp6::non_residue * t5; - z2 = tmp + z2; - z2 = z2 + z2; - z2 = z2 + tmp; - - // z3 = 3 * t4 - 2 * z3 - z3 = t4 - z3; - z3 = z3 + z3; - z3 = z3 + t4; - - // for C - - // z4 = 3 * t2 - 2 * z4 - z4 = t2 - z4; - z4 = z4 + z4; - z4 = z4 + t2; - - // z5 = 3 * t3 + 2 * z5 - z5 = t3 + z5; - z5 = z5 + z5; - z5 = z5 + t3; - - return Fp12_2over3over2_model(my_Fp6(z0,z4,z3),my_Fp6(z2,z1,z5)); -} - -template& modulus> -Fp12_2over3over2_model Fp12_2over3over2_model::mul_by_024(const Fp2_model &ell_0, - const Fp2_model &ell_VW, - const Fp2_model &ell_VV) const -{ - /* OLD: naive implementation - Fp12_2over3over2_model a(my_Fp6(ell_0, my_Fp2::zero(), ell_VV), - my_Fp6(my_Fp2::zero(), ell_VW, my_Fp2::zero())); - - return (*this) * a; - */ - my_Fp2 z0 = this->c0.c0; - my_Fp2 z1 = this->c0.c1; - my_Fp2 z2 = this->c0.c2; - my_Fp2 z3 = this->c1.c0; - my_Fp2 z4 = this->c1.c1; - my_Fp2 z5 = this->c1.c2; - - my_Fp2 x0 = ell_0; - my_Fp2 x2 = ell_VV; - my_Fp2 x4 = ell_VW; - - my_Fp2 t0, t1, t2, s0, T3, T4, D0, D2, D4, S1; - - D0 = z0 * x0; - D2 = z2 * x2; - D4 = z4 * x4; - t2 = z0 + z4; - t1 = z0 + z2; - s0 = z1 + z3 + z5; - - // For z.a_.a_ = z0. - S1 = z1 * x2; - T3 = S1 + D4; - T4 = my_Fp6::non_residue * T3 + D0; - z0 = T4; - - // For z.a_.b_ = z1 - T3 = z5 * x4; - S1 = S1 + T3; - T3 = T3 + D2; - T4 = my_Fp6::non_residue * T3; - T3 = z1 * x0; - S1 = S1 + T3; - T4 = T4 + T3; - z1 = T4; - - // For z.a_.c_ = z2 - t0 = x0 + x2; - T3 = t1 * t0 - D0 - D2; - T4 = z3 * x4; - S1 = S1 + T4; - T3 = T3 + T4; - - // For z.b_.a_ = z3 (z3 needs z2) - t0 = z2 + z4; - z2 = T3; - t1 = x2 + x4; - T3 = t0 * t1 - D2 - D4; - T4 = my_Fp6::non_residue * T3; - T3 = z3 * x0; - S1 = S1 + T3; - T4 = T4 + T3; - z3 = T4; - - // For z.b_.b_ = z4 - T3 = z5 * x2; - S1 = S1 + T3; - T4 = my_Fp6::non_residue * T3; - t0 = x0 + x4; - T3 = t2 * t0 - D0 - D4; - T4 = T4 + T3; - z4 = T4; - - // For z.b_.c_ = z5. - t0 = x0 + x2 + x4; - T3 = s0 * t0 - S1; - z5 = T3; - - return Fp12_2over3over2_model(my_Fp6(z0,z1,z2),my_Fp6(z3,z4,z5)); - -} - -template& modulus, mp_size_t m> -Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const bigint &exponent) -{ - return power >(self, exponent); -} - -template& modulus, mp_size_t m, const bigint& exp_modulus> -Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const Fp_model &exponent) -{ - return self^(exponent.as_bigint()); -} - - -template& modulus> -template -Fp12_2over3over2_model Fp12_2over3over2_model::cyclotomic_exp(const bigint &exponent) const -{ - Fp12_2over3over2_model res = Fp12_2over3over2_model::one(); - - bool found_one = false; - for (int64_t i = m-1; i >= 0; --i) - { - for (int64_t j = GMP_NUMB_BITS - 1; j >= 0; --j) - { - if (found_one) - { - res = res.cyclotomic_squared(); - } - - if (exponent.data[i] & (((mp_limb_t) 1)<& modulus> -std::ostream& operator<<(std::ostream &out, const Fp12_2over3over2_model &el) -{ - out << el.c0 << OUTPUT_SEPARATOR << el.c1; - return out; -} - -template& modulus> -std::istream& operator>>(std::istream &in, Fp12_2over3over2_model &el) -{ - in >> el.c0 >> el.c1; - return in; -} - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v) -{ - out << v.size() << "\n"; - for (const Fp12_2over3over2_model& t : v) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v) -{ - v.clear(); - - uint64_t s; - in >> s; - - char b; - in.read(&b, 1); - - v.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - Fp12_2over3over2_model el; - in >> el; - v.emplace_back(el); - } - - return in; -} - -} // libsnark -#endif // FP12_2OVER3OVER2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp2.hpp b/src/snark/libsnark/algebra/fields/fp2.hpp deleted file mode 100644 index f194f5ec5..000000000 --- a/src/snark/libsnark/algebra/fields/fp2.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of arithmetic in the finite field F[p^2]. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP2_HPP_ -#define FP2_HPP_ -#include "algebra/fields/fp.hpp" -#include - -namespace libsnark { - -template& modulus> -class Fp2_model; - -template& modulus> -std::ostream& operator<<(std::ostream &, const Fp2_model &); - -template& modulus> -std::istream& operator>>(std::istream &, Fp2_model &); - -/** - * Arithmetic in the field F[p^3]. - * - * Let p := modulus. This interface provides arithmetic for the extension field - * Fp2 = Fp[U]/(U^2-non_residue), where non_residue is in Fp. - * - * ASSUMPTION: p = 1 (mod 6) - */ -template& modulus> -class Fp2_model { -public: - typedef Fp_model my_Fp; - - static bigint<2*n> euler; // (modulus^2-1)/2 - static uint64_t s; // modulus^2 = 2^s * t + 1 - static bigint<2*n> t; // with t odd - static bigint<2*n> t_minus_1_over_2; // (t-1)/2 - static my_Fp non_residue; // X^4-non_residue irreducible over Fp; used for constructing Fp2 = Fp[X] / (X^2 - non_residue) - static Fp2_model nqr; // a quadratic nonresidue in Fp2 - static Fp2_model nqr_to_t; // nqr^t - static my_Fp Frobenius_coeffs_c1[2]; // non_residue^((modulus^i-1)/2) for i=0,1 - - my_Fp c0, c1; - Fp2_model() {}; - Fp2_model(const my_Fp& c0, const my_Fp& c1) : c0(c0), c1(c1) {}; - - void clear() { c0.clear(); c1.clear(); } - void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); } - - static Fp2_model zero(); - static Fp2_model one(); - static Fp2_model random_element(); - - bool is_zero() const { return c0.is_zero() && c1.is_zero(); } - bool operator==(const Fp2_model &other) const; - bool operator!=(const Fp2_model &other) const; - - Fp2_model operator+(const Fp2_model &other) const; - Fp2_model operator-(const Fp2_model &other) const; - Fp2_model operator*(const Fp2_model &other) const; - Fp2_model operator-() const; - Fp2_model squared() const; // default is squared_complex - Fp2_model inverse() const; - Fp2_model Frobenius_map(uint64_t power) const; - Fp2_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) - Fp2_model squared_karatsuba() const; - Fp2_model squared_complex() const; - - template - Fp2_model operator^(const bigint &other) const; - - static uint64_t size_in_bits() { return 2*my_Fp::size_in_bits(); } - static bigint base_field_char() { return modulus; } - - friend std::ostream& operator<< (std::ostream &out, const Fp2_model &el); - friend std::istream& operator>> (std::istream &in, Fp2_model &el); -}; - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v); - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v); - -template& modulus> -Fp2_model operator*(const Fp_model &lhs, const Fp2_model &rhs); - -template& modulus> -bigint<2*n> Fp2_model::euler; - -template& modulus> -uint64_t Fp2_model::s; - -template& modulus> -bigint<2*n> Fp2_model::t; - -template& modulus> -bigint<2*n> Fp2_model::t_minus_1_over_2; - -template& modulus> -Fp_model Fp2_model::non_residue; - -template& modulus> -Fp2_model Fp2_model::nqr; - -template& modulus> -Fp2_model Fp2_model::nqr_to_t; - -template& modulus> -Fp_model Fp2_model::Frobenius_coeffs_c1[2]; - -} // libsnark -#include "algebra/fields/fp2.tcc" - -#endif // FP2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp2.tcc b/src/snark/libsnark/algebra/fields/fp2.tcc deleted file mode 100644 index 84aa3035c..000000000 --- a/src/snark/libsnark/algebra/fields/fp2.tcc +++ /dev/null @@ -1,261 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of arithmetic in the finite field F[p^2]. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP2_TCC_ -#define FP2_TCC_ - -#include "algebra/fields/field_utils.hpp" - -namespace libsnark { - -template& modulus> -Fp2_model Fp2_model::zero() -{ - return Fp2_model(my_Fp::zero(), my_Fp::zero()); -} - -template& modulus> -Fp2_model Fp2_model::one() -{ - return Fp2_model(my_Fp::one(), my_Fp::zero()); -} - -template& modulus> -Fp2_model Fp2_model::random_element() -{ - Fp2_model r; - r.c0 = my_Fp::random_element(); - r.c1 = my_Fp::random_element(); - - return r; -} - -template& modulus> -bool Fp2_model::operator==(const Fp2_model &other) const -{ - return (this->c0 == other.c0 && this->c1 == other.c1); -} - -template& modulus> -bool Fp2_model::operator!=(const Fp2_model &other) const -{ - return !(operator==(other)); -} - -template& modulus> -Fp2_model Fp2_model::operator+(const Fp2_model &other) const -{ - return Fp2_model(this->c0 + other.c0, - this->c1 + other.c1); -} - -template& modulus> -Fp2_model Fp2_model::operator-(const Fp2_model &other) const -{ - return Fp2_model(this->c0 - other.c0, - this->c1 - other.c1); -} - -template& modulus> -Fp2_model operator*(const Fp_model &lhs, const Fp2_model &rhs) -{ - return Fp2_model(lhs*rhs.c0, - lhs*rhs.c1); -} - -template& modulus> -Fp2_model Fp2_model::operator*(const Fp2_model &other) const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba) */ - const my_Fp - &A = other.c0, &B = other.c1, - &a = this->c0, &b = this->c1; - const my_Fp aA = a * A; - const my_Fp bB = b * B; - - return Fp2_model(aA + non_residue * bB, - (a + b)*(A+B) - aA - bB); -} - -template& modulus> -Fp2_model Fp2_model::operator-() const -{ - return Fp2_model(-this->c0, - -this->c1); -} - -template& modulus> -Fp2_model Fp2_model::squared() const -{ - return squared_complex(); -} - -template& modulus> -Fp2_model Fp2_model::squared_karatsuba() const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba squaring) */ - const my_Fp &a = this->c0, &b = this->c1; - const my_Fp asq = a.squared(); - const my_Fp bsq = b.squared(); - - return Fp2_model(asq + non_residue * bsq, - (a + b).squared() - asq - bsq); -} - -template& modulus> -Fp2_model Fp2_model::squared_complex() const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Complex squaring) */ - const my_Fp &a = this->c0, &b = this->c1; - const my_Fp ab = a * b; - - return Fp2_model((a + b) * (a + non_residue * b) - ab - non_residue * ab, - ab + ab); -} - -template& modulus> -Fp2_model Fp2_model::inverse() const -{ - const my_Fp &a = this->c0, &b = this->c1; - - /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8 */ - const my_Fp t0 = a.squared(); - const my_Fp t1 = b.squared(); - const my_Fp t2 = t0 - non_residue * t1; - const my_Fp t3 = t2.inverse(); - const my_Fp c0 = a * t3; - const my_Fp c1 = - (b * t3); - - return Fp2_model(c0, c1); -} - -template& modulus> -Fp2_model Fp2_model::Frobenius_map(uint64_t power) const -{ - return Fp2_model(c0, - Frobenius_coeffs_c1[power % 2] * c1); -} - -template& modulus> -Fp2_model Fp2_model::sqrt() const -{ - if (is_zero()) { - return *this; - } - - Fp2_model one = Fp2_model::one(); - - unsigned long long v = Fp2_model::s; - Fp2_model z = Fp2_model::nqr_to_t; - Fp2_model w = (*this)^Fp2_model::t_minus_1_over_2; - Fp2_model x = (*this) * w; - Fp2_model b = x * w; // b = (*this)^t - - - // check if square with euler's criterion - Fp2_model check = b; - for (size_t i = 0; i < v-1; ++i) - { - check = check.squared(); - } - if (check != one) - { - assert_except(0); - } - - - // compute square root with Tonelli--Shanks - // (does not terminate if not a square!) - - while (b != one) - { - unsigned long long m = 0; - Fp2_model b2m = b; - while (b2m != one) - { - /* invariant: b2m = b^(2^m) after entering this loop */ - b2m = b2m.squared(); - m += 1; - } - - int j = v-m-1; - w = z; - while (j > 0) - { - w = w.squared(); - --j; - } // w = z^2^(v-m-1) - - z = w.squared(); - b = b * z; - x = x * w; - v = m; - } - - return x; -} - -template& modulus> -template -Fp2_model Fp2_model::operator^(const bigint &pow) const -{ - return power, m>(*this, pow); -} - -template& modulus> -std::ostream& operator<<(std::ostream &out, const Fp2_model &el) -{ - out << el.c0 << OUTPUT_SEPARATOR << el.c1; - return out; -} - -template& modulus> -std::istream& operator>>(std::istream &in, Fp2_model &el) -{ - in >> el.c0 >> el.c1; - return in; -} - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v) -{ - out << v.size() << "\n"; - for (const Fp2_model& t : v) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v) -{ - v.clear(); - - unsigned long long s; - in >> s; - - char b; - in.read(&b, 1); - - v.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - Fp2_model el; - in >> el; - v.emplace_back(el); - } - - return in; -} - -} // libsnark -#endif // FP2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp6_3over2.hpp b/src/snark/libsnark/algebra/fields/fp6_3over2.hpp deleted file mode 100644 index 8a888f0cf..000000000 --- a/src/snark/libsnark/algebra/fields/fp6_3over2.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/** @file - ***************************************************************************** - Declaration of arithmetic in the finite field F[(p^2)^3] - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP6_3OVER2_HPP_ -#define FP6_3OVER2_HPP_ -#include "algebra/fields/fp.hpp" -#include "algebra/fields/fp2.hpp" -#include - -namespace libsnark { - -template& modulus> -class Fp6_3over2_model; - -template& modulus> -std::ostream& operator<<(std::ostream &, const Fp6_3over2_model &); - -template& modulus> -std::istream& operator>>(std::istream &, Fp6_3over2_model &); - -/** - * Arithmetic in the finite field F[(p^2)^3]. - * - * Let p := modulus. This interface provides arithmetic for the extension field - * Fp6 = Fp2[V]/(V^3-non_residue) where non_residue is in Fp. - * - * ASSUMPTION: p = 1 (mod 6) - */ -template& modulus> -class Fp6_3over2_model { -public: - typedef Fp_model my_Fp; - typedef Fp2_model my_Fp2; - - static my_Fp2 non_residue; - static my_Fp2 Frobenius_coeffs_c1[6]; // non_residue^((modulus^i-1)/3) for i=0,1,2,3,4,5 - static my_Fp2 Frobenius_coeffs_c2[6]; // non_residue^((2*modulus^i-2)/3) for i=0,1,2,3,4,5 - - my_Fp2 c0, c1, c2; - Fp6_3over2_model() {}; - Fp6_3over2_model(const my_Fp2& c0, const my_Fp2& c1, const my_Fp2& c2) : c0(c0), c1(c1), c2(c2) {}; - - void clear() { c0.clear(); c1.clear(); c2.clear(); } - void print() const { printf("c0/c1/c2:\n"); c0.print(); c1.print(); c2.print(); } - - static Fp6_3over2_model zero(); - static Fp6_3over2_model one(); - static Fp6_3over2_model random_element(); - - bool is_zero() const { return c0.is_zero() && c1.is_zero() && c2.is_zero(); } - bool operator==(const Fp6_3over2_model &other) const; - bool operator!=(const Fp6_3over2_model &other) const; - - Fp6_3over2_model operator+(const Fp6_3over2_model &other) const; - Fp6_3over2_model operator-(const Fp6_3over2_model &other) const; - Fp6_3over2_model operator*(const Fp6_3over2_model &other) const; - Fp6_3over2_model operator-() const; - Fp6_3over2_model squared() const; - Fp6_3over2_model inverse() const; - Fp6_3over2_model Frobenius_map(uint64_t power) const; - - static my_Fp2 mul_by_non_residue(const my_Fp2 &elt); - - template - Fp6_3over2_model operator^(const bigint &other) const; - - static bigint base_field_char() { return modulus; } - static uint64_t extension_degree() { return 6; } - - friend std::ostream& operator<< (std::ostream &out, const Fp6_3over2_model &el); - friend std::istream& operator>> (std::istream &in, Fp6_3over2_model &el); -}; - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v); - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v); - -template& modulus> -Fp6_3over2_model operator*(const Fp_model &lhs, const Fp6_3over2_model &rhs); - -template& modulus> -Fp6_3over2_model operator*(const Fp2_model &lhs, const Fp6_3over2_model &rhs); - -template& modulus> -Fp2_model Fp6_3over2_model::non_residue; - -template& modulus> -Fp2_model Fp6_3over2_model::Frobenius_coeffs_c1[6]; - -template& modulus> -Fp2_model Fp6_3over2_model::Frobenius_coeffs_c2[6]; - -} // libsnark -#include "algebra/fields/fp6_3over2.tcc" - -#endif // FP6_3OVER2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp6_3over2.tcc b/src/snark/libsnark/algebra/fields/fp6_3over2.tcc deleted file mode 100644 index de9b83d11..000000000 --- a/src/snark/libsnark/algebra/fields/fp6_3over2.tcc +++ /dev/null @@ -1,216 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of arithmetic in the finite field F[(p^2)^3]. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP6_3OVER2_TCC_ -#define FP6_3OVER2_TCC_ -#include "algebra/fields/field_utils.hpp" - -namespace libsnark { - -template& modulus> -Fp2_model Fp6_3over2_model::mul_by_non_residue(const Fp2_model &elt) -{ - return Fp2_model(non_residue * elt); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::zero() -{ - return Fp6_3over2_model(my_Fp2::zero(), my_Fp2::zero(), my_Fp2::zero()); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::one() -{ - return Fp6_3over2_model(my_Fp2::one(), my_Fp2::zero(), my_Fp2::zero()); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::random_element() -{ - Fp6_3over2_model r; - r.c0 = my_Fp2::random_element(); - r.c1 = my_Fp2::random_element(); - r.c2 = my_Fp2::random_element(); - - return r; -} - -template& modulus> -bool Fp6_3over2_model::operator==(const Fp6_3over2_model &other) const -{ - return (this->c0 == other.c0 && this->c1 == other.c1 && this->c2 == other.c2); -} - -template& modulus> -bool Fp6_3over2_model::operator!=(const Fp6_3over2_model &other) const -{ - return !(operator==(other)); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::operator+(const Fp6_3over2_model &other) const -{ - return Fp6_3over2_model(this->c0 + other.c0, - this->c1 + other.c1, - this->c2 + other.c2); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::operator-(const Fp6_3over2_model &other) const -{ - return Fp6_3over2_model(this->c0 - other.c0, - this->c1 - other.c1, - this->c2 - other.c2); -} - -template& modulus> -Fp6_3over2_model operator*(const Fp_model &lhs, const Fp6_3over2_model &rhs) -{ - return Fp6_3over2_model(lhs*rhs.c0, - lhs*rhs.c1, - lhs*rhs.c2); -} - -template& modulus> -Fp6_3over2_model operator*(const Fp2_model &lhs, const Fp6_3over2_model &rhs) -{ - return Fp6_3over2_model(lhs*rhs.c0, - lhs*rhs.c1, - lhs*rhs.c2); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::operator*(const Fp6_3over2_model &other) const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4 (Karatsuba) */ - - const my_Fp2 &A = other.c0, &B = other.c1, &C = other.c2, - &a = this->c0, &b = this->c1, &c = this->c2; - const my_Fp2 aA = a*A; - const my_Fp2 bB = b*B; - const my_Fp2 cC = c*C; - - return Fp6_3over2_model(aA + Fp6_3over2_model::mul_by_non_residue((b+c)*(B+C)-bB-cC), - (a+b)*(A+B)-aA-bB+Fp6_3over2_model::mul_by_non_residue(cC), - (a+c)*(A+C)-aA+bB-cC); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::operator-() const -{ - return Fp6_3over2_model(-this->c0, - -this->c1, - -this->c2); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::squared() const -{ - /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4 (CH-SQR2) */ - - const my_Fp2 &a = this->c0, &b = this->c1, &c = this->c2; - const my_Fp2 s0 = a.squared(); - const my_Fp2 ab = a*b; - const my_Fp2 s1 = ab + ab; - const my_Fp2 s2 = (a - b + c).squared(); - const my_Fp2 bc = b*c; - const my_Fp2 s3 = bc + bc; - const my_Fp2 s4 = c.squared(); - - return Fp6_3over2_model(s0 + Fp6_3over2_model::mul_by_non_residue(s3), - s1 + Fp6_3over2_model::mul_by_non_residue(s4), - s1 + s2 + s3 - s0 - s4); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::inverse() const -{ - /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 17 */ - - const my_Fp2 &a = this->c0, &b = this->c1, &c = this->c2; - const my_Fp2 t0 = a.squared(); - const my_Fp2 t1 = b.squared(); - const my_Fp2 t2 = c.squared(); - const my_Fp2 t3 = a*b; - const my_Fp2 t4 = a*c; - const my_Fp2 t5 = b*c; - const my_Fp2 c0 = t0 - Fp6_3over2_model::mul_by_non_residue(t5); - const my_Fp2 c1 = Fp6_3over2_model::mul_by_non_residue(t2) - t3; - const my_Fp2 c2 = t1 - t4; // typo in paper referenced above. should be "-" as per Scott, but is "*" - const my_Fp2 t6 = (a * c0 + Fp6_3over2_model::mul_by_non_residue((c * c1 + b * c2))).inverse(); - return Fp6_3over2_model(t6 * c0, t6 * c1, t6 * c2); -} - -template& modulus> -Fp6_3over2_model Fp6_3over2_model::Frobenius_map(uint64_t power) const -{ - return Fp6_3over2_model(c0.Frobenius_map(power), - Frobenius_coeffs_c1[power % 6] * c1.Frobenius_map(power), - Frobenius_coeffs_c2[power % 6] * c2.Frobenius_map(power)); -} - -template& modulus> -template -Fp6_3over2_model Fp6_3over2_model::operator^(const bigint &pow) const -{ - return power, m>(*this, pow); -} - -template& modulus> -std::ostream& operator<<(std::ostream &out, const Fp6_3over2_model &el) -{ - out << el.c0 << OUTPUT_SEPARATOR << el.c1 << OUTPUT_SEPARATOR << el.c2; - return out; -} - -template& modulus> -std::istream& operator>>(std::istream &in, Fp6_3over2_model &el) -{ - in >> el.c0 >> el.c1 >> el.c2; - return in; -} - -template& modulus> -std::ostream& operator<<(std::ostream& out, const std::vector > &v) -{ - out << v.size() << "\n"; - for (const Fp6_3over2_model& t : v) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -template& modulus> -std::istream& operator>>(std::istream& in, std::vector > &v) -{ - v.clear(); - - uint64_t s; - in >> s; - - char b; - in.read(&b, 1); - - v.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - Fp6_3over2_model el; - in >> el; - v.emplace_back(el); - } - - return in; -} - -} // libsnark -#endif // FP6_3_OVER_2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp_aux.tcc b/src/snark/libsnark/algebra/fields/fp_aux.tcc deleted file mode 100644 index 7f8a3eadf..000000000 --- a/src/snark/libsnark/algebra/fields/fp_aux.tcc +++ /dev/null @@ -1,389 +0,0 @@ -/** @file - ***************************************************************************** - Assembly code snippets for F[p] finite field arithmetic, used by fp.tcc . - Specific to x86-64, and used only if USE_ASM is defined. - On other architectures or without USE_ASM, fp.tcc uses a portable - C++ implementation instead. - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef FP_AUX_TCC_ -#define FP_AUX_TCC_ - -namespace libsnark { - -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - -/* addq is faster than adcq, even if preceded by clc */ -#define ADD_FIRSTADD \ - "movq (%[B]), %%rax \n\t" \ - "addq %%rax, (%[A]) \n\t" - -#define ADD_NEXTADD(ofs) \ - "movq " STR(ofs) "(%[B]), %%rax \n\t" \ - "adcq %%rax, " STR(ofs) "(%[A]) \n\t" - -#define ADD_CMP(ofs) \ - "movq " STR(ofs) "(%[mod]), %%rax \n\t" \ - "cmpq %%rax, " STR(ofs) "(%[A]) \n\t" \ - "jb done%= \n\t" \ - "ja subtract%= \n\t" - -#define ADD_FIRSTSUB \ - "movq (%[mod]), %%rax \n\t" \ - "subq %%rax, (%[A]) \n\t" - -#define ADD_FIRSTSUB \ - "movq (%[mod]), %%rax \n\t" \ - "subq %%rax, (%[A]) \n\t" - -#define ADD_NEXTSUB(ofs) \ - "movq " STR(ofs) "(%[mod]), %%rax \n\t" \ - "sbbq %%rax, " STR(ofs) "(%[A]) \n\t" - -#define SUB_FIRSTSUB \ - "movq (%[B]), %%rax\n\t" \ - "subq %%rax, (%[A])\n\t" - -#define SUB_NEXTSUB(ofs) \ - "movq " STR(ofs) "(%[B]), %%rax\n\t" \ - "sbbq %%rax, " STR(ofs) "(%[A])\n\t" - -#define SUB_FIRSTADD \ - "movq (%[mod]), %%rax\n\t" \ - "addq %%rax, (%[A])\n\t" - -#define SUB_NEXTADD(ofs) \ - "movq " STR(ofs) "(%[mod]), %%rax\n\t" \ - "adcq %%rax, " STR(ofs) "(%[A])\n\t" - -#define MONT_CMP(ofs) \ - "movq " STR(ofs) "(%[M]), %%rax \n\t" \ - "cmpq %%rax, " STR(ofs) "(%[tmp]) \n\t" \ - "jb done%= \n\t" \ - "ja subtract%= \n\t" - -#define MONT_FIRSTSUB \ - "movq (%[M]), %%rax \n\t" \ - "subq %%rax, (%[tmp]) \n\t" - -#define MONT_NEXTSUB(ofs) \ - "movq " STR(ofs) "(%[M]), %%rax \n\t" \ - "sbbq %%rax, " STR(ofs) "(%[tmp]) \n\t" - -/* - The x86-64 Montgomery multiplication here is similar - to Algorithm 2 (CIOS method) in http://eprint.iacr.org/2012/140.pdf - and the PowerPC pseudocode of gmp-ecm library (c) Paul Zimmermann and Alexander Kruppa - (see comments on top of powerpc64/mulredc.m4). -*/ - -#define MONT_PRECOMPUTE \ - "xorq %[cy], %[cy] \n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq 0(%[B]) \n\t" \ - "movq %%rax, %[T0] \n\t" \ - "movq %%rdx, %[T1] # T1:T0 <- A[0] * B[0] \n\t" \ - "mulq %[inv] \n\t" \ - "movq %%rax, %[u] # u <- T0 * inv \n\t" \ - "mulq 0(%[M]) \n\t" \ - "addq %[T0], %%rax \n\t" \ - "adcq %%rdx, %[T1] \n\t" \ - "adcq $0, %[cy] # cy:T1 <- (M[0]*u + T1 * b + T0) / b\n\t" - -#define MONT_FIRSTITER(j) \ - "xorq %[T0], %[T0] \n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq " STR((j*8)) "(%[B]) \n\t" \ - "addq %[T1], %%rax \n\t" \ - "movq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ - "adcq $0, %%rdx \n\t" \ - "movq %%rdx, %[T1] # now T1:tmp[j-1] <-- X[0] * Y[j] + T1\n\t" \ - "movq " STR((j*8)) "(%[M]), %%rax \n\t" \ - "mulq %[u] \n\t" \ - "addq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ - "adcq %[cy], %%rdx \n\t" \ - "adcq $0, %[T0] \n\t" \ - "xorq %[cy], %[cy] \n\t" \ - "addq %%rdx, %[T1] \n\t" \ - "adcq %[T0], %[cy] # cy:T1:tmp[j-1] <---- (X[0] * Y[j] + T1) + (M[j] * u + cy * b) \n\t" - -#define MONT_ITERFIRST(i) \ - "xorq %[cy], %[cy] \n\t" \ - "movq " STR((i*8)) "(%[A]), %%rax \n\t" \ - "mulq 0(%[B]) \n\t" \ - "addq 0(%[tmp]), %%rax \n\t" \ - "adcq 8(%[tmp]), %%rdx \n\t" \ - "adcq $0, %[cy] \n\t" \ - "movq %%rax, %[T0] \n\t" \ - "movq %%rdx, %[T1] # cy:T1:T0 <- A[i] * B[0] + tmp[1] * b + tmp[0]\n\t" \ - "mulq %[inv] \n\t" \ - "movq %%rax, %[u] # u <- T0 * inv\n\t" \ - "mulq 0(%[M]) \n\t" \ - "addq %[T0], %%rax \n\t" \ - "adcq %%rdx, %[T1] \n\t" \ - "adcq $0, %[cy] # cy:T1 <- (M[0]*u + cy * b * b + T1 * b + T0) / b\n\t" - -#define MONT_ITERITER(i, j) \ - "xorq %[T0], %[T0] \n\t" \ - "movq " STR((i*8)) "(%[A]), %%rax \n\t" \ - "mulq " STR((j*8)) "(%[B]) \n\t" \ - "addq %[T1], %%rax \n\t" \ - "movq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ - "adcq $0, %%rdx \n\t" \ - "movq %%rdx, %[T1] # now T1:tmp[j-1] <-- X[i] * Y[j] + T1 \n\t" \ - "movq " STR((j*8)) "(%[M]), %%rax \n\t" \ - "mulq %[u] \n\t" \ - "addq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ - "adcq %[cy], %%rdx \n\t" \ - "adcq $0, %[T0] \n\t" \ - "xorq %[cy], %[cy] \n\t" \ - "addq %%rdx, %[T1] \n\t" \ - "adcq %[T0], %[cy] # cy:T1:tmp[j-1] <-- (X[i] * Y[j] + T1) + M[j] * u + cy * b \n\t" \ - "addq " STR(((j+1)*8)) "(%[tmp]), %[T1] \n\t" \ - "adcq $0, %[cy] # cy:T1:tmp[j-1] <-- (X[i] * Y[j] + T1) + M[j] * u + (tmp[j+1] + cy) * b \n\t" - -#define MONT_FINALIZE(j) \ - "movq %[T1], " STR((j*8)) "(%[tmp]) \n\t" \ - "movq %[cy], " STR(((j+1)*8)) "(%[tmp]) \n\t" - -/* - Comba multiplication and squaring routines are based on the - public-domain tomsfastmath library by Tom St Denis - - - - Compared to the above, we save 5-20% of cycles by using careful register - renaming to implement Comba forward operation. - */ - -#define COMBA_3_BY_3_MUL(c0_, c1_, c2_, res_, A_, B_) \ - asm volatile ( \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq 0(%[B]) \n\t" \ - "movq %%rax, 0(%[res]) \n\t" \ - "movq %%rdx, %[c0] \n\t" \ - \ - "xorq %[c1], %[c1] \n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq 8(%[B]) \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - \ - "xorq %[c2], %[c2] \n\t" \ - "movq 8(%[A]), %%rax \n\t" \ - "mulq 0(%[B]) \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "movq %[c0], 8(%[res]) \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - "adcq $0, %[c2] \n\t" \ - \ - "// register renaming (c1, c2, c0)\n\t" \ - "xorq %[c0], %[c0] \n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq 16(%[B]) \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - \ - "movq 8(%[A]), %%rax \n\t" \ - "mulq 8(%[B]) \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - \ - "movq 16(%[A]), %%rax \n\t" \ - "mulq 0(%[B]) \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "movq %[c1], 16(%[res]) \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - \ - "// register renaming (c2, c0, c1)\n\t" \ - "xorq %[c1], %[c1] \n\t" \ - "movq 8(%[A]), %%rax \n\t" \ - "mulq 16(%[B]) \n\t" \ - "addq %%rax, %[c2] \n\t" \ - "adcq %%rdx, %[c0] \n\t" \ - "adcq $0, %[c1] \n\t" \ - \ - "movq 16(%[A]), %%rax \n\t" \ - "mulq 8(%[B]) \n\t" \ - "addq %%rax, %[c2] \n\t" \ - "movq %[c2], 24(%[res]) \n\t" \ - "adcq %%rdx, %[c0] \n\t" \ - "adcq $0, %[c1] \n\t" \ - \ - "// register renaming (c0, c1, c2)\n\t" \ - "xorq %[c2], %[c2] \n\t" \ - "movq 16(%[A]), %%rax \n\t" \ - "mulq 16(%[B]) \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "movq %[c0], 32(%[res]) \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - "movq %[c1], 40(%[res]) \n\t" \ - : [c0] "=&r" (c0_), [c1] "=&r" (c1_), [c2] "=&r" (c2_) \ - : [res] "r" (res_), [A] "r" (A_), [B] "r" (B_) \ - : "%rax", "%rdx", "cc", "memory") - -#define COMBA_3_BY_3_SQR(c0_, c1_, c2_, res_, A_) \ - asm volatile ( \ - "xorq %[c1], %[c1] \n\t" \ - "xorq %[c2], %[c2] \n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq %%rax \n\t" \ - "movq %%rax, 0(%[res]) \n\t" \ - "movq %%rdx, %[c0] \n\t" \ - \ - "movq 0(%[A]), %%rax \n\t" \ - "mulq 8(%[A]) \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "movq %[c0], 8(%[res]) \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - "adcq $0, %[c2] \n\t" \ - \ - "// register renaming (c1, c2, c0)\n\t" \ - "movq 0(%[A]), %%rax \n\t" \ - "xorq %[c0], %[c0] \n\t" \ - "mulq 16(%[A]) \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - \ - "movq 8(%[A]), %%rax \n\t" \ - "mulq %%rax \n\t" \ - "addq %%rax, %[c1] \n\t" \ - "movq %[c1], 16(%[res]) \n\t" \ - "adcq %%rdx, %[c2] \n\t" \ - "adcq $0, %[c0] \n\t" \ - \ - "// register renaming (c2, c0, c1)\n\t" \ - "movq 8(%[A]), %%rax \n\t" \ - "xorq %[c1], %[c1] \n\t" \ - "mulq 16(%[A]) \n\t" \ - "addq %%rax, %[c2] \n\t" \ - "adcq %%rdx, %[c0] \n\t" \ - "adcq $0, %[c1] \n\t" \ - "addq %%rax, %[c2] \n\t" \ - "movq %[c2], 24(%[res]) \n\t" \ - "adcq %%rdx, %[c0] \n\t" \ - "adcq $0, %[c1] \n\t" \ - \ - "// register renaming (c0, c1, c2)\n\t" \ - "movq 16(%[A]), %%rax \n\t" \ - "mulq %%rax \n\t" \ - "addq %%rax, %[c0] \n\t" \ - "movq %[c0], 32(%[res]) \n\t" \ - "adcq %%rdx, %[c1] \n\t" \ - "movq %[c1], 40(%[res]) \n\t" \ - \ - : [c0] "=&r" (c0_), [c1] "=&r" (c1_), [c2] "=&r" (c2_) \ - : [res] "r" (res_), [A] "r" (A_) \ - : "%rax", "%rdx", "cc", "memory") - -/* - The Montgomery reduction here is based on Algorithm 14.32 in - Handbook of Applied Cryptography - . - */ -#define REDUCE_6_LIMB_PRODUCT(k_, tmp1_, tmp2_, tmp3_, inv_, res_, mod_) \ - __asm__ volatile \ - ("///////////////////////////////////\n\t" \ - "movq 0(%[res]), %%rax \n\t" \ - "mulq %[modprime] \n\t" \ - "movq %%rax, %[k] \n\t" \ - \ - "movq (%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "movq %%rax, %[tmp1] \n\t" \ - "movq %%rdx, %[tmp2] \n\t" \ - \ - "xorq %[tmp3], %[tmp3] \n\t" \ - "movq 8(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp1], 0(%[res]) \n\t" \ - "adcq %%rax, %[tmp2] \n\t" \ - "adcq %%rdx, %[tmp3] \n\t" \ - \ - "xorq %[tmp1], %[tmp1] \n\t" \ - "movq 16(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp2], 8(%[res]) \n\t" \ - "adcq %%rax, %[tmp3] \n\t" \ - "adcq %%rdx, %[tmp1] \n\t" \ - \ - "addq %[tmp3], 16(%[res]) \n\t" \ - "adcq %[tmp1], 24(%[res]) \n\t" \ - "adcq $0, 32(%[res]) \n\t" \ - "adcq $0, 40(%[res]) \n\t" \ - \ - "///////////////////////////////////\n\t" \ - "movq 8(%[res]), %%rax \n\t" \ - "mulq %[modprime] \n\t" \ - "movq %%rax, %[k] \n\t" \ - \ - "movq (%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "movq %%rax, %[tmp1] \n\t" \ - "movq %%rdx, %[tmp2] \n\t" \ - \ - "xorq %[tmp3], %[tmp3] \n\t" \ - "movq 8(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp1], 8(%[res]) \n\t" \ - "adcq %%rax, %[tmp2] \n\t" \ - "adcq %%rdx, %[tmp3] \n\t" \ - \ - "xorq %[tmp1], %[tmp1] \n\t" \ - "movq 16(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp2], 16(%[res]) \n\t" \ - "adcq %%rax, %[tmp3] \n\t" \ - "adcq %%rdx, %[tmp1] \n\t" \ - \ - "addq %[tmp3], 24(%[res]) \n\t" \ - "adcq %[tmp1], 32(%[res]) \n\t" \ - "adcq $0, 40(%[res]) \n\t" \ - \ - "///////////////////////////////////\n\t" \ - "movq 16(%[res]), %%rax \n\t" \ - "mulq %[modprime] \n\t" \ - "movq %%rax, %[k] \n\t" \ - \ - "movq (%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "movq %%rax, %[tmp1] \n\t" \ - "movq %%rdx, %[tmp2] \n\t" \ - \ - "xorq %[tmp3], %[tmp3] \n\t" \ - "movq 8(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp1], 16(%[res]) \n\t" \ - "adcq %%rax, %[tmp2] \n\t" \ - "adcq %%rdx, %[tmp3] \n\t" \ - \ - "xorq %[tmp1], %[tmp1] \n\t" \ - "movq 16(%[mod]), %%rax \n\t" \ - "mulq %[k] \n\t" \ - "addq %[tmp2], 24(%[res]) \n\t" \ - "adcq %%rax, %[tmp3] \n\t" \ - "adcq %%rdx, %[tmp1] \n\t" \ - \ - "addq %[tmp3], 32(%[res]) \n\t" \ - "adcq %[tmp1], 40(%[res]) \n\t" \ - : [k] "=&r" (k_), [tmp1] "=&r" (tmp1_), [tmp2] "=&r" (tmp2_), [tmp3] "=&r" (tmp3_) \ - : [modprime] "r" (inv_), [res] "r" (res_), [mod] "r" (mod_) \ - : "%rax", "%rdx", "cc", "memory") - -} // libsnark -#endif // FP_AUX_TCC_ diff --git a/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp b/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp deleted file mode 100644 index a735c3436..000000000 --- a/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "algebra/fields/bigint.hpp" - -using namespace libsnark; - -void test_bigint() -{ - static_assert(GMP_NUMB_BITS == 64, "GMP limb not 64-bit"); - - const char *b1_decimal = "76749407"; - const char *b2_decimal = "435020359732196472065729437602"; - const char *b3_decimal = "33387554642372758038536799358397002014"; - const char *b2_binary = "0000000000000000000000000000010101111101101000000110100001011010" - "1101101010001001000001101000101000100110011001110001111110100010"; - - bigint<1> b0 = bigint<1>(UINT64_C(0)); - bigint<1> b1 = bigint<1>(b1_decimal); - bigint<2> b2 = bigint<2>(b2_decimal); - - EXPECT_EQ(b0.as_uint64(), UINT64_C(0)); - EXPECT_TRUE(b0.is_zero()); - EXPECT_EQ(b1.as_uint64(), UINT64_C(76749407)); - EXPECT_FALSE(b1.is_zero()); - EXPECT_EQ(b2.as_uint64(), UINT64_C(15747124762497195938)); - EXPECT_FALSE(b2.is_zero()); - EXPECT_NE(b0, b1); - EXPECT_FALSE(b0 == b1); - - EXPECT_EQ(b2.max_bits(), 128u); - EXPECT_EQ(b2.num_bits(), 99u); - for (size_t i = 0; i < 128; i++) { - assert(b2.test_bit(i) == (b2_binary[127-i] == '1')); - } - - bigint<3> b3 = b2 * b1; - - assert(b3 == bigint<3>(b3_decimal)); - assert(!(b3.is_zero())); - - bigint<3> b3a { b3 }; - assert(b3a == bigint<3>(b3_decimal)); - assert(b3a == b3); - assert(!(b3a.is_zero())); - - mpz_t m3; - mpz_init(m3); - b3.to_mpz(m3); - bigint<3> b3b { m3 }; - assert(b3b == b3); - - bigint<2> quotient; - bigint<2> remainder; - bigint<3>::div_qr(quotient, remainder, b3, b2); - EXPECT_LT(quotient.num_bits(), static_cast(GMP_NUMB_BITS)); - EXPECT_EQ(quotient.as_uint64(), b1.as_uint64()); - bigint<1> b1inc = bigint<1>("76749408"); - bigint<1> b1a = quotient.shorten(b1inc, "test"); - assert(b1a == b1); - assert(remainder.is_zero()); - remainder.limit(b2, "test"); - - try { - (void)(quotient.shorten(b1, "test")); - assert(false); - } catch (std::domain_error) {} - try { - remainder.limit(remainder, "test"); - assert(false); - } catch (std::domain_error) {} - - bigint<1> br = bigint<1>("42"); - b3 += br; - assert(b3 != b3a); - assert(b3 > b3a); - assert(!(b3a > b3)); - - bigint<3>::div_qr(quotient, remainder, b3, b2); - EXPECT_LT(quotient.num_bits(), static_cast(GMP_NUMB_BITS)); - EXPECT_EQ(quotient.as_uint64(), b1.as_uint64()); - EXPECT_LT(remainder.num_bits(), static_cast(GMP_NUMB_BITS)); - EXPECT_EQ(remainder.as_uint64(), 42u); - - b3a.clear(); - EXPECT_TRUE(b3a.is_zero()); - EXPECT_EQ(b3a.num_bits(), 0u); - EXPECT_FALSE(b3.is_zero()); - - bigint<4> bx = bigint<4>().randomize(); - bigint<4> by = bigint<4>().randomize(); - assert(!(bx == by)); - - // TODO: test serialization -} - -int main(void) -{ - test_bigint(); - return 0; -} - diff --git a/src/snark/libsnark/algebra/fields/tests/test_fields.cpp b/src/snark/libsnark/algebra/fields/tests/test_fields.cpp deleted file mode 100644 index 8f62ceef9..000000000 --- a/src/snark/libsnark/algebra/fields/tests/test_fields.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include "common/profiling.hpp" -#include "algebra/curves/edwards/edwards_pp.hpp" -#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" -#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -#ifdef CURVE_BN128 -#include "algebra/curves/bn128/bn128_pp.hpp" -#endif -#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" -#include "algebra/fields/fp6_3over2.hpp" -#include "algebra/fields/fp12_2over3over2.hpp" - -using namespace libsnark; - -template -void test_field() -{ - bigint<1> rand1 = bigint<1>("76749407"); - bigint<1> rand2 = bigint<1>("44410867"); - bigint<1> randsum = bigint<1>("121160274"); - - FieldT zero = FieldT::zero(); - FieldT one = FieldT::one(); - FieldT a = FieldT::random_element(); - FieldT a_ser; - a_ser = reserialize(a); - assert(a_ser == a); - - FieldT b = FieldT::random_element(); - FieldT c = FieldT::random_element(); - FieldT d = FieldT::random_element(); - - assert(a != zero); - assert(a != one); - - assert(a * a == a.squared()); - assert((a + b).squared() == a.squared() + a*b + b*a + b.squared()); - assert((a + b)*(c + d) == a*c + a*d + b*c + b*d); - assert(a - b == a + (-b)); - assert(a - b == (-b) + a); - - assert((a ^ rand1) * (a ^ rand2) == (a^randsum)); - - assert(a * a.inverse() == one); - assert((a + b) * c.inverse() == a * c.inverse() + (b.inverse() * c).inverse()); - -} - -template -void test_sqrt() -{ - for (size_t i = 0; i < 100; ++i) - { - FieldT a = FieldT::random_element(); - FieldT asq = a.squared(); - assert(asq.sqrt() == a || asq.sqrt() == -a); - } -} - -template -void test_two_squarings() -{ - FieldT a = FieldT::random_element(); - assert(a.squared() == a * a); - assert(a.squared() == a.squared_complex()); - assert(a.squared() == a.squared_karatsuba()); -} - -template -void test_Frobenius() -{ - FieldT a = FieldT::random_element(); - assert(a.Frobenius_map(0) == a); - FieldT a_q = a ^ FieldT::base_field_char(); - for (size_t power = 1; power < 10; ++power) - { - const FieldT a_qi = a.Frobenius_map(power); - assert(a_qi == a_q); - - a_q = a_q ^ FieldT::base_field_char(); - } -} - -template -void test_unitary_inverse() -{ - EXPECT_EQ(FieldT::extension_degree() % 2, 0u); - FieldT a = FieldT::random_element(); - FieldT aqcubed_minus1 = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); - assert(aqcubed_minus1.inverse() == aqcubed_minus1.unitary_inverse()); -} - -template -void test_cyclotomic_squaring(); - -template<> -void test_cyclotomic_squaring >() -{ - typedef Fqk FieldT; - assert(FieldT::extension_degree() % 2 == 0); - FieldT a = FieldT::random_element(); - FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); - // beta = a^((q^(k/2)-1)*(q+1)) - FieldT beta = a_unitary.Frobenius_map(1) * a_unitary; - assert(beta.cyclotomic_squared() == beta.squared()); -} - -template<> -void test_cyclotomic_squaring >() -{ - typedef Fqk FieldT; - assert(FieldT::extension_degree() % 2 == 0); - FieldT a = FieldT::random_element(); - FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); - // beta = a^(q^(k/2)-1) - FieldT beta = a_unitary; - assert(beta.cyclotomic_squared() == beta.squared()); -} - -template<> -void test_cyclotomic_squaring >() -{ - typedef Fqk FieldT; - assert(FieldT::extension_degree() % 2 == 0); - FieldT a = FieldT::random_element(); - FieldT a_unitary = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); - // beta = a^((q^(k/2)-1)*(q+1)) - FieldT beta = a_unitary.Frobenius_map(1) * a_unitary; - assert(beta.cyclotomic_squared() == beta.squared()); -} - -template -void test_all_fields() -{ - test_field >(); - test_field >(); - test_field >(); - test_field >(); - - test_sqrt >(); - test_sqrt >(); - test_sqrt >(); - - test_Frobenius >(); - test_Frobenius >(); - - test_unitary_inverse >(); -} - -template -void test_Fp4_tom_cook() -{ - typedef typename Fp4T::my_Fp FieldT; - for (size_t i = 0; i < 100; ++i) - { - const Fp4T a = Fp4T::random_element(); - const Fp4T b = Fp4T::random_element(); - const Fp4T correct_res = a * b; - - Fp4T res; - - const FieldT - &a0 = a.c0.c0, - &a1 = a.c1.c0, - &a2 = a.c0.c1, - &a3 = a.c1.c1; - - const FieldT - &b0 = b.c0.c0, - &b1 = b.c1.c0, - &b2 = b.c0.c1, - &b3 = b.c1.c1; - - FieldT - &c0 = res.c0.c0, - &c1 = res.c1.c0, - &c2 = res.c0.c1, - &c3 = res.c1.c1; - - const FieldT v0 = a0 * b0; - const FieldT v1 = (a0 + a1 + a2 + a3) * (b0 + b1 + b2 + b3); - const FieldT v2 = (a0 - a1 + a2 - a3) * (b0 - b1 + b2 - b3); - const FieldT v3 = (a0 + FieldT(2)*a1 + FieldT(4)*a2 + FieldT(8)*a3) * (b0 + FieldT(2)*b1 + FieldT(4)*b2 + FieldT(8)*b3); - const FieldT v4 = (a0 - FieldT(2)*a1 + FieldT(4)*a2 - FieldT(8)*a3) * (b0 - FieldT(2)*b1 + FieldT(4)*b2 - FieldT(8)*b3); - const FieldT v5 = (a0 + FieldT(3)*a1 + FieldT(9)*a2 + FieldT(27)*a3) * (b0 + FieldT(3)*b1 + FieldT(9)*b2 + FieldT(27)*b3); - const FieldT v6 = a3 * b3; - - const FieldT beta = Fp4T::non_residue; - - c0 = v0 + beta*(FieldT(4).inverse()*v0 - FieldT(6).inverse()*(v1 + v2) + FieldT(24).inverse() * (v3 + v4) - FieldT(5) * v6); - c1 = - FieldT(3).inverse()*v0 + v1 - FieldT(2).inverse()*v2 - FieldT(4).inverse()*v3 + FieldT(20).inverse() * v4 + FieldT(30).inverse() * v5 - FieldT(12) * v6 + beta * ( - FieldT(12).inverse() * (v0 - v1) + FieldT(24).inverse()*(v2 - v3) - FieldT(120).inverse() * (v4 - v5) - FieldT(3) * v6); - c2 = - (FieldT(5)*(FieldT(4).inverse()))* v0 + (FieldT(2)*(FieldT(3).inverse()))*(v1 + v2) - FieldT(24).inverse()*(v3 + v4) + FieldT(4)*v6 + beta*v6; - c3 = FieldT(12).inverse() * (FieldT(5)*v0 - FieldT(7)*v1) - FieldT(24).inverse()*(v2 - FieldT(7)*v3 + v4 + v5) + FieldT(15)*v6; - - assert(res == correct_res); - - // {v0, v3, v4, v5} - const FieldT u = (FieldT::one() - beta).inverse(); - assert(v0 == u * c0 + beta * u * c2 - beta * u * FieldT(2).inverse() * v1 - beta * u * FieldT(2).inverse() * v2 + beta * v6); - assert(v3 == - FieldT(15) * u * c0 - FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 - FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v1 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v2 - - FieldT(3) * (-FieldT(16) + beta) * v6); - assert(v4 == - FieldT(15) * u * c0 + FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 + FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v2 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v1 - - FieldT(3) * (-FieldT(16) + beta) * v6); - assert(v5 == - FieldT(80) * u * c0 - FieldT(240) * u * c1 - FieldT(8) * (FieldT(9) + beta) * u * c2 - FieldT(24) * (FieldT(9) + beta) * u * c3 - FieldT(2) * (-FieldT(81) + beta) * u * v1 + (-FieldT(81) + beta) * u * v2 - - FieldT(8) * (-FieldT(81) + beta) * v6); - - // c0 + beta c2 - (beta v1)/2 - (beta v2)/ 2 - (-1 + beta) beta v6, - // -15 c0 - 30 c1 - 3 (4 + beta) c2 - 6 (4 + beta) c3 + (24 - (3 beta)/2) v1 + (-8 + beta/2) v2 + 3 (-16 + beta) (-1 + beta) v6, - // -15 c0 + 30 c1 - 3 (4 + beta) c2 + 6 (4 + beta) c3 + (-8 + beta/2) v1 + (24 - (3 beta)/2) v2 + 3 (-16 + beta) (-1 + beta) v6, - // -80 c0 - 240 c1 - 8 (9 + beta) c2 - 24 (9 + beta) c3 - 2 (-81 + beta) v1 + (-81 + beta) v2 + 8 (-81 + beta) (-1 + beta) v6 - } -} - -int main(void) -{ - edwards_pp::init_public_params(); - test_all_fields(); - test_cyclotomic_squaring >(); - - mnt4_pp::init_public_params(); - test_all_fields(); - test_Fp4_tom_cook(); - test_two_squarings >(); - test_cyclotomic_squaring >(); - - mnt6_pp::init_public_params(); - test_all_fields(); - test_cyclotomic_squaring >(); - - alt_bn128_pp::init_public_params(); - test_field(); - test_Frobenius(); - test_all_fields(); - -#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled - bn128_pp::init_public_params(); - test_field >(); - test_field >(); -#endif -} diff --git a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp deleted file mode 100644 index 902423134..000000000 --- a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for: - - a knowledge commitment, and - - a knowledge commitment vector. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef KNOWLEDGE_COMMITMENT_HPP_ -#define KNOWLEDGE_COMMITMENT_HPP_ - -#include "algebra/fields/fp.hpp" -#include "common/data_structures/sparse_vector.hpp" - -namespace libsnark { - -/********************** Knowledge commitment *********************************/ - -/** - * A knowledge commitment is a pair (g,h) where g is in T1 and h in T2, - * and T1 and T2 are groups (written additively). - * - * Such pairs form a group by defining: - * - "zero" = (0,0) - * - "one" = (1,1) - * - a * (g,h) + b * (g',h') := ( a * g + b * g', a * h + b * h'). - */ -template -struct knowledge_commitment { - - T1 g; - T2 h; - - knowledge_commitment() = default; - knowledge_commitment(const knowledge_commitment &other) = default; - knowledge_commitment(knowledge_commitment &&other) = default; - knowledge_commitment(const T1 &g, const T2 &h); - - knowledge_commitment& operator=(const knowledge_commitment &other) = default; - knowledge_commitment& operator=(knowledge_commitment &&other) = default; - knowledge_commitment operator+(const knowledge_commitment &other) const; - - bool is_zero() const; - bool operator==(const knowledge_commitment &other) const; - bool operator!=(const knowledge_commitment &other) const; - - static knowledge_commitment zero(); - static knowledge_commitment one(); - - void print() const; - - static size_t size_in_bits(); -}; - -template -knowledge_commitment operator*(const bigint &lhs, const knowledge_commitment &rhs); - -template &modulus_p> -knowledge_commitment operator*(const Fp_model &lhs, const knowledge_commitment &rhs); - -template -std::ostream& operator<<(std::ostream& out, const knowledge_commitment &kc); - -template -std::istream& operator>>(std::istream& in, knowledge_commitment &kc); - -/******************** Knowledge commitment vector ****************************/ - -/** - * A knowledge commitment vector is a sparse vector of knowledge commitments. - */ -template -using knowledge_commitment_vector = sparse_vector >; - -} // libsnark - -#include "algebra/knowledge_commitment/knowledge_commitment.tcc" - -#endif // KNOWLEDGE_COMMITMENT_HPP_ diff --git a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc deleted file mode 100644 index 15b2926c8..000000000 --- a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc +++ /dev/null @@ -1,111 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for: - - a knowledge commitment, and - - a knowledge commitment vector. - - See knowledge_commitment.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef KNOWLEDGE_COMMITMENT_TCC_ -#define KNOWLEDGE_COMMITMENT_TCC_ - -namespace libsnark { - -template -knowledge_commitment::knowledge_commitment(const T1 &g, const T2 &h) : - g(g), h(h) -{ -} - -template -knowledge_commitment knowledge_commitment::zero() -{ - return knowledge_commitment(T1::zero(), T2::zero()); -} - -template -knowledge_commitment knowledge_commitment::one() -{ - return knowledge_commitment(T1::one(), T2::one()); -} - -template -knowledge_commitment knowledge_commitment::operator+(const knowledge_commitment &other) const -{ - return knowledge_commitment(this->g + other.g, - this->h + other.h); -} - -template -bool knowledge_commitment::is_zero() const -{ - return (g.is_zero() && h.is_zero()); -} - -template -bool knowledge_commitment::operator==(const knowledge_commitment &other) const -{ - return (this->g == other.g && - this->h == other.h); -} - -template -bool knowledge_commitment::operator!=(const knowledge_commitment &other) const -{ - return !((*this) == other); -} - -template -knowledge_commitment operator*(const bigint &lhs, const knowledge_commitment &rhs) -{ - return knowledge_commitment(lhs * rhs.g, - lhs * rhs.h); -} - -template &modulus_p> -knowledge_commitment operator*(const Fp_model &lhs, const knowledge_commitment &rhs) -{ - return (lhs.as_bigint()) * rhs; -} - -template -void knowledge_commitment::print() const -{ - printf("knowledge_commitment.g:\n"); - g.print(); - printf("knowledge_commitment.h:\n"); - h.print(); -} - -template -size_t knowledge_commitment::size_in_bits() -{ - return T1::size_in_bits() + T2::size_in_bits(); -} - -template -std::ostream& operator<<(std::ostream& out, const knowledge_commitment &kc) -{ - out << kc.g << OUTPUT_SEPARATOR << kc.h; - return out; -} - -template -std::istream& operator>>(std::istream& in, knowledge_commitment &kc) -{ - in >> kc.g; - consume_OUTPUT_SEPARATOR(in); - in >> kc.h; - return in; -} - -} // libsnark - -#endif // KNOWLEDGE_COMMITMENT_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp deleted file mode 100644 index 4e8b55667..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef KC_MULTIEXP_HPP_ -#define KC_MULTIEXP_HPP_ - -/* - Split out from multiexp to prevent cyclical - dependencies. I.e. previously multiexp dependend on - knowledge_commitment, which dependend on sparse_vector, which - dependend on multiexp (to do accumulate). - - Will probably go away in more general exp refactoring. -*/ - -#include "algebra/knowledge_commitment/knowledge_commitment.hpp" - -namespace libsnark { - -template -knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment &base, - const bigint &scalar, const size_t scalar_bits); - -template -knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, - const size_t min_idx, - const size_t max_idx, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp=false); - -template -void kc_batch_to_special(std::vector > &vec); - -template -knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, - const size_t T1_window, - const size_t T2_window, - const window_table &T1_table, - const window_table &T2_table, - const FieldT &T1_coeff, - const FieldT &T2_coeff, - const std::vector &v, - const size_t suggested_num_chunks); - -} // libsnark - -#include "algebra/scalar_multiplication/kc_multiexp.tcc" - -#endif // KC_MULTIEXP_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc deleted file mode 100644 index 605203347..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc +++ /dev/null @@ -1,276 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef KC_MULTIEXP_TCC_ -#define KC_MULTIEXP_TCC_ - -#include "common/assert_except.hpp" - -namespace libsnark { - -template -knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment &base, - const bigint &scalar, const size_t scalar_bits) -{ - return knowledge_commitment(opt_window_wnaf_exp(base.g, scalar, scalar_bits), - opt_window_wnaf_exp(base.h, scalar, scalar_bits)); -} - -template -knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, - const size_t min_idx, - const size_t max_idx, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp) -{ - enter_block("Process scalar vector"); - auto index_it = std::lower_bound(vec.indices.begin(), vec.indices.end(), min_idx); - const size_t offset = index_it - vec.indices.begin(); - - auto value_it = vec.values.begin() + offset; - - const FieldT zero = FieldT::zero(); - const FieldT one = FieldT::one(); - - std::vector p; - std::vector > g; - - knowledge_commitment acc = knowledge_commitment::zero(); - - size_t num_skip = 0; - size_t num_add = 0; - size_t num_other = 0; - - const size_t scalar_length = std::distance(scalar_start, scalar_end); - - while (index_it != vec.indices.end() && *index_it < max_idx) - { - const size_t scalar_position = (*index_it) - min_idx; - assert_except(scalar_position < scalar_length); - - const FieldT scalar = *(scalar_start + scalar_position); - - if (scalar == zero) - { - // do nothing - ++num_skip; - } - else if (scalar == one) - { -#ifdef USE_MIXED_ADDITION - acc.g = acc.g.mixed_add(value_it->g); - acc.h = acc.h.mixed_add(value_it->h); -#else - acc.g = acc.g + value_it->g; - acc.h = acc.h + value_it->h; -#endif - ++num_add; - } - else - { - p.emplace_back(scalar); - g.emplace_back(*value_it); - ++num_other; - } - - ++index_it; - ++value_it; - } - - //print_indent(); printf("* Elements of w skipped: %zu (%0.2f%%)\n", num_skip, 100.*num_skip/(num_skip+num_add+num_other)); - //print_indent(); printf("* Elements of w processed with special addition: %zu (%0.2f%%)\n", num_add, 100.*num_add/(num_skip+num_add+num_other)); - //print_indent(); printf("* Elements of w remaining: %zu (%0.2f%%)\n", num_other, 100.*num_other/(num_skip+num_add+num_other)); - leave_block("Process scalar vector"); - - return acc + multi_exp, FieldT>(g.begin(), g.end(), p.begin(), p.end(), chunks, use_multiexp); -} - -template -void kc_batch_to_special(std::vector > &vec) -{ - enter_block("Batch-convert knowledge-commitments to special form"); - - std::vector g_vec; - g_vec.reserve(vec.size()); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].g.is_zero()) - { - g_vec.emplace_back(vec[i].g); - } - } - - batch_to_special_all_non_zeros(g_vec); - auto g_it = g_vec.begin(); - T1 T1_zero_special = T1::zero(); - T1_zero_special.to_special(); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].g.is_zero()) - { - vec[i].g = *g_it; - ++g_it; - } - else - { - vec[i].g = T1_zero_special; - } - } - - g_vec.clear(); - - std::vector h_vec; - h_vec.reserve(vec.size()); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].h.is_zero()) - { - h_vec.emplace_back(vec[i].h); - } - } - - batch_to_special_all_non_zeros(h_vec); - auto h_it = h_vec.begin(); - T2 T2_zero_special = T2::zero(); - T2_zero_special.to_special(); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].h.is_zero()) - { - vec[i].h = *h_it; - ++h_it; - } - else - { - vec[i].h = T2_zero_special; - } - } - - g_vec.clear(); - - leave_block("Batch-convert knowledge-commitments to special form"); -} - -template -knowledge_commitment_vector kc_batch_exp_internal(const size_t scalar_size, - const size_t T1_window, - const size_t T2_window, - const window_table &T1_table, - const window_table &T2_table, - const FieldT &T1_coeff, - const FieldT &T2_coeff, - const std::vector &v, - const size_t start_pos, - const size_t end_pos, - const size_t expected_size) -{ - knowledge_commitment_vector res; - - res.values.reserve(expected_size); - res.indices.reserve(expected_size); - - for (size_t pos = start_pos; pos != end_pos; ++pos) - { - if (!v[pos].is_zero()) - { - res.values.emplace_back(knowledge_commitment(windowed_exp(scalar_size, T1_window, T1_table, T1_coeff * v[pos]), - windowed_exp(scalar_size, T2_window, T2_table, T2_coeff * v[pos]))); - res.indices.emplace_back(pos); - } - } - - return res; -} - -template -knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, - const size_t T1_window, - const size_t T2_window, - const window_table &T1_table, - const window_table &T2_table, - const FieldT &T1_coeff, - const FieldT &T2_coeff, - const std::vector &v, - const size_t suggested_num_chunks) -{ - knowledge_commitment_vector res; - res.domain_size_ = v.size(); - - size_t nonzero = 0; - for (size_t i = 0; i < v.size(); ++i) - { - nonzero += (v[i].is_zero() ? 0 : 1); - } - - const size_t num_chunks = std::max((size_t)1, std::min(nonzero, suggested_num_chunks)); - - if (!inhibit_profiling_info) - { - print_indent(); printf("Non-zero coordinate count: %zu/%zu (%0.2f%%)\n", nonzero, v.size(), 100.*nonzero/v.size()); - } - - std::vector > tmp(num_chunks); - std::vector chunk_pos(num_chunks+1); - - const size_t chunk_size = nonzero / num_chunks; - const size_t last_chunk = nonzero - chunk_size * (num_chunks - 1); - - chunk_pos[0] = 0; - - size_t cnt = 0; - size_t chunkno = 1; - - for (size_t i = 0; i < v.size(); ++i) - { - cnt += (v[i].is_zero() ? 0 : 1); - if (cnt == chunk_size && chunkno < num_chunks) - { - chunk_pos[chunkno] = i; - cnt = 0; - ++chunkno; - } - } - - chunk_pos[num_chunks] = v.size(); - -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < num_chunks; ++i) - { - tmp[i] = kc_batch_exp_internal(scalar_size, T1_window, T2_window, T1_table, T2_table, T1_coeff, T2_coeff, v, - chunk_pos[i], chunk_pos[i+1], i == num_chunks - 1 ? last_chunk : chunk_size); -#ifdef USE_MIXED_ADDITION - kc_batch_to_special(tmp[i].values); -#endif - } - - if (num_chunks == 1) - { - tmp[0].domain_size_ = v.size(); - return tmp[0]; - } - else - { - for (size_t i = 0; i < num_chunks; ++i) - { - res.values.insert(res.values.end(), tmp[i].values.begin(), tmp[i].values.end()); - res.indices.insert(res.indices.end(), tmp[i].indices.begin(), tmp[i].indices.end()); - } - return res; - } -} - -} // libsnark - -#endif // KC_MULTIEXP_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp deleted file mode 100644 index eaf72d61f..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp +++ /dev/null @@ -1,110 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for multi-exponentiation routines. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MULTIEXP_HPP_ -#define MULTIEXP_HPP_ - -namespace libsnark { - -/** - * Naive multi-exponentiation individually multiplies each base by the - * corresponding scalar and adds up the results. - */ -template -T naive_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end); - -template -T naive_plain_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end); - -/** - * Naive multi-exponentiation uses a variant of the Bos-Coster algorithm [1], - * and implementation suggestions from [2]. - * - * [1] = Bos and Coster, "Addition chain heuristics", CRYPTO '89 - * [2] = Bernstein, Duif, Lange, Schwabe, and Yang, "High-speed high-security signatures", CHES '11 - */ -template -T multi_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp=false); - - -/** - * A variant of multi_exp that takes advantage of the method mixed_add (instead of the operator '+'). - */ -template -T multi_exp_with_mixed_addition(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp); - -/** - * A window table stores window sizes for different instance sizes for fixed-base multi-scalar multiplications. - */ -template -using window_table = std::vector >; - -/** - * Compute window size for the given number of scalars. - */ -template -size_t get_exp_window_size(const size_t num_scalars); - -/** - * Compute table of window sizes. - */ -template -window_table get_window_table(const size_t scalar_size, - const size_t window, - const T &g); - -template -T windowed_exp(const size_t scalar_size, - const size_t window, - const window_table &powers_of_g, - const FieldT &pow); - -template -std::vector batch_exp(const size_t scalar_size, - const size_t window, - const window_table &table, - const std::vector &v); - -template -std::vector batch_exp_with_coeff(const size_t scalar_size, - const size_t window, - const window_table &table, - const FieldT &coeff, - const std::vector &v); - -// defined in every curve -template -void batch_to_special_all_non_zeros(std::vector &vec); - -template -void batch_to_special(std::vector &vec); - -} // libsnark - -#include "algebra/scalar_multiplication/multiexp.tcc" - -#endif // MULTIEXP_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc deleted file mode 100644 index 5dd19a651..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc +++ /dev/null @@ -1,591 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for multi-exponentiation routines. - - See multiexp.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MULTIEXP_TCC_ -#define MULTIEXP_TCC_ - -#include "algebra/fields/fp_aux.tcc" - -#include -#include -#include - -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "common/assert_except.hpp" -#include "algebra/scalar_multiplication/wnaf.hpp" - -namespace libsnark { - -template -class ordered_exponent { -// to use std::push_heap and friends later -public: - size_t idx; - bigint r; - - ordered_exponent(const size_t idx, const bigint &r) : idx(idx), r(r) {}; - - bool operator<(const ordered_exponent &other) const - { -#if defined(__x86_64__) && defined(USE_ASM) - if (n == 3) - { - int64_t res; - __asm__ - ("// check for overflow \n\t" - "mov $0, %[res] \n\t" - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - "jmp done%= \n\t" - "subtract%=: \n\t" - "mov $1, %[res] \n\t" - "done%=: \n\t" - : [res] "=&r" (res) - : [A] "r" (other.r.data), [mod] "r" (this->r.data) - : "cc", "%rax"); - return res; - } - else if (n == 4) - { - int64_t res; - __asm__ - ("// check for overflow \n\t" - "mov $0, %[res] \n\t" - ADD_CMP(24) - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - "jmp done%= \n\t" - "subtract%=: \n\t" - "mov $1, %[res] \n\t" - "done%=: \n\t" - : [res] "=&r" (res) - : [A] "r" (other.r.data), [mod] "r" (this->r.data) - : "cc", "%rax"); - return res; - } - else if (n == 5) - { - int64_t res; - __asm__ - ("// check for overflow \n\t" - "mov $0, %[res] \n\t" - ADD_CMP(32) - ADD_CMP(24) - ADD_CMP(16) - ADD_CMP(8) - ADD_CMP(0) - "jmp done%= \n\t" - "subtract%=: \n\t" - "mov $1, %[res] \n\t" - "done%=: \n\t" - : [res] "=&r" (res) - : [A] "r" (other.r.data), [mod] "r" (this->r.data) - : "cc", "%rax"); - return res; - } - else -#endif - { - return (mpn_cmp(this->r.data, other.r.data, n) < 0); - } - } -}; - -template -T naive_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end) -{ - T result(T::zero()); - - typename std::vector::const_iterator vec_it; - typename std::vector::const_iterator scalar_it; - - for (vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it) - { - bigint scalar_bigint = scalar_it->as_bigint(); - result = result + opt_window_wnaf_exp(*vec_it, scalar_bigint, scalar_bigint.num_bits()); - } - assert_except(scalar_it == scalar_end); - - return result; -} - -template -T naive_plain_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end) -{ - T result(T::zero()); - - typename std::vector::const_iterator vec_it; - typename std::vector::const_iterator scalar_it; - - for (vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it) - { - result = result + (*scalar_it) * (*vec_it); - } - assert_except(scalar_it == scalar_end); - - return result; -} - -/* - The multi-exponentiation algorithm below is a variant of the Bos-Coster algorithm - [Bos and Coster, "Addition chain heuristics", CRYPTO '89]. - The implementation uses suggestions from - [Bernstein, Duif, Lange, Schwabe, and Yang, "High-speed high-security signatures", CHES '11]. -*/ -template -T multi_exp_inner(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end) -{ - const mp_size_t n = std::remove_reference::type::num_limbs; - - if (vec_start == vec_end) - { - return T::zero(); - } - - if (vec_start + 1 == vec_end) - { - return (*scalar_start)*(*vec_start); - } - - std::vector > opt_q; - const size_t vec_len = scalar_end - scalar_start; - const size_t odd_vec_len = (vec_len % 2 == 1 ? vec_len : vec_len + 1); - opt_q.reserve(odd_vec_len); - std::vector g; - g.reserve(odd_vec_len); - - typename std::vector::const_iterator vec_it; - typename std::vector::const_iterator scalar_it; - size_t i; - for (i=0, vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it, ++i) - { - g.emplace_back(*vec_it); - - opt_q.emplace_back(ordered_exponent(i, scalar_it->as_bigint())); - } - std::make_heap(opt_q.begin(),opt_q.end()); - assert_except(scalar_it == scalar_end); - - if (vec_len != odd_vec_len) - { - g.emplace_back(T::zero()); - opt_q.emplace_back(ordered_exponent(odd_vec_len - 1, bigint(UINT64_C(0)))); - } - assert_except(g.size() % 2 == 1); - assert_except(opt_q.size() == g.size()); - - T opt_result = T::zero(); - - while (true) - { - ordered_exponent &a = opt_q[0]; - ordered_exponent &b = (opt_q[1] < opt_q[2] ? opt_q[2] : opt_q[1]); - - const size_t abits = a.r.num_bits(); - - if (b.r.is_zero()) - { - // opt_result = opt_result + (a.r * g[a.idx]); - opt_result = opt_result + opt_window_wnaf_exp(g[a.idx], a.r, abits); - break; - } - - const size_t bbits = b.r.num_bits(); - const size_t limit = (abits-bbits >= 20 ? 20 : abits-bbits); - - if (bbits < UINT64_C(1)< (x-y) A + y (B+A) - mpn_sub_n(a.r.data, a.r.data, b.r.data, n); - g[b.idx] = g[b.idx] + g[a.idx]; - } - - // regardless of whether a was cleared or subtracted from we push it down, then take back up - - /* heapify A down */ - size_t a_pos = 0; - while (2*a_pos + 2< odd_vec_len) - { - // this is a max-heap so to maintain a heap property we swap with the largest of the two - if (opt_q[2*a_pos+1] < opt_q[2*a_pos+2]) - { - std::swap(opt_q[a_pos], opt_q[2*a_pos+2]); - a_pos = 2*a_pos+2; - } - else - { - std::swap(opt_q[a_pos], opt_q[2*a_pos+1]); - a_pos = 2*a_pos+1; - } - } - - /* now heapify A up appropriate amount of times */ - while (a_pos > 0 && opt_q[(a_pos-1)/2] < opt_q[a_pos]) - { - std::swap(opt_q[a_pos], opt_q[(a_pos-1)/2]); - a_pos = (a_pos-1) / 2; - } - } - - return opt_result; -} - -template -T multi_exp(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp) -{ - const size_t total = vec_end - vec_start; - if (total < chunks) - { - return naive_exp(vec_start, vec_end, scalar_start, scalar_end); - } - - const size_t one = total/chunks; - - std::vector partial(chunks, T::zero()); - - if (use_multiexp) - { -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < chunks; ++i) - { - partial[i] = multi_exp_inner(vec_start + i*one, - (i == chunks-1 ? vec_end : vec_start + (i+1)*one), - scalar_start + i*one, - (i == chunks-1 ? scalar_end : scalar_start + (i+1)*one)); - } - } - else - { -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < chunks; ++i) - { - partial[i] = naive_exp(vec_start + i*one, - (i == chunks-1 ? vec_end : vec_start + (i+1)*one), - scalar_start + i*one, - (i == chunks-1 ? scalar_end : scalar_start + (i+1)*one)); - } - } - - T final = T::zero(); - - for (size_t i = 0; i < chunks; ++i) - { - final = final + partial[i]; - } - - return final; -} - -template -T multi_exp_with_mixed_addition(typename std::vector::const_iterator vec_start, - typename std::vector::const_iterator vec_end, - typename std::vector::const_iterator scalar_start, - typename std::vector::const_iterator scalar_end, - const size_t chunks, - const bool use_multiexp) -{ - assert_except(std::distance(vec_start, vec_end) == std::distance(scalar_start, scalar_end)); - enter_block("Process scalar vector"); - auto value_it = vec_start; - auto scalar_it = scalar_start; - - const FieldT zero = FieldT::zero(); - const FieldT one = FieldT::one(); - std::vector p; - std::vector g; - - T acc = T::zero(); - - size_t num_skip = 0; - size_t num_add = 0; - size_t num_other = 0; - - for (; scalar_it != scalar_end; ++scalar_it, ++value_it) - { - if (*scalar_it == zero) - { - // do nothing - ++num_skip; - } - else if (*scalar_it == one) - { -#ifdef USE_MIXED_ADDITION - acc = acc.mixed_add(*value_it); -#else - acc = acc + (*value_it); -#endif - ++num_add; - } - else - { - p.emplace_back(*scalar_it); - g.emplace_back(*value_it); - ++num_other; - } - } - //print_indent(); printf("* Elements of w skipped: %zu (%0.2f%%)\n", num_skip, 100.*num_skip/(num_skip+num_add+num_other)); - //print_indent(); printf("* Elements of w processed with special addition: %zu (%0.2f%%)\n", num_add, 100.*num_add/(num_skip+num_add+num_other)); - //print_indent(); printf("* Elements of w remaining: %zu (%0.2f%%)\n", num_other, 100.*num_other/(num_skip+num_add+num_other)); - - leave_block("Process scalar vector"); - - return acc + multi_exp(g.begin(), g.end(), p.begin(), p.end(), chunks, use_multiexp); -} - -template -size_t get_exp_window_size(const size_t num_scalars) -{ - if (T::fixed_base_exp_window_table.empty()) - { -#ifdef LOWMEM - return 14; -#else - return 17; -#endif - } - size_t window = 1; - for (int64_t i = T::fixed_base_exp_window_table.size()-1; i >= 0; --i) - { -#ifdef DEBUG - if (!inhibit_profiling_info) - { - printf("%ld %zu %zu\n", i, num_scalars, T::fixed_base_exp_window_table[i]); - } -#endif - if (T::fixed_base_exp_window_table[i] != 0 && num_scalars >= T::fixed_base_exp_window_table[i]) - { - window = i+1; - break; - } - } - - if (!inhibit_profiling_info) - { - print_indent(); printf("Choosing window size %zu for %zu elements\n", window, num_scalars); - } - -#ifdef LOWMEM - window = std::min((size_t)14, window); -#endif - return window; -} - -template -window_table get_window_table(const size_t scalar_size, - const size_t window, - const T &g) -{ - const size_t in_window = UINT64_C(1)< powers_of_g(outerc, std::vector(in_window, T::zero())); - - T gouter = g; - - for (size_t outer = 0; outer < outerc; ++outer) - { - T ginner = T::zero(); - size_t cur_in_window = outer == outerc-1 ? last_in_window : in_window; - for (size_t inner = 0; inner < cur_in_window; ++inner) - { - powers_of_g[outer][inner] = ginner; - ginner = ginner + gouter; - } - - for (size_t i = 0; i < window; ++i) - { - gouter = gouter + gouter; - } - } - - return powers_of_g; -} - -template -T windowed_exp(const size_t scalar_size, - const size_t window, - const window_table &powers_of_g, - const FieldT &pow) -{ - const size_t outerc = (scalar_size+window-1)/window; - const bigint pow_val = pow.as_bigint(); - - /* exp */ - T res = powers_of_g[0][0]; - - for (size_t outer = 0; outer < outerc; ++outer) - { - size_t inner = 0; - for (size_t i = 0; i < window; ++i) - { - if (pow_val.test_bit(outer*window + i)) - { - inner |= 1u << i; - } - } - - res = res + powers_of_g[outer][inner]; - } - - return res; -} - -template -std::vector batch_exp(const size_t scalar_size, - const size_t window, - const window_table &table, - const std::vector &v) -{ - if (!inhibit_profiling_info) - { - print_indent(); - } - std::vector res(v.size(), table[0][0]); - -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < v.size(); ++i) - { - res[i] = windowed_exp(scalar_size, window, table, v[i]); - - if (!inhibit_profiling_info && (i % 10000 == 0)) - { - printf("."); - fflush(stdout); - } - } - - if (!inhibit_profiling_info) - { - printf(" DONE!\n"); - } - - return res; -} - -template -std::vector batch_exp_with_coeff(const size_t scalar_size, - const size_t window, - const window_table &table, - const FieldT &coeff, - const std::vector &v) -{ - if (!inhibit_profiling_info) - { - print_indent(); - } - std::vector res(v.size(), table[0][0]); - -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < v.size(); ++i) - { - res[i] = windowed_exp(scalar_size, window, table, coeff * v[i]); - - if (!inhibit_profiling_info && (i % 10000 == 0)) - { - printf("."); - fflush(stdout); - } - } - - if (!inhibit_profiling_info) - { - printf(" DONE!\n"); - } - - return res; -} - -template -void batch_to_special(std::vector &vec) -{ - enter_block("Batch-convert elements to special form"); - - std::vector non_zero_vec; - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].is_zero()) - { - non_zero_vec.emplace_back(vec[i]); - } - } - - batch_to_special_all_non_zeros(non_zero_vec); - auto it = non_zero_vec.begin(); - T zero_special = T::zero(); - zero_special.to_special(); - - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].is_zero()) - { - vec[i] = *it; - ++it; - } - else - { - vec[i] = zero_special; - } - } - leave_block("Batch-convert elements to special form"); -} - -} // libsnark - -#endif // MULTIEXP_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp deleted file mode 100644 index d6c43267e..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for wNAF ("width-w Non-Adjacent Form") exponentiation routines. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef WNAF_HPP_ -#define WNAF_HPP_ - -namespace libsnark { - -/** - * Find the wNAF representation of the given scalar relative to the given window size. - */ -template -std::vector find_wnaf(const size_t window_size, const bigint &scalar); - -/** - * In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base. - */ -template -T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar); - -/** - * In additive notation, use wNAF exponentiation (with the window size determined by T) to compute scalar * base. - */ -template -T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits); - -} // libsnark - -#include "algebra/scalar_multiplication/wnaf.tcc" - -#endif // WNAF_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc deleted file mode 100644 index 4f2e4072c..000000000 --- a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc +++ /dev/null @@ -1,123 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for wNAF ("weighted Non-Adjacent Form") exponentiation routines. - - See wnaf.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef WNAF_TCC_ -#define WNAF_TCC_ - -namespace libsnark { - -template -std::vector find_wnaf(const size_t window_size, const bigint &scalar) -{ - const size_t length = scalar.max_bits(); // upper bound - std::vector res(length+1); - bigint c = scalar; - int64_t j = 0; - while (!c.is_zero()) - { - int64_t u; - if ((c.data[0] & 1) == 1) - { - u = c.data[0] % (1u << (window_size+1)); - if (u > (1 << window_size)) - { - u = u - (1 << (window_size+1)); - } - - if (u > 0) - { - mpn_sub_1(c.data, c.data, n, u); - } - else - { - mpn_add_1(c.data, c.data, n, -u); - } - } - else - { - u = 0; - } - res[j] = u; - ++j; - - mpn_rshift(c.data, c.data, n, 1); // c = c/2 - } - - return res; -} - -template -T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar) -{ - std::vector naf = find_wnaf(window_size, scalar); - std::vector table(UINT64_C(1)<<(window_size-1)); - T tmp = base; - T dbl = base.dbl(); - for (size_t i = 0; i < UINT64_C(1)<<(window_size-1); ++i) - { - table[i] = tmp; - tmp = tmp + dbl; - } - - T res = T::zero(); - bool found_nonzero = false; - for (int64_t i = naf.size()-1; i >= 0; --i) - { - if (found_nonzero) - { - res = res.dbl(); - } - - if (naf[i] != 0) - { - found_nonzero = true; - if (naf[i] > 0) - { - res = res + table[naf[i]/2]; - } - else - { - res = res - table[(-naf[i])/2]; - } - } - } - - return res; -} - -template -T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits) -{ - size_t best = 0; - for (int64_t i = T::wnaf_window_table.size() - 1; i >= 0; --i) - { - if (scalar_bits >= T::wnaf_window_table[i]) - { - best = i+1; - break; - } - } - - if (best > 0) - { - return fixed_window_wnaf_exp(best, base, scalar); - } - else - { - return scalar * base; - } -} - -} // libsnark - -#endif // WNAF_TCC_ diff --git a/src/snark/libsnark/common/assert_except.hpp b/src/snark/libsnark/common/assert_except.hpp deleted file mode 100644 index 781923044..000000000 --- a/src/snark/libsnark/common/assert_except.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ASSERT_except_H -#define ASSERT_except_H - -#include - -inline void assert_except(bool condition) { - if (!condition) { - throw std::runtime_error("Assertion failed."); - } -} - -#endif diff --git a/src/snark/libsnark/common/data_structures/accumulation_vector.hpp b/src/snark/libsnark/common/data_structures/accumulation_vector.hpp deleted file mode 100644 index 37e0c9841..000000000 --- a/src/snark/libsnark/common/data_structures/accumulation_vector.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for an accumulation vector. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ACCUMULATION_VECTOR_HPP_ -#define ACCUMULATION_VECTOR_HPP_ - -#include "common/data_structures/sparse_vector.hpp" - -namespace libsnark { - -template -class accumulation_vector; - -template -std::ostream& operator<<(std::ostream &out, const accumulation_vector &v); - -template -std::istream& operator>>(std::istream &in, accumulation_vector &v); - -/** - * An accumulation vector comprises an accumulation value and a sparse vector. - * The method "accumulate_chunk" allows one to accumlate portions of the sparse - * vector into the accumualation value. - */ -template -class accumulation_vector { -public: - T first; - sparse_vector rest; - - accumulation_vector() = default; - accumulation_vector(const accumulation_vector &other) = default; - accumulation_vector(accumulation_vector &&other) = default; - accumulation_vector(T &&first, sparse_vector &&rest) : first(std::move(first)), rest(std::move(rest)) {}; - accumulation_vector(T &&first, std::vector &&v) : first(std::move(first)), rest(std::move(v)) {} - accumulation_vector(std::vector &&v) : first(T::zero()), rest(std::move(v)) {}; - - accumulation_vector& operator=(const accumulation_vector &other) = default; - accumulation_vector& operator=(accumulation_vector &&other) = default; - - bool operator==(const accumulation_vector &other) const; - - bool is_fully_accumulated() const; - - size_t domain_size() const; - size_t size() const; - size_t size_in_bits() const; - - template - accumulation_vector accumulate_chunk(const typename std::vector::const_iterator &it_begin, - const typename std::vector::const_iterator &it_end, - const size_t offset) const; - -}; - -template -std::ostream& operator<<(std::ostream &out, const accumulation_vector &v); - -template -std::istream& operator>>(std::istream &in, accumulation_vector &v); - -} // libsnark - -#include "common/data_structures/accumulation_vector.tcc" - -#endif // ACCUMULATION_VECTOR_HPP_ diff --git a/src/snark/libsnark/common/data_structures/accumulation_vector.tcc b/src/snark/libsnark/common/data_structures/accumulation_vector.tcc deleted file mode 100644 index 9e524aba7..000000000 --- a/src/snark/libsnark/common/data_structures/accumulation_vector.tcc +++ /dev/null @@ -1,84 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for an accumulation vector. - - See accumulation_vector.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef ACCUMULATION_VECTOR_TCC_ -#define ACCUMULATION_VECTOR_TCC_ - -namespace libsnark { - -template -bool accumulation_vector::operator==(const accumulation_vector &other) const -{ - return (this->first == other.first && this->rest == other.rest); -} - -template -bool accumulation_vector::is_fully_accumulated() const -{ - return rest.empty(); -} - -template -size_t accumulation_vector::domain_size() const -{ - return rest.domain_size(); -} - -template -size_t accumulation_vector::size() const -{ - return rest.domain_size(); -} - -template -size_t accumulation_vector::size_in_bits() const -{ - const size_t first_size_in_bits = T::size_in_bits(); - const size_t rest_size_in_bits = rest.size_in_bits(); - return first_size_in_bits + rest_size_in_bits; -} - -template -template -accumulation_vector accumulation_vector::accumulate_chunk(const typename std::vector::const_iterator &it_begin, - const typename std::vector::const_iterator &it_end, - const size_t offset) const -{ - std::pair > acc_result = rest.template accumulate(it_begin, it_end, offset); - T new_first = first + acc_result.first; - return accumulation_vector(std::move(new_first), std::move(acc_result.second)); -} - -template -std::ostream& operator<<(std::ostream& out, const accumulation_vector &v) -{ - out << v.first << OUTPUT_NEWLINE; - out << v.rest << OUTPUT_NEWLINE; - - return out; -} - -template -std::istream& operator>>(std::istream& in, accumulation_vector &v) -{ - in >> v.first; - consume_OUTPUT_NEWLINE(in); - in >> v.rest; - consume_OUTPUT_NEWLINE(in); - - return in; -} - -} // libsnark - -#endif // ACCUMULATION_VECTOR_TCC_ diff --git a/src/snark/libsnark/common/data_structures/merkle_tree.hpp b/src/snark/libsnark/common/data_structures/merkle_tree.hpp deleted file mode 100644 index 6f0c851ba..000000000 --- a/src/snark/libsnark/common/data_structures/merkle_tree.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a Merkle tree. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_HPP_ -#define MERKLE_TREE_HPP_ - -#include -#include -#include "common/utils.hpp" - -namespace libsnark { - -/** - * A Merkle tree is maintained as two maps: - * - a map from addresses to values, and - * - a map from addresses to hashes. - * - * The second map maintains the intermediate hashes of a Merkle tree - * built atop the values currently stored in the tree (the - * implementation admits a very efficient support for sparse - * trees). Besides offering methods to load and store values, the - * class offers methods to retrieve the root of the Merkle tree and to - * obtain the authentication paths for (the value at) a given address. - */ - -typedef bit_vector merkle_authentication_node; -typedef std::vector merkle_authentication_path; - -template -class merkle_tree { -private: - - typedef typename HashT::hash_value_type hash_value_type; - typedef typename HashT::merkle_authentication_path_type merkle_authentication_path_type; - -public: - - std::vector hash_defaults; - std::map values; - std::map hashes; - - size_t depth; - size_t value_size; - size_t digest_size; - - merkle_tree(const size_t depth, const size_t value_size); - merkle_tree(const size_t depth, const size_t value_size, const std::vector &contents_as_vector); - merkle_tree(const size_t depth, const size_t value_size, const std::map &contents); - - bit_vector get_value(const size_t address) const; - void set_value(const size_t address, const bit_vector &value); - - hash_value_type get_root() const; - merkle_authentication_path_type get_path(const size_t address) const; - - void dump() const; -}; - -} // libsnark - -#include "common/data_structures/merkle_tree.tcc" - -#endif // MERKLE_TREE_HPP_ diff --git a/src/snark/libsnark/common/data_structures/merkle_tree.tcc b/src/snark/libsnark/common/data_structures/merkle_tree.tcc deleted file mode 100644 index ce28b124f..000000000 --- a/src/snark/libsnark/common/data_structures/merkle_tree.tcc +++ /dev/null @@ -1,246 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for Merkle tree. - - See merkle_tree.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_TCC -#define MERKLE_TREE_TCC - -#include - -#include "common/profiling.hpp" -#include "common/utils.hpp" - -namespace libsnark { - -template -typename HashT::hash_value_type two_to_one_CRH(const typename HashT::hash_value_type &l, - const typename HashT::hash_value_type &r) -{ - typename HashT::hash_value_type new_input; - new_input.insert(new_input.end(), l.begin(), l.end()); - new_input.insert(new_input.end(), r.begin(), r.end()); - - const size_t digest_size = HashT::get_digest_len(); - assert(l.size() == digest_size); - assert(r.size() == digest_size); - - return HashT::get_hash(new_input); -} - -template -merkle_tree::merkle_tree(const size_t depth, const size_t value_size) : - depth(depth), value_size(value_size) -{ - assert(depth < sizeof(size_t) * 8); - - digest_size = HashT::get_digest_len(); - assert(value_size <= digest_size); - - hash_value_type last(digest_size); - hash_defaults.reserve(depth+1); - hash_defaults.emplace_back(last); - for (size_t i = 0; i < depth; ++i) - { - last = two_to_one_CRH(last, last); - hash_defaults.emplace_back(last); - } - - std::reverse(hash_defaults.begin(), hash_defaults.end()); -} - -template -merkle_tree::merkle_tree(const size_t depth, - const size_t value_size, - const std::vector &contents_as_vector) : - merkle_tree(depth, value_size) -{ - assert(log2(contents_as_vector.size()) <= depth); - for (size_t address = 0; address < contents_as_vector.size(); ++address) - { - const size_t idx = address + (UINT64_C(1)< 0; --layer) - { - for (size_t idx = idx_begin; idx < idx_end; idx += 2) - { - hash_value_type l = hashes[idx]; // this is sound, because idx_begin is always a left child - hash_value_type r = (idx + 1 < idx_end ? hashes[idx+1] : hash_defaults[layer]); - - hash_value_type h = two_to_one_CRH(l, r); - hashes[(idx-1)/2] = h; - } - - idx_begin = (idx_begin-1)/2; - idx_end = (idx_end-1)/2; - } -} - -template -merkle_tree::merkle_tree(const size_t depth, - const size_t value_size, - const std::map &contents) : - merkle_tree(depth, value_size) -{ - - if (!contents.empty()) - { - assert(contents.rbegin()->first < UINT64_C(1)<first; - const bit_vector value = it->second; - const size_t idx = address + (UINT64_C(1)< 0; --layer) - { - auto next_last_it = hashes.begin(); - - for (auto it = hashes.begin(); it != last_it; ++it) - { - const size_t idx = it->first; - const hash_value_type hash = it->second; - - if (idx % 2 == 0) - { - // this is the right child of its parent and by invariant we are missing the left child - hashes[(idx-1)/2] = two_to_one_CRH(hash_defaults[layer], hash); - } - else - { - if (std::next(it) == last_it || std::next(it)->first != idx + 1) - { - // this is the left child of its parent and is missing its right child - hashes[(idx-1)/2] = two_to_one_CRH(hash, hash_defaults[layer]); - } - else - { - // typical case: this is the left child of the parent and adjecent to it there is a right child - hashes[(idx-1)/2] = two_to_one_CRH(hash, std::next(it)->second); - ++it; - } - } - } - - last_it = next_last_it; - } - } -} - -template -bit_vector merkle_tree::get_value(const size_t address) const -{ - assert(log2(address) <= depth); - - auto it = values.find(address); - bit_vector padded_result = (it == values.end() ? bit_vector(digest_size) : it->second); - padded_result.resize(value_size); - - return padded_result; -} - -template -void merkle_tree::set_value(const size_t address, - const bit_vector &value) -{ - assert(log2(address) <= depth); - size_t idx = address + (UINT64_C(1)<=0; --layer) - { - idx = (idx-1)/2; - - auto it = hashes.find(2*idx+1); - hash_value_type l = (it == hashes.end() ? hash_defaults[layer+1] : it->second); - - it = hashes.find(2*idx+2); - hash_value_type r = (it == hashes.end() ? hash_defaults[layer+1] : it->second); - - hash_value_type h = two_to_one_CRH(l, r); - hashes[idx] = h; - } -} - -template -typename HashT::hash_value_type merkle_tree::get_root() const -{ - auto it = hashes.find(0); - return (it == hashes.end() ? hash_defaults[0] : it->second); -} - -template -typename HashT::merkle_authentication_path_type merkle_tree::get_path(const size_t address) const -{ - typename HashT::merkle_authentication_path_type result(depth); - assert(log2(address) <= depth); - size_t idx = address + (UINT64_C(1)< 0; --layer) - { - size_t sibling_idx = ((idx + 1) ^ 1) - 1; - auto it = hashes.find(sibling_idx); - if (layer == depth) - { - auto it2 = values.find(sibling_idx - ((UINT64_C(1)<second); - result[layer-1].resize(digest_size); - } - else - { - result[layer-1] = (it == hashes.end() ? hash_defaults[layer] : it->second); - } - - idx = (idx-1)/2; - } - - return result; -} - -template -void merkle_tree::dump() const -{ - for (size_t i = 0; i < UINT64_C(1)< ", i); - const bit_vector value = (it == values.end() ? bit_vector(value_size) : it->second); - for (bool b : value) - { - printf("%d", b ? 1 : 0); - } - printf("\n"); - } - printf("\n"); -} - -} // libsnark - -#endif // MERKLE_TREE_TCC diff --git a/src/snark/libsnark/common/data_structures/sparse_vector.hpp b/src/snark/libsnark/common/data_structures/sparse_vector.hpp deleted file mode 100644 index 20f1bc267..000000000 --- a/src/snark/libsnark/common/data_structures/sparse_vector.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a sparse vector. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SPARSE_VECTOR_HPP_ -#define SPARSE_VECTOR_HPP_ - -#include - -namespace libsnark { - -template -struct sparse_vector; - -template -std::ostream& operator<<(std::ostream &out, const sparse_vector &v); - -template -std::istream& operator>>(std::istream &in, sparse_vector &v); - -/** - * A sparse vector is a list of indices along with corresponding values. - * The indices are selected from the set {0,1,...,domain_size-1}. - */ -template -struct sparse_vector { - - std::vector indices; - std::vector values; - uint64_t domain_size_ = 0; - - sparse_vector() = default; - sparse_vector(const sparse_vector &other) = default; - sparse_vector(sparse_vector &&other) = default; - sparse_vector(std::vector &&v); /* constructor from std::vector */ - - sparse_vector& operator=(const sparse_vector &other) = default; - sparse_vector& operator=(sparse_vector &&other) = default; - - T operator[](const uint64_t idx) const; - - bool operator==(const sparse_vector &other) const; - bool operator==(const std::vector &other) const; - - bool is_valid() const; - bool empty() const; - - uint64_t domain_size() const; // return domain_size_ - uint64_t size() const; // return the number of indices (representing the number of non-zero entries) - uint64_t size_in_bits() const; // return the number bits needed to store the sparse vector - - /* return a pair consisting of the accumulated value and the sparse vector of non-accumuated values */ - template - std::pair > accumulate(const typename std::vector::const_iterator &it_begin, - const typename std::vector::const_iterator &it_end, - const uint64_t offset) const; - - friend std::ostream& operator<< (std::ostream &out, const sparse_vector &v); - friend std::istream& operator>> (std::istream &in, sparse_vector &v); -}; - -template -std::ostream& operator<<(std::ostream& out, const sparse_vector &v); - -template -std::istream& operator>>(std::istream& in, sparse_vector &v); - -} // libsnark - -#include "common/data_structures/sparse_vector.tcc" - -#endif // SPARSE_VECTOR_HPP_ diff --git a/src/snark/libsnark/common/data_structures/sparse_vector.tcc b/src/snark/libsnark/common/data_structures/sparse_vector.tcc deleted file mode 100644 index 906ed16d9..000000000 --- a/src/snark/libsnark/common/data_structures/sparse_vector.tcc +++ /dev/null @@ -1,316 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for a sparse vector. - - See sparse_vector.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SPARSE_VECTOR_TCC_ -#define SPARSE_VECTOR_TCC_ - -#include "algebra/scalar_multiplication/multiexp.hpp" - -#include - -namespace libsnark { - -template -sparse_vector::sparse_vector(std::vector &&v) : - values(std::move(v)), domain_size_(values.size()) -{ - indices.resize(domain_size_); - std::iota(indices.begin(), indices.end(), 0); -} - -template -T sparse_vector::operator[](const uint64_t idx) const -{ - auto it = std::lower_bound(indices.begin(), indices.end(), idx); - return (it != indices.end() && *it == idx) ? values[it - indices.begin()] : T(); -} - -template -bool sparse_vector::operator==(const sparse_vector &other) const -{ - if (this->domain_size_ != other.domain_size_) - { - return false; - } - - uint64_t this_pos = 0, other_pos = 0; - while (this_pos < this->indices.size() && other_pos < other.indices.size()) - { - if (this->indices[this_pos] == other.indices[other_pos]) - { - if (this->values[this_pos] != other.values[other_pos]) - { - return false; - } - ++this_pos; - ++other_pos; - } - else if (this->indices[this_pos] < other.indices[other_pos]) - { - if (!this->values[this_pos].is_zero()) - { - return false; - } - ++this_pos; - } - else - { - if (!other.values[other_pos].is_zero()) - { - return false; - } - ++other_pos; - } - } - - /* at least one of the vectors has been exhausted, so other must be empty */ - while (this_pos < this->indices.size()) - { - if (!this->values[this_pos].is_zero()) - { - return false; - } - ++this_pos; - } - - while (other_pos < other.indices.size()) - { - if (!other.values[other_pos].is_zero()) - { - return false; - } - ++other_pos; - } - - return true; -} - -template -bool sparse_vector::operator==(const std::vector &other) const -{ - if (this->domain_size_ < other.size()) - { - return false; - } - - uint64_t j = 0; - for (uint64_t i = 0; i < other.size(); ++i) - { - if (this->indices[j] == i) - { - if (this->values[j] != other[j]) - { - return false; - } - ++j; - } - else - { - if (!other[j].is_zero()) - { - return false; - } - } - } - - return true; -} - -template -bool sparse_vector::is_valid() const -{ - if (values.size() == indices.size() && values.size() <= domain_size_) - { - return false; - } - - for (uint64_t i = 0; i + 1 < indices.size(); ++i) - { - if (indices[i] >= indices[i+1]) - { - return false; - } - } - - if (!indices.empty() && indices[indices.size()-1] >= domain_size_) - { - return false; - } - - return true; -} - -template -bool sparse_vector::empty() const -{ - return indices.empty(); -} - -template -uint64_t sparse_vector::domain_size() const -{ - return domain_size_; -} - -template -uint64_t sparse_vector::size() const -{ - return indices.size(); -} - -template -uint64_t sparse_vector::size_in_bits() const -{ - return indices.size() * (sizeof(uint64_t) * 8 + T::size_in_bits()); -} - -template -template -std::pair > sparse_vector::accumulate(const typename std::vector::const_iterator &it_begin, - const typename std::vector::const_iterator &it_end, - const uint64_t offset) const -{ - // TODO: does not really belong here. - const uint64_t chunks = 1; - const bool use_multiexp = true; - - T accumulated_value = T::zero(); - sparse_vector resulting_vector; - resulting_vector.domain_size_ = domain_size_; - - const uint64_t range_len = it_end - it_begin; - bool in_block = false; - uint64_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases. - - for (uint64_t i = 0; i < indices.size(); ++i) - { - const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len); - // printf("i = %zu, pos[i] = %zu, offset = %zu, w_size = %zu\n", i, indices[i], offset, w_size); - bool copy_over; - - if (in_block) - { - if (matching_pos && last_pos == i-1) - { - // block can be extended, do it - last_pos = i; - copy_over = false; - } - else - { - // block has ended here - in_block = false; - copy_over = true; - -#ifdef DEBUG - print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); -#endif - accumulated_value = accumulated_value + multi_exp(values.begin() + first_pos, - values.begin() + last_pos + 1, - it_begin + (indices[first_pos] - offset), - it_begin + (indices[last_pos] - offset) + 1, - chunks, use_multiexp); - } - } - else - { - if (matching_pos) - { - // block can be started - first_pos = i; - last_pos = i; - in_block = true; - copy_over = false; - } - else - { - copy_over = true; - } - } - - if (copy_over) - { - resulting_vector.indices.emplace_back(indices[i]); - resulting_vector.values.emplace_back(values[i]); - } - } - - if (in_block) - { -#ifdef DEBUG - print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); -#endif - accumulated_value = accumulated_value + multi_exp(values.begin() + first_pos, - values.begin() + last_pos + 1, - it_begin + (indices[first_pos] - offset), - it_begin + (indices[last_pos] - offset) + 1, - chunks, use_multiexp); - } - - return std::make_pair(accumulated_value, resulting_vector); -} - -template -std::ostream& operator<<(std::ostream& out, const sparse_vector &v) -{ - out << v.domain_size_ << "\n"; - out << v.indices.size() << "\n"; - for (const uint64_t& i : v.indices) - { - out << i << "\n"; - } - - out << v.values.size() << "\n"; - for (const T& t : v.values) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -template -std::istream& operator>>(std::istream& in, sparse_vector &v) -{ - in >> v.domain_size_; - consume_newline(in); - - uint64_t s; - in >> s; - consume_newline(in); - v.indices.resize(s); - for (uint64_t i = 0; i < s; ++i) - { - in >> v.indices[i]; - consume_newline(in); - } - - v.values.clear(); - in >> s; - consume_newline(in); - v.values.reserve(s); - - for (uint64_t i = 0; i < s; ++i) - { - T t; - in >> t; - consume_OUTPUT_NEWLINE(in); - v.values.emplace_back(t); - } - - return in; -} - -} // libsnark - -#endif // SPARSE_VECTOR_TCC_ diff --git a/src/snark/libsnark/common/default_types/ec_pp.hpp b/src/snark/libsnark/common/default_types/ec_pp.hpp deleted file mode 100644 index b08c2da88..000000000 --- a/src/snark/libsnark/common/default_types/ec_pp.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/** @file - ***************************************************************************** - - This file defines default_ec_pp based on the CURVE=... make flag, which selects - which elliptic curve is used to implement group arithmetic and pairings. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef EC_PP_HPP_ -#define EC_PP_HPP_ - -/************************ Pick the elliptic curve ****************************/ - -#ifdef CURVE_ALT_BN128 -#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" -namespace libsnark { -typedef alt_bn128_pp default_ec_pp; -} // libsnark -#endif - -#ifdef CURVE_BN128 -#include "algebra/curves/bn128/bn128_pp.hpp" -namespace libsnark { -typedef bn128_pp default_ec_pp; -} // libsnark -#endif - -#ifdef CURVE_EDWARDS -#include "algebra/curves/edwards/edwards_pp.hpp" -namespace libsnark { -typedef edwards_pp default_ec_pp; -} // libsnark -#endif - -#ifdef CURVE_MNT4 -#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" -namespace libsnark { -typedef mnt4_pp default_ec_pp; -} // libsnark -#endif - -#ifdef CURVE_MNT6 -#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -namespace libsnark { -typedef mnt6_pp default_ec_pp; -} // libsnark -#endif - -#endif // EC_PP_HPP_ diff --git a/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp b/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp deleted file mode 100644 index c819b4a85..000000000 --- a/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/** @file - ***************************************************************************** - - This file defines default_r1cs_ppzksnark_pp based on the elliptic curve - choice selected in ec_pp.hpp. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_PPZKSNARK_PP_HPP_ -#define R1CS_PPZKSNARK_PP_HPP_ - -#include "common/default_types/ec_pp.hpp" - -namespace libsnark { -typedef default_ec_pp default_r1cs_ppzksnark_pp; -} // libsnark - -#endif // R1CS_PPZKSNARK_PP_HPP_ diff --git a/src/snark/libsnark/common/profiling.cpp b/src/snark/libsnark/common/profiling.cpp deleted file mode 100644 index 38b387d97..000000000 --- a/src/snark/libsnark/common/profiling.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of functions for profiling code blocks. - - See profiling.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "common/profiling.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include "common/default_types/ec_pp.hpp" -#include "common/utils.hpp" - -#ifndef NO_PROCPS -#include -#endif - -#ifdef __MACH__ // required to build on MacOS -#include -#include -#include -#include -#endif - -namespace libsnark { - -int64_t get_nsec_time() -{ - auto timepoint = std::chrono::high_resolution_clock::now(); - return std::chrono::duration_cast(timepoint.time_since_epoch()).count(); -} - -/* Return total CPU time consumed by all threads of the process, in nanoseconds. */ -int64_t get_nsec_cpu_time() -{ - ::timespec ts; - #ifdef __MACH__ - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - #else - if ( ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) ) - throw ::std::runtime_error("clock_gettime(CLOCK_PROCESS_CPUTIME_ID) failed"); - // If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef . - //TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__? - #endif - return ts.tv_sec * 1000000000ll + ts.tv_nsec; -} - -static int64_t start_time; -static int64_t last_time; -static int64_t start_cpu_time; -static int64_t last_cpu_time; - -void start_profiling() -{ - printf("Reset time counters for profiling\n"); - - last_time = start_time = get_nsec_time(); - last_cpu_time = start_cpu_time = get_nsec_cpu_time(); -} - -std::map invocation_counts; -static std::map enter_times; -std::map last_times; -std::map cumulative_times; -//TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map -static std::map enter_cpu_times; -static std::map last_cpu_times; -static std::map, int64_t> op_counts; -static std::map, int64_t> cumulative_op_counts; // ((msg, data_point), value) - // TODO: Convert op_counts and cumulative_op_counts from pair to structs -static size_t indentation = 0; - -static std::vector block_names; - -static std::list > op_data_points = { -#ifdef PROFILE_OP_COUNTS - std::make_pair("Fradd", &Fr::add_cnt), - std::make_pair("Frsub", &Fr::sub_cnt), - std::make_pair("Frmul", &Fr::mul_cnt), - std::make_pair("Frinv", &Fr::inv_cnt), - std::make_pair("Fqadd", &Fq::add_cnt), - std::make_pair("Fqsub", &Fq::sub_cnt), - std::make_pair("Fqmul", &Fq::mul_cnt), - std::make_pair("Fqinv", &Fq::inv_cnt), - std::make_pair("G1add", &G1::add_cnt), - std::make_pair("G1dbl", &G1::dbl_cnt), - std::make_pair("G2add", &G2::add_cnt), - std::make_pair("G2dbl", &G2::dbl_cnt) -#endif -}; - -bool inhibit_profiling_info = true; -bool inhibit_profiling_counters = false; - -void clear_profiling_counters() -{ - invocation_counts.clear(); - last_times.clear(); - last_cpu_times.clear(); - cumulative_times.clear(); -} - -void print_cumulative_time_entry(const std::string &key, const int64_t factor) -{ - const double total_ms = (cumulative_times.at(key) * 1e-6); - const size_t cnt = invocation_counts.at(key); - const double avg_ms = total_ms / cnt; - printf(" %-45s: %12.5fms = %" PRId64 " * %0.5fms (%zu invocations, %0.5fms = %" PRId64 " * %0.5fms per invocation)\n", key.c_str(), total_ms, factor, total_ms/factor, cnt, avg_ms, factor, avg_ms/factor); -} - -void print_cumulative_times(const int64_t factor) -{ - printf("Dumping times:\n"); - for (auto& kv : cumulative_times) - { - print_cumulative_time_entry(kv.first, factor); - } -} - -void print_cumulative_op_counts(const bool only_fq) -{ -#ifdef PROFILE_OP_COUNTS - printf("Dumping operation counts:\n"); - for (auto& msg : invocation_counts) - { - printf(" %-45s: ", msg.first.c_str()); - bool first = true; - for (auto& data_point : op_data_points) - { - if (only_fq && data_point.first.compare(0, 2, "Fq") != 0) - { - continue; - } - - if (!first) - { - printf(", "); - } - printf("%-5s = %7.0f (%3zu)", - data_point.first.c_str(), - 1. * cumulative_op_counts[std::make_pair(msg.first, data_point.first)] / msg.second, - msg.second); - first = false; - } - printf("\n"); - } -#else - UNUSED(only_fq); -#endif -} - -void print_op_profiling(const std::string &msg) -{ -#ifdef PROFILE_OP_COUNTS - printf("\n"); - print_indent(); - - printf("(opcounts) = ("); - bool first = true; - for (std::pair p : op_data_points) - { - if (!first) - { - printf(", "); - } - - printf("%s=%lld", p.first.c_str(), *(p.second)-op_counts[std::make_pair(msg, p.first)]); - first = false; - } - printf(")"); -#else - UNUSED(msg); -#endif -} - -static void print_times_from_last_and_start(int64_t now, int64_t last, - int64_t cpu_now, int64_t cpu_last) -{ - int64_t time_from_start = now - start_time; - int64_t time_from_last = now - last; - - int64_t cpu_time_from_start = cpu_now - start_cpu_time; - int64_t cpu_time_from_last = cpu_now - cpu_last; - - if (time_from_last != 0) { - double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last; - printf("[%0.4fs x%0.2f]", time_from_last * 1e-9, parallelism_from_last); - } else { - printf("[ ]"); - } - if (time_from_start != 0) { - double parallelism_from_start = 1.0 * cpu_time_from_start / time_from_start; - printf("\t(%0.4fs x%0.2f from start)", time_from_start * 1e-9, parallelism_from_start); - } -} - -void print_time(const char* msg) -{ - if (inhibit_profiling_info) - { - return; - } - - int64_t now = get_nsec_time(); - int64_t cpu_now = get_nsec_cpu_time(); - - printf("%-35s\t", msg); - print_times_from_last_and_start(now, last_time, cpu_now, last_cpu_time); -#ifdef PROFILE_OP_COUNTS - print_op_profiling(msg); -#endif - printf("\n"); - - fflush(stdout); - last_time = now; - last_cpu_time = cpu_now; -} - -void print_header(const char *msg) -{ - printf("\n================================================================================\n"); - printf("%s\n", msg); - printf("================================================================================\n\n"); -} - -void print_indent() -{ - for (size_t i = 0; i < indentation; ++i) - { - printf(" "); - } -} - -void op_profiling_enter(const std::string &msg) -{ - for (std::pair p : op_data_points) - { - op_counts[std::make_pair(msg, p.first)] = *(p.second); - } -} - -void enter_block(const std::string &msg, const bool indent) -{ - if (inhibit_profiling_counters) - { - return; - } - - block_names.emplace_back(msg); - int64_t t = get_nsec_time(); - enter_times[msg] = t; - int64_t cpu_t = get_nsec_cpu_time(); - enter_cpu_times[msg] = cpu_t; - - if (inhibit_profiling_info) - { - return; - } - -#ifdef MULTICORE -#pragma omp critical -#endif - { - op_profiling_enter(msg); - - print_indent(); - printf("(enter) %-35s\t", msg.c_str()); - print_times_from_last_and_start(t, t, cpu_t, cpu_t); - printf("\n"); - fflush(stdout); - - if (indent) - { - ++indentation; - } - } -} - -void leave_block(const std::string &msg, const bool indent) -{ - if (inhibit_profiling_counters) - { - return; - } - -#ifndef MULTICORE - assert(*(--block_names.end()) == msg); -#endif - block_names.pop_back(); - - ++invocation_counts[msg]; - - int64_t t = get_nsec_time(); - last_times[msg] = (t - enter_times[msg]); - cumulative_times[msg] += (t - enter_times[msg]); - - int64_t cpu_t = get_nsec_cpu_time(); - last_cpu_times[msg] = (cpu_t - enter_cpu_times[msg]); - -#ifdef PROFILE_OP_COUNTS - for (std::pair p : op_data_points) - { - cumulative_op_counts[std::make_pair(msg, p.first)] += *(p.second)-op_counts[std::make_pair(msg, p.first)]; - } -#endif - - if (inhibit_profiling_info) - { - return; - } - -#ifdef MULTICORE -#pragma omp critical -#endif - { - if (indent) - { - --indentation; - } - - print_indent(); - printf("(leave) %-35s\t", msg.c_str()); - print_times_from_last_and_start(t, enter_times[msg], cpu_t, enter_cpu_times[msg]); - print_op_profiling(msg); - printf("\n"); - fflush(stdout); - } -} - -void print_mem(const std::string &s) -{ -#ifndef NO_PROCPS - struct proc_t usage; - look_up_our_self(&usage); - if (s.empty()) - { - printf("* Peak vsize (physical memory+swap) in mebibytes: %lu\n", usage.vsize >> 20); - } - else - { - printf("* Peak vsize (physical memory+swap) in mebibytes (%s): %lu\n", s.c_str(), usage.vsize >> 20); - } -#else - printf("* Memory profiling not supported in NO_PROCPS mode\n"); -#endif -} - -void print_compilation_info() -{ -#ifdef __GNUC__ - printf("g++ version: %s\n", __VERSION__); - //printf("Compiled on %s %s\n", __DATE__, __TIME__); -#endif -#ifdef STATIC - printf("STATIC: yes\n"); -#else - printf("STATIC: no\n"); -#endif -#ifdef MULTICORE - printf("MULTICORE: yes\n"); -#else - printf("MULTICORE: no\n"); -#endif -#ifdef DEBUG - printf("DEBUG: yes\n"); -#else - printf("DEBUG: no\n"); -#endif -#ifdef PROFILE_OP_COUNTS - printf("PROFILE_OP_COUNTS: yes\n"); -#else - printf("PROFILE_OP_COUNTS: no\n"); -#endif -#ifdef _GLIBCXX_DEBUG - printf("_GLIBCXX_DEBUG: yes\n"); -#else - printf("_GLIBCXX_DEBUG: no\n"); -#endif -} - -} // libsnark diff --git a/src/snark/libsnark/common/profiling.hpp b/src/snark/libsnark/common/profiling.hpp deleted file mode 100644 index 4a496107b..000000000 --- a/src/snark/libsnark/common/profiling.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of functions for profiling code blocks. - - Reports time, operation counts, memory usage, and others. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PROFILING_HPP_ -#define PROFILING_HPP_ - -#include -#include -#include -#include - -namespace libsnark { - -void start_profiling(); -int64_t get_nsec_time(); -void print_time(const char* msg); -void print_header(const char* msg); - -void print_indent(); - -extern bool inhibit_profiling_info; -extern bool inhibit_profiling_counters; -extern std::map invocation_counts; -extern std::map last_times; -extern std::map cumulative_times; - -void clear_profiling_counters(); - -void print_cumulative_time_entry(const std::string &key, const int64_t factor=1); -void print_cumulative_times(const int64_t factor=1); -void print_cumulative_op_counts(const bool only_fq=false); - -void enter_block(const std::string &msg, const bool indent=true); -void leave_block(const std::string &msg, const bool indent=true); - -void print_mem(const std::string &s = ""); -void print_compilation_info(); - -} // libsnark - -#endif // PROFILING_HPP_ diff --git a/src/snark/libsnark/common/serialization.hpp b/src/snark/libsnark/common/serialization.hpp deleted file mode 100644 index c931c65b2..000000000 --- a/src/snark/libsnark/common/serialization.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of serialization routines and constants. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SERIALIZATION_HPP_ -#define SERIALIZATION_HPP_ - -#include -#include -#include -#include -#include - -namespace libsnark { - -/* - * @todo - * The serialization is fragile. Shoud be rewritten using a standard, portable-format - * library like boost::serialize. - * - * However, for now the following conventions are used within the code. - * - * All algebraic objects support either binary or decimal output using - * the standard C++ stream operators (operator<<, operator>>). - * - * The binary mode is activated by defining a BINARY_OUTPUT - * preprocessor macro (e.g. g++ -DBINARY_OUTPUT ...). - * - * Binary output assumes that the stream is to be binary read at its - * current position so any white space should be consumed beforehand. - * - * Consecutive algebraic objects are separated by OUTPUT_NEWLINE and - * within themselves (e.g. X and Y coordinates for field elements) with - * OUTPUT_SEPARATOR (as defined below). - * - * Therefore to dump two integers, two Fp elements and another integer - * one would: - * - * out << 3 << "\n"; - * out << 4 << "\n"; - * out << FieldT(56) << OUTPUT_NEWLINE; - * out << FieldT(78) << OUTPUT_NEWLINE; - * out << 9 << "\n"; - * - * Then reading back it its reader's responsibility (!) to consume "\n" - * after 4, but Fp::operator<< will correctly consume OUTPUT_NEWLINE. - * - * The reader should also consume "\n" after 9, so that another field - * element can be properly chained. This is especially important for - * binary output. - * - * The binary serialization of algebraic objects is currently *not* - * portable between machines of different word sizes. - */ - -#ifdef BINARY_OUTPUT -#define OUTPUT_NEWLINE "" -#define OUTPUT_SEPARATOR "" -#else -#define OUTPUT_NEWLINE "\n" -#define OUTPUT_SEPARATOR " " -#endif - -inline void consume_newline(std::istream &in); -inline void consume_OUTPUT_NEWLINE(std::istream &in); -inline void consume_OUTPUT_SEPARATOR(std::istream &in); - -inline void output_bool(std::ostream &out, const bool b); - -inline void output_bool_vector(std::ostream &out, const std::vector &v); - -template -T reserialize(const T &obj); - -template -std::ostream& operator<<(std::ostream& out, const std::vector &v); - -template -std::istream& operator>>(std::ostream& out, std::vector &v); - -template -std::ostream& operator<<(std::ostream& out, const std::map &m); - -template -std::istream& operator>>(std::istream& in, std::map &m); - -template -std::ostream& operator<<(std::ostream& out, const std::set &s); - -template -std::istream& operator>>(std::istream& in, std::set &s); - -} // libsnark - -#include "common/serialization.tcc" - -#endif // SERIALIZATION_HPP_ diff --git a/src/snark/libsnark/common/serialization.tcc b/src/snark/libsnark/common/serialization.tcc deleted file mode 100644 index 7983c9f25..000000000 --- a/src/snark/libsnark/common/serialization.tcc +++ /dev/null @@ -1,181 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of serialization routines. - - See serialization.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SERIALIZATION_TCC_ -#define SERIALIZATION_TCC_ - -#include -#include -#include "common/utils.hpp" -#include "common/assert_except.hpp" - -namespace libsnark { - -inline void consume_newline(std::istream &in) -{ - char c; - in.read(&c, 1); -} - -inline void consume_OUTPUT_NEWLINE(std::istream &in) -{ -#ifdef BINARY_OUTPUT - // nothing to consume - UNUSED(in); -#else - char c; - in.read(&c, 1); -#endif -} - -inline void consume_OUTPUT_SEPARATOR(std::istream &in) -{ -#ifdef BINARY_OUTPUT - // nothing to consume - UNUSED(in); -#else - char c; - in.read(&c, 1); -#endif -} - -inline void output_bool(std::ostream &out, const bool b) -{ - out << (b ? 1 : 0) << "\n"; -} - -inline void output_bool_vector(std::ostream &out, const std::vector &v) -{ - out << v.size() << "\n"; - for (const bool b : v) - { - output_bool(out, b); - } -} - -template -T reserialize(const T &obj) -{ - std::stringstream ss; - ss << obj; - T tmp; - ss >> tmp; - assert_except(obj == tmp); - return tmp; -} - -template -std::ostream& operator<<(std::ostream& out, const std::vector &v) -{ - static_assert(!std::is_same::value, "this does not work for std::vector"); - out << v.size() << "\n"; - for (const T& t : v) - { - out << t << OUTPUT_NEWLINE; - } - - return out; -} - -template -std::istream& operator>>(std::istream& in, std::vector &v) -{ - static_assert(!std::is_same::value, "this does not work for std::vector"); - size_t size; - in >> size; - consume_newline(in); - - v.resize(0); - for (size_t i = 0; i < size; ++i) - { - T elt; - in >> elt; - consume_OUTPUT_NEWLINE(in); - v.push_back(elt); - } - - return in; -} - -template -std::ostream& operator<<(std::ostream& out, const std::map &m) -{ - out << m.size() << "\n"; - - for (auto &it : m) - { - out << it.first << "\n"; - out << it.second << "\n"; - } - - return out; -} - -template -std::istream& operator>>(std::istream& in, std::map &m) -{ - m.clear(); - size_t size; - in >> size; - consume_newline(in); - - for (size_t i = 0; i < size; ++i) - { - T1 k; - T2 v; - in >> k; - consume_newline(in); - in >> v; - consume_newline(in); - m[k] = v; - } - - return in; -} - -template -std::ostream& operator<<(std::ostream& out, const std::set &s) -{ - out << s.size() << "\n"; - - for (auto &el : s) - { - out << el << "\n"; - } - - return out; -} - - -template -std::istream& operator>>(std::istream& in, std::set &s) -{ - s.clear(); - size_t size; - in >> size; - consume_newline(in); - - for (size_t i = 0; i < size; ++i) - { - T el; - in >> el; - consume_newline(in); - s.insert(el); - } - - return in; -} - -} - -#endif // SERIALIZATION_TCC_ diff --git a/src/snark/libsnark/common/template_utils.hpp b/src/snark/libsnark/common/template_utils.hpp deleted file mode 100644 index 8dbfd261d..000000000 --- a/src/snark/libsnark/common/template_utils.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of functions for supporting the use of templates. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef TEMPLATE_UTILS_HPP_ -#define TEMPLATE_UTILS_HPP_ - -namespace libsnark { - -/* A commonly used SFINAE helper type */ -template -struct void_type -{ - typedef void type; -}; - -} // libsnark - -#endif // TEMPLATE_UTILS_HPP_ diff --git a/src/snark/libsnark/common/utils.cpp b/src/snark/libsnark/common/utils.cpp deleted file mode 100644 index e2d7ab407..000000000 --- a/src/snark/libsnark/common/utils.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of misc math and serialization utility functions - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include -#include -#include -#include -#include "common/utils.hpp" - -namespace libsnark { - -size_t log2(size_t n) -/* returns ceil(log2(n)), so UINT64_C(1)< 1) - { - n >>= 1; - r++; - } - - return r; -} - -uint64_t bitreverse(uint64_t n, const uint64_t l) -{ - uint64_t r = 0; - for (uint64_t k = 0; k < l; ++k) - { - r = (r << 1) | (n & 1); - n >>= 1; - } - return r; -} - -bit_vector int_list_to_bits(const std::initializer_list &l, const size_t wordsize) -{ - bit_vector res(wordsize*l.size()); - for (uint64_t i = 0; i < l.size(); ++i) - { - for (uint64_t j = 0; j < wordsize; ++j) - { - res[i*wordsize + j] = (*(l.begin()+i) & (UINT64_C(1)<<(wordsize-1-j))); - } - } - return res; -} - -int64_t div_ceil(int64_t x, int64_t y) -{ - return (x + (y-1)) / y; -} - -bool is_little_endian() -{ - uint64_t a = 0x12345678; - unsigned char *c = (unsigned char*)(&a); - return (*c = 0x78); -} - -std::string FORMAT(const std::string &prefix, const char* format, ...) -{ - const static uint64_t MAX_FMT = 256; - char buf[MAX_FMT]; - va_list args; - va_start(args, format); - vsnprintf(buf, MAX_FMT, format, args); - va_end(args); - - return prefix + std::string(buf); -} - -void serialize_bit_vector(std::ostream &out, const bit_vector &v) -{ - out << v.size() << "\n"; - for (uint64_t i = 0; i < v.size(); ++i) - { - out << v[i] << "\n"; - } -} - -void deserialize_bit_vector(std::istream &in, bit_vector &v) -{ - uint64_t size; - in >> size; - v.resize(size); - for (uint64_t i = 0; i < size; ++i) - { - bool b; - in >> b; - v[i] = b; - } -} -} // libsnark diff --git a/src/snark/libsnark/common/utils.hpp b/src/snark/libsnark/common/utils.hpp deleted file mode 100644 index c4ce26735..000000000 --- a/src/snark/libsnark/common/utils.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - ***************************************************************************** - Declaration of misc math and serialization utility functions - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef UTILS_HPP_ -#define UTILS_HPP_ - -#include -#include -#include -#include -#include - -namespace libsnark { - -typedef std::vector bit_vector; - -/// returns ceil(log2(n)), so UINT64_C(1)< &l, const size_t wordsize); -int64_t div_ceil(int64_t x, int64_t y); - -bool is_little_endian(); - -std::string FORMAT(const std::string &prefix, const char* format, ...); - -/* A variadic template to suppress unused argument warnings */ -template -void UNUSED(Types&&...) {} - -#ifdef DEBUG -#define FMT FORMAT -#else -#define FMT(...) (UNUSED(__VA_ARGS__), "") -#endif - -void serialize_bit_vector(std::ostream &out, const bit_vector &v); -void deserialize_bit_vector(std::istream &in, bit_vector &v); - -#ifdef __APPLE__ -template -unsigned long size_in_bits(const std::vector &v); -#else -template -uint64_t size_in_bits(const std::vector &v); -#endif - -#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) - -} // libsnark - -#include "common/utils.tcc" /* note that utils has a templatized part (utils.tcc) and non-templatized part (utils.cpp) */ -#endif // UTILS_HPP_ diff --git a/src/snark/libsnark/common/utils.tcc b/src/snark/libsnark/common/utils.tcc deleted file mode 100644 index 4afdc8b3d..000000000 --- a/src/snark/libsnark/common/utils.tcc +++ /dev/null @@ -1,31 +0,0 @@ -/** @file - ***************************************************************************** - Implementation of templatized utility functions - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef UTILS_TCC_ -#define UTILS_TCC_ - -namespace libsnark { - -#ifdef __APPLE__ -template -unsigned long size_in_bits(const std::vector &v) -{ - return v.size() * T::size_in_bits(); -} -#else -template -size_t size_in_bits(const std::vector &v) -{ - return v.size() * T::size_in_bits(); -} -#endif - -} // libsnark - -#endif // UTILS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp b/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp deleted file mode 100644 index bc17e63bc..000000000 --- a/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for profiling constraints. - - See constraint_profiling.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "gadgetlib1/constraint_profiling.hpp" -#include "common/profiling.hpp" - -namespace libsnark { - -size_t constraint_profiling_indent = 0; -std::vector constraint_profiling_table; - -size_t PRINT_CONSTRAINT_PROFILING() -{ - size_t accounted = 0; - print_indent(); - printf("Constraint profiling:\n"); - for (constraint_profiling_entry &ent : constraint_profiling_table) - { - if (ent.indent == 0) - { - accounted += ent.count; - } - - print_indent(); - for (size_t i = 0; i < ent.indent; ++i) - { - printf(" "); - } - printf("* Number of constraints in [%s]: %zu\n", ent.annotation.c_str(), ent.count); - } - - constraint_profiling_table.clear(); - constraint_profiling_indent = 0; - - return accounted; -} - -} diff --git a/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp b/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp deleted file mode 100644 index df8a55de1..000000000 --- a/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for profiling constraints. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef CONSTRAINT_PROFILING_HPP_ -#define CONSTRAINT_PROFILING_HPP_ - -#include -#include -#include -#include - -namespace libsnark { - -extern size_t constraint_profiling_indent; - -struct constraint_profiling_entry { - size_t indent; - std::string annotation; - size_t count; -}; - -extern std::vector constraint_profiling_table; - -#define PROFILE_CONSTRAINTS(pb, annotation) \ - for (size_t _num_constraints_before = pb.num_constraints(), _iter = (++constraint_profiling_indent, 0), _cp_pos = constraint_profiling_table.size(); \ - _iter == 0; \ - constraint_profiling_table.insert(constraint_profiling_table.begin() + _cp_pos, constraint_profiling_entry{--constraint_profiling_indent, annotation, pb.num_constraints() - _num_constraints_before}), \ - _iter = 1) - -size_t PRINT_CONSTRAINT_PROFILING(); // returns # of top level constraints - -} // libsnark - -#endif // CONSTRAINT_PROFILING_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp b/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp deleted file mode 100644 index faa3a9605..000000000 --- a/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SIMPLE_EXAMPLE_HPP_ -#define SIMPLE_EXAMPLE_HPP_ - -#include "examples/r1cs_examples.hpp" - -namespace libsnark { - -template -r1cs_example gen_r1cs_example_from_protoboard(const size_t num_constraints, - const size_t num_inputs); - -} // libsnark - -#include "gadgetlib1/examples/simple_example.tcc" - -#endif // SIMPLE_EXAMPLE_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc b/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc deleted file mode 100644 index 9d500b5c7..000000000 --- a/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc +++ /dev/null @@ -1,54 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SIMPLE_EXAMPLE_TCC_ -#define SIMPLE_EXAMPLE_TCC_ - -#include -#include "gadgetlib1/gadgets/basic_gadgets.hpp" - -namespace libsnark { - -/* NOTE: all examples here actually generate one constraint less to account for soundness constraint in QAP */ - -template -r1cs_example gen_r1cs_example_from_protoboard(const size_t num_constraints, - const size_t num_inputs) -{ - const size_t new_num_constraints = num_constraints - 1; - - /* construct dummy example: inner products of two vectors */ - protoboard pb; - pb_variable_array A; - pb_variable_array B; - pb_variable res; - - // the variables on the protoboard are (ONE (constant 1 term), res, A[0], ..., A[num_constraints-1], B[0], ..., B[num_constraints-1]) - res.allocate(pb, "res"); - A.allocate(pb, new_num_constraints, "A"); - B.allocate(pb, new_num_constraints, "B"); - - inner_product_gadget compute_inner_product(pb, A, B, res, "compute_inner_product"); - compute_inner_product.generate_r1cs_constraints(); - - /* fill in random example */ - for (size_t i = 0; i < new_num_constraints; ++i) - { - pb.val(A[i]) = FieldT::random_element(); - pb.val(B[i]) = FieldT::random_element(); - } - - compute_inner_product.generate_r1cs_witness(); - - pb.constraint_system.num_inputs = num_inputs; - const r1cs_variable_assignment va = pb.values; - const r1cs_variable_assignment input(va.begin(), va.begin() + num_inputs); - return r1cs_example(pb.constraint_system, input, va, num_inputs); -} - -} // libsnark -#endif // R1CS_EXAMPLES_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadget.hpp b/src/snark/libsnark/gadgetlib1/gadget.hpp deleted file mode 100644 index dbeaa9d4b..000000000 --- a/src/snark/libsnark/gadgetlib1/gadget.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef GADGET_HPP_ -#define GADGET_HPP_ - -#include "gadgetlib1/protoboard.hpp" - -namespace libsnark { - -template -class gadget { -protected: - protoboard &pb; - const std::string annotation_prefix; -public: - gadget(protoboard &pb, const std::string &annotation_prefix=""); -}; - -} // libsnark -#include "gadgetlib1/gadget.tcc" - -#endif // GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadget.tcc b/src/snark/libsnark/gadgetlib1/gadget.tcc deleted file mode 100644 index 120229bbe..000000000 --- a/src/snark/libsnark/gadgetlib1/gadget.tcc +++ /dev/null @@ -1,23 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef GADGET_TCC_ -#define GADGET_TCC_ - -namespace libsnark { - -template -gadget::gadget(protoboard &pb, const std::string &annotation_prefix) : - pb(pb), annotation_prefix(annotation_prefix) -{ -#ifdef DEBUG - assert(annotation_prefix != ""); -#endif -} - -} // libsnark -#endif // GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp deleted file mode 100644 index 08e596bee..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp +++ /dev/null @@ -1,351 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_GADGETS_HPP_ -#define BASIC_GADGETS_HPP_ - -#include -#include - -#include "gadgetlib1/gadget.hpp" - -namespace libsnark { - -/* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ -template -void generate_boolean_r1cs_constraint(protoboard &pb, const pb_linear_combination &lc, const std::string &annotation_prefix=""); - -template -void generate_r1cs_equals_const_constraint(protoboard &pb, const pb_linear_combination &lc, const FieldT& c, const std::string &annotation_prefix=""); - -template -class packing_gadget : public gadget { -private: - /* no internal variables */ -public: - const pb_linear_combination_array bits; - const pb_linear_combination packed; - - packing_gadget(protoboard &pb, - const pb_linear_combination_array &bits, - const pb_linear_combination &packed, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), bits(bits), packed(packed) {} - - void generate_r1cs_constraints(const bool enforce_bitness); - /* adds constraint result = \sum bits[i] * 2^i */ - - void generate_r1cs_witness_from_packed(); - void generate_r1cs_witness_from_bits(); -}; - -template -class multipacking_gadget : public gadget { -private: - std::vector > packers; -public: - const pb_linear_combination_array bits; - const pb_linear_combination_array packed_vars; - - const size_t chunk_size; - const size_t num_chunks; - // const size_t last_chunk_size; - - multipacking_gadget(protoboard &pb, - const pb_linear_combination_array &bits, - const pb_linear_combination_array &packed_vars, - const size_t chunk_size, - const std::string &annotation_prefix=""); - void generate_r1cs_constraints(const bool enforce_bitness); - void generate_r1cs_witness_from_packed(); - void generate_r1cs_witness_from_bits(); -}; - -template -class field_vector_copy_gadget : public gadget { -public: - const pb_variable_array source; - const pb_variable_array target; - const pb_linear_combination do_copy; - - field_vector_copy_gadget(protoboard &pb, - const pb_variable_array &source, - const pb_variable_array &target, - const pb_linear_combination &do_copy, - const std::string &annotation_prefix=""); - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -class bit_vector_copy_gadget : public gadget { -public: - const pb_variable_array source_bits; - const pb_variable_array target_bits; - const pb_linear_combination do_copy; - - pb_variable_array packed_source; - pb_variable_array packed_target; - - std::shared_ptr > pack_source; - std::shared_ptr > pack_target; - std::shared_ptr > copier; - - const size_t chunk_size; - const size_t num_chunks; - - bit_vector_copy_gadget(protoboard &pb, - const pb_variable_array &source_bits, - const pb_variable_array &target_bits, - const pb_linear_combination &do_copy, - const size_t chunk_size, - const std::string &annotation_prefix=""); - void generate_r1cs_constraints(const bool enforce_source_bitness, const bool enforce_target_bitness); - void generate_r1cs_witness(); -}; - -template -class dual_variable_gadget : public gadget { -private: - std::shared_ptr > consistency_check; -public: - pb_variable packed; - pb_variable_array bits; - - dual_variable_gadget(protoboard &pb, - const size_t width, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix) - { - packed.allocate(pb, FMT(this->annotation_prefix, " packed")); - bits.allocate(pb, width, FMT(this->annotation_prefix, " bits")); - consistency_check.reset(new packing_gadget(pb, - bits, - packed, - FMT(this->annotation_prefix, " consistency_check"))); - } - - dual_variable_gadget(protoboard &pb, - const pb_variable_array &bits, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), bits(bits) - { - packed.allocate(pb, FMT(this->annotation_prefix, " packed")); - consistency_check.reset(new packing_gadget(pb, - bits, - packed, - FMT(this->annotation_prefix, " consistency_check"))); - } - - dual_variable_gadget(protoboard &pb, - const pb_variable &packed, - const size_t width, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), packed(packed) - { - bits.allocate(pb, width, FMT(this->annotation_prefix, " bits")); - consistency_check.reset(new packing_gadget(pb, - bits, - packed, - FMT(this->annotation_prefix, " consistency_check"))); - } - - void generate_r1cs_constraints(const bool enforce_bitness); - void generate_r1cs_witness_from_packed(); - void generate_r1cs_witness_from_bits(); -}; - -/* - the gadgets below are Fp specific: - I * X = R - (1-R) * X = 0 - - if X = 0 then R = 0 - if X != 0 then R = 1 and I = X^{-1} -*/ - -template -class disjunction_gadget : public gadget { -private: - pb_variable inv; -public: - const pb_variable_array inputs; - const pb_variable output; - - disjunction_gadget(protoboard& pb, - const pb_variable_array &inputs, - const pb_variable &output, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), inputs(inputs), output(output) - { - assert(inputs.size() >= 1); - inv.allocate(pb, FMT(this->annotation_prefix, " inv")); - } - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -void test_disjunction_gadget(const size_t n); - -template -class conjunction_gadget : public gadget { -private: - pb_variable inv; -public: - const pb_variable_array inputs; - const pb_variable output; - - conjunction_gadget(protoboard& pb, - const pb_variable_array &inputs, - const pb_variable &output, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), inputs(inputs), output(output) - { - assert(inputs.size() >= 1); - inv.allocate(pb, FMT(this->annotation_prefix, " inv")); - } - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -void test_conjunction_gadget(const size_t n); - -template -class comparison_gadget : public gadget { -private: - pb_variable_array alpha; - pb_variable alpha_packed; - std::shared_ptr > pack_alpha; - - std::shared_ptr > all_zeros_test; - pb_variable not_all_zeros; -public: - const size_t n; - const pb_linear_combination A; - const pb_linear_combination B; - const pb_variable less; - const pb_variable less_or_eq; - - comparison_gadget(protoboard& pb, - const size_t n, - const pb_linear_combination &A, - const pb_linear_combination &B, - const pb_variable &less, - const pb_variable &less_or_eq, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), n(n), A(A), B(B), less(less), less_or_eq(less_or_eq) - { - alpha.allocate(pb, n, FMT(this->annotation_prefix, " alpha")); - alpha.emplace_back(less_or_eq); // alpha[n] is less_or_eq - - alpha_packed.allocate(pb, FMT(this->annotation_prefix, " alpha_packed")); - not_all_zeros.allocate(pb, FMT(this->annotation_prefix, " not_all_zeros")); - - pack_alpha.reset(new packing_gadget(pb, alpha, alpha_packed, - FMT(this->annotation_prefix, " pack_alpha"))); - - all_zeros_test.reset(new disjunction_gadget(pb, - pb_variable_array(alpha.begin(), alpha.begin() + n), - not_all_zeros, - FMT(this->annotation_prefix, " all_zeros_test"))); - }; - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -void test_comparison_gadget(const size_t n); - -template -class inner_product_gadget : public gadget { -private: - /* S_i = \sum_{k=0}^{i+1} A[i] * B[i] */ - pb_variable_array S; -public: - const pb_linear_combination_array A; - const pb_linear_combination_array B; - const pb_variable result; - - inner_product_gadget(protoboard& pb, - const pb_linear_combination_array &A, - const pb_linear_combination_array &B, - const pb_variable &result, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), A(A), B(B), result(result) - { - assert(A.size() >= 1); - assert(A.size() == B.size()); - - S.allocate(pb, A.size()-1, FMT(this->annotation_prefix, " S")); - } - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -void test_inner_product_gadget(const size_t n); - -template -class loose_multiplexing_gadget : public gadget { -/* - this implements loose multiplexer: - index not in bounds -> success_flag = 0 - index in bounds && success_flag = 1 -> result is correct - however if index is in bounds we can also set success_flag to 0 (and then result will be forced to be 0) -*/ -public: - pb_variable_array alpha; -private: - std::shared_ptr > compute_result; -public: - const pb_linear_combination_array arr; - const pb_variable index; - const pb_variable result; - const pb_variable success_flag; - - loose_multiplexing_gadget(protoboard& pb, - const pb_linear_combination_array &arr, - const pb_variable &index, - const pb_variable &result, - const pb_variable &success_flag, - const std::string &annotation_prefix="") : - gadget(pb, annotation_prefix), arr(arr), index(index), result(result), success_flag(success_flag) - { - alpha.allocate(pb, arr.size(), FMT(this->annotation_prefix, " alpha")); - compute_result.reset(new inner_product_gadget(pb, alpha, arr, result, FMT(this->annotation_prefix, " compute_result"))); - }; - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -void test_loose_multiplexing_gadget(const size_t n); - -template -void create_linear_combination_constraints(protoboard &pb, - const std::vector &base, - const std::vector > &v, - const VarT &target, - const std::string &annotation_prefix); - -template -void create_linear_combination_witness(protoboard &pb, - const std::vector &base, - const std::vector > &v, - const VarT &target); - -} // libsnark -#include "gadgetlib1/gadgets/basic_gadgets.tcc" - -#endif // BASIC_GADGETS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc deleted file mode 100644 index 4e2d9fce3..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc +++ /dev/null @@ -1,705 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef BASIC_GADGETS_TCC_ -#define BASIC_GADGETS_TCC_ - -#include "common/profiling.hpp" -#include "common/utils.hpp" - -namespace libsnark { - -template -void generate_boolean_r1cs_constraint(protoboard &pb, const pb_linear_combination &lc, const std::string &annotation_prefix) -/* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ -{ - pb.add_r1cs_constraint(r1cs_constraint(lc, 1-lc, 0), - FMT(annotation_prefix, " boolean_r1cs_constraint")); -} - -template -void generate_r1cs_equals_const_constraint(protoboard &pb, const pb_linear_combination &lc, const FieldT& c, const std::string &annotation_prefix) -{ - pb.add_r1cs_constraint(r1cs_constraint(1, lc, c), - FMT(annotation_prefix, " constness_constraint")); -} - -template -void packing_gadget::generate_r1cs_constraints(const bool enforce_bitness) -/* adds constraint result = \sum bits[i] * 2^i */ -{ - this->pb.add_r1cs_constraint(r1cs_constraint(1, pb_packing_sum(bits), packed), FMT(this->annotation_prefix, " packing_constraint")); - - if (enforce_bitness) - { - for (size_t i = 0; i < bits.size(); ++i) - { - generate_boolean_r1cs_constraint(this->pb, bits[i], FMT(this->annotation_prefix, " bitness_%zu", i)); - } - } -} - -template -void packing_gadget::generate_r1cs_witness_from_packed() -{ - packed.evaluate(this->pb); - assert(this->pb.lc_val(packed).as_bigint().num_bits() <= bits.size()); - bits.fill_with_bits_of_field_element(this->pb, this->pb.lc_val(packed)); -} - -template -void packing_gadget::generate_r1cs_witness_from_bits() -{ - bits.evaluate(this->pb); - this->pb.lc_val(packed) = bits.get_field_element_from_bits(this->pb); -} - -template -multipacking_gadget::multipacking_gadget(protoboard &pb, - const pb_linear_combination_array &bits, - const pb_linear_combination_array &packed_vars, - const size_t chunk_size, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), bits(bits), packed_vars(packed_vars), - chunk_size(chunk_size), - num_chunks(div_ceil(bits.size(), chunk_size)) - // last_chunk_size(bits.size() - (num_chunks-1) * chunk_size) -{ - assert(packed_vars.size() == num_chunks); - for (size_t i = 0; i < num_chunks; ++i) - { - packers.emplace_back(packing_gadget(this->pb, pb_linear_combination_array(bits.begin() + i * chunk_size, - bits.begin() + std::min((i+1) * chunk_size, bits.size())), - packed_vars[i], FMT(this->annotation_prefix, " packers_%zu", i))); - } -} - -template -void multipacking_gadget::generate_r1cs_constraints(const bool enforce_bitness) -{ - for (size_t i = 0; i < num_chunks; ++i) - { - packers[i].generate_r1cs_constraints(enforce_bitness); - } -} - -template -void multipacking_gadget::generate_r1cs_witness_from_packed() -{ - for (size_t i = 0; i < num_chunks; ++i) - { - packers[i].generate_r1cs_witness_from_packed(); - } -} - -template -void multipacking_gadget::generate_r1cs_witness_from_bits() -{ - for (size_t i = 0; i < num_chunks; ++i) - { - packers[i].generate_r1cs_witness_from_bits(); - } -} - -template -size_t multipacking_num_chunks(const size_t num_bits) -{ - return div_ceil(num_bits, FieldT::capacity()); -} - -template -field_vector_copy_gadget::field_vector_copy_gadget(protoboard &pb, - const pb_variable_array &source, - const pb_variable_array &target, - const pb_linear_combination &do_copy, - const std::string &annotation_prefix) : -gadget(pb, annotation_prefix), source(source), target(target), do_copy(do_copy) -{ - assert(source.size() == target.size()); -} - -template -void field_vector_copy_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < source.size(); ++i) - { - this->pb.add_r1cs_constraint(r1cs_constraint(do_copy, source[i] - target[i], 0), - FMT(this->annotation_prefix, " copying_check_%zu", i)); - } -} - -template -void field_vector_copy_gadget::generate_r1cs_witness() -{ - do_copy.evaluate(this->pb); - assert(this->pb.lc_val(do_copy) == FieldT::one() || this->pb.lc_val(do_copy) == FieldT::zero()); - if (this->pb.lc_val(do_copy) != FieldT::zero()) - { - for (size_t i = 0; i < source.size(); ++i) - { - this->pb.val(target[i]) = this->pb.val(source[i]); - } - } -} - -template -bit_vector_copy_gadget::bit_vector_copy_gadget(protoboard &pb, - const pb_variable_array &source_bits, - const pb_variable_array &target_bits, - const pb_linear_combination &do_copy, - const size_t chunk_size, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), source_bits(source_bits), target_bits(target_bits), do_copy(do_copy), - chunk_size(chunk_size), num_chunks(div_ceil(source_bits.size(), chunk_size)) -{ - assert(source_bits.size() == target_bits.size()); - - packed_source.allocate(pb, num_chunks, FMT(annotation_prefix, " packed_source")); - pack_source.reset(new multipacking_gadget(pb, source_bits, packed_source, chunk_size, FMT(annotation_prefix, " pack_source"))); - - packed_target.allocate(pb, num_chunks, FMT(annotation_prefix, " packed_target")); - pack_target.reset(new multipacking_gadget(pb, target_bits, packed_target, chunk_size, FMT(annotation_prefix, " pack_target"))); - - copier.reset(new field_vector_copy_gadget(pb, packed_source, packed_target, do_copy, FMT(annotation_prefix, " copier"))); -} - -template -void bit_vector_copy_gadget::generate_r1cs_constraints(const bool enforce_source_bitness, const bool enforce_target_bitness) -{ - pack_source->generate_r1cs_constraints(enforce_source_bitness); - pack_target->generate_r1cs_constraints(enforce_target_bitness); - - copier->generate_r1cs_constraints(); -} - -template -void bit_vector_copy_gadget::generate_r1cs_witness() -{ - do_copy.evaluate(this->pb); - assert(this->pb.lc_val(do_copy) == FieldT::zero() || this->pb.lc_val(do_copy) == FieldT::one()); - if (this->pb.lc_val(do_copy) == FieldT::one()) - { - for (size_t i = 0; i < source_bits.size(); ++i) - { - this->pb.val(target_bits[i]) = this->pb.val(source_bits[i]); - } - } - - pack_source->generate_r1cs_witness_from_bits(); - pack_target->generate_r1cs_witness_from_bits(); -} - -template -void dual_variable_gadget::generate_r1cs_constraints(const bool enforce_bitness) -{ - consistency_check->generate_r1cs_constraints(enforce_bitness); -} - -template -void dual_variable_gadget::generate_r1cs_witness_from_packed() -{ - consistency_check->generate_r1cs_witness_from_packed(); -} - -template -void dual_variable_gadget::generate_r1cs_witness_from_bits() -{ - consistency_check->generate_r1cs_witness_from_bits(); -} - -template -void disjunction_gadget::generate_r1cs_constraints() -{ - /* inv * sum = output */ - linear_combination a1, b1, c1; - a1.add_term(inv); - for (size_t i = 0; i < inputs.size(); ++i) - { - b1.add_term(inputs[i]); - } - c1.add_term(output); - - this->pb.add_r1cs_constraint(r1cs_constraint(a1, b1, c1), FMT(this->annotation_prefix, " inv*sum=output")); - - /* (1-output) * sum = 0 */ - linear_combination a2, b2, c2; - a2.add_term(ONE); - a2.add_term(output, -1); - for (size_t i = 0; i < inputs.size(); ++i) - { - b2.add_term(inputs[i]); - } - c2.add_term(ONE, 0); - - this->pb.add_r1cs_constraint(r1cs_constraint(a2, b2, c2), FMT(this->annotation_prefix, " (1-output)*sum=0")); -} - -template -void disjunction_gadget::generate_r1cs_witness() -{ - FieldT sum = FieldT::zero(); - - for (size_t i = 0; i < inputs.size(); ++i) - { - sum += this->pb.val(inputs[i]); - } - - if (sum.is_zero()) - { - this->pb.val(inv) = FieldT::zero(); - this->pb.val(output) = FieldT::zero(); - } - else - { - this->pb.val(inv) = sum.inverse(); - this->pb.val(output) = FieldT::one(); - } -} - -template -void test_disjunction_gadget(const size_t n) -{ - printf("testing disjunction_gadget on all %zu bit strings\n", n); - - protoboard pb; - pb_variable_array inputs; - inputs.allocate(pb, n, "inputs"); - - pb_variable output; - output.allocate(pb, "output"); - - disjunction_gadget d(pb, inputs, output, "d"); - d.generate_r1cs_constraints(); - - for (size_t w = 0; w < UINT64_C(1)< -void conjunction_gadget::generate_r1cs_constraints() -{ - /* inv * (n-sum) = 1-output */ - linear_combination a1, b1, c1; - a1.add_term(inv); - b1.add_term(ONE, inputs.size()); - for (size_t i = 0; i < inputs.size(); ++i) - { - b1.add_term(inputs[i], -1); - } - c1.add_term(ONE); - c1.add_term(output, -1); - - this->pb.add_r1cs_constraint(r1cs_constraint(a1, b1, c1), FMT(this->annotation_prefix, " inv*(n-sum)=(1-output)")); - - /* output * (n-sum) = 0 */ - linear_combination a2, b2, c2; - a2.add_term(output); - b2.add_term(ONE, inputs.size()); - for (size_t i = 0; i < inputs.size(); ++i) - { - b2.add_term(inputs[i], -1); - } - c2.add_term(ONE, 0); - - this->pb.add_r1cs_constraint(r1cs_constraint(a2, b2, c2), FMT(this->annotation_prefix, " output*(n-sum)=0")); -} - -template -void conjunction_gadget::generate_r1cs_witness() -{ - FieldT sum = FieldT(inputs.size()); - - for (size_t i = 0; i < inputs.size(); ++i) - { - sum -= this->pb.val(inputs[i]); - } - - if (sum.is_zero()) - { - this->pb.val(inv) = FieldT::zero(); - this->pb.val(output) = FieldT::one(); - } - else - { - this->pb.val(inv) = sum.inverse(); - this->pb.val(output) = FieldT::zero(); - } -} - -template -void test_conjunction_gadget(const size_t n) -{ - printf("testing conjunction_gadget on all %zu bit strings\n", n); - - protoboard pb; - pb_variable_array inputs; - inputs.allocate(pb, n, "inputs"); - - pb_variable output; - output.allocate(pb, "output"); - - conjunction_gadget c(pb, inputs, output, "c"); - c.generate_r1cs_constraints(); - - for (size_t w = 0; w < UINT64_C(1)< -void comparison_gadget::generate_r1cs_constraints() -{ - /* - packed(alpha) = 2^n + B - A - - not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i - - if B - A > 0, then 2^n + B - A > 2^n, - so alpha_n = 1 and not_all_zeros = 1 - if B - A = 0, then 2^n + B - A = 2^n, - so alpha_n = 1 and not_all_zeros = 0 - if B - A < 0, then 2^n + B - A \in {0, 1, \ldots, 2^n-1}, - so alpha_n = 0 - - therefore alpha_n = less_or_eq and alpha_n * not_all_zeros = less - */ - - /* not_all_zeros to be Boolean, alpha_i are Boolean by packing gadget */ - generate_boolean_r1cs_constraint(this->pb, not_all_zeros, - FMT(this->annotation_prefix, " not_all_zeros")); - - /* constraints for packed(alpha) = 2^n + B - A */ - pack_alpha->generate_r1cs_constraints(true); - this->pb.add_r1cs_constraint(r1cs_constraint(1, (FieldT(2)^n) + B - A, alpha_packed), FMT(this->annotation_prefix, " main_constraint")); - - /* compute result */ - all_zeros_test->generate_r1cs_constraints(); - this->pb.add_r1cs_constraint(r1cs_constraint(less_or_eq, not_all_zeros, less), - FMT(this->annotation_prefix, " less")); -} - -template -void comparison_gadget::generate_r1cs_witness() -{ - A.evaluate(this->pb); - B.evaluate(this->pb); - - /* unpack 2^n + B - A into alpha_packed */ - this->pb.val(alpha_packed) = (FieldT(2)^n) + this->pb.lc_val(B) - this->pb.lc_val(A); - pack_alpha->generate_r1cs_witness_from_packed(); - - /* compute result */ - all_zeros_test->generate_r1cs_witness(); - this->pb.val(less) = this->pb.val(less_or_eq) * this->pb.val(not_all_zeros); -} - -template -void test_comparison_gadget(const size_t n) -{ - printf("testing comparison_gadget on all %zu bit inputs\n", n); - - protoboard pb; - - pb_variable A, B, less, less_or_eq; - A.allocate(pb, "A"); - B.allocate(pb, "B"); - less.allocate(pb, "less"); - less_or_eq.allocate(pb, "less_or_eq"); - - comparison_gadget cmp(pb, n, A, B, less, less_or_eq, "cmp"); - cmp.generate_r1cs_constraints(); - - for (size_t a = 0; a < UINT64_C(1)< -void inner_product_gadget::generate_r1cs_constraints() -{ - /* - S_i = \sum_{k=0}^{i+1} A[i] * B[i] - S[0] = A[0] * B[0] - S[i+1] - S[i] = A[i] * B[i] - */ - for (size_t i = 0; i < A.size(); ++i) - { - this->pb.add_r1cs_constraint( - r1cs_constraint(A[i], B[i], - (i == A.size()-1 ? result : S[i]) + (i == 0 ? 0 * ONE : -S[i-1])), - FMT(this->annotation_prefix, " S_%zu", i)); - } -} - -template -void inner_product_gadget::generate_r1cs_witness() -{ - FieldT total = FieldT::zero(); - for (size_t i = 0; i < A.size(); ++i) - { - A[i].evaluate(this->pb); - B[i].evaluate(this->pb); - - total += this->pb.lc_val(A[i]) * this->pb.lc_val(B[i]); - this->pb.val(i == A.size()-1 ? result : S[i]) = total; - } -} - -template -void test_inner_product_gadget(const size_t n) -{ - printf("testing inner_product_gadget on all %zu bit strings\n", n); - - protoboard pb; - pb_variable_array A; - A.allocate(pb, n, "A"); - pb_variable_array B; - B.allocate(pb, n, "B"); - - pb_variable result; - result.allocate(pb, "result"); - - inner_product_gadget g(pb, A, B, result, "g"); - g.generate_r1cs_constraints(); - - for (size_t i = 0; i < UINT64_C(1)< -void loose_multiplexing_gadget::generate_r1cs_constraints() -{ - /* \alpha_i (index - i) = 0 */ - for (size_t i = 0; i < arr.size(); ++i) - { - this->pb.add_r1cs_constraint( - r1cs_constraint(alpha[i], index - i, 0), - FMT(this->annotation_prefix, " alpha_%zu", i)); - } - - /* 1 * (\sum \alpha_i) = success_flag */ - linear_combination a, b, c; - a.add_term(ONE); - for (size_t i = 0; i < arr.size(); ++i) - { - b.add_term(alpha[i]); - } - c.add_term(success_flag); - this->pb.add_r1cs_constraint(r1cs_constraint(a, b, c), FMT(this->annotation_prefix, " main_constraint")); - - /* now success_flag is constrained to either 0 (if index is out of - range) or \alpha_i. constrain it and \alpha_i to zero */ - generate_boolean_r1cs_constraint(this->pb, success_flag, FMT(this->annotation_prefix, " success_flag")); - - /* compute result */ - compute_result->generate_r1cs_constraints(); -} - -template -void loose_multiplexing_gadget::generate_r1cs_witness() -{ - /* assumes that idx can be fit in uint64_t; true for our purposes for now */ - const bigint valint = this->pb.val(index).as_bigint(); - uint64_t idx = valint.as_uint64(); - const bigint arrsize(arr.size()); - - if (idx >= arr.size() || mpn_cmp(valint.data, arrsize.data, FieldT::num_limbs) >= 0) - { - for (size_t i = 0; i < arr.size(); ++i) - { - this->pb.val(alpha[i]) = FieldT::zero(); - } - - this->pb.val(success_flag) = FieldT::zero(); - } - else - { - for (size_t i = 0; i < arr.size(); ++i) - { - this->pb.val(alpha[i]) = (i == idx ? FieldT::one() : FieldT::zero()); - } - - this->pb.val(success_flag) = FieldT::one(); - } - - compute_result->generate_r1cs_witness(); -} - -template -void test_loose_multiplexing_gadget(const size_t n) -{ - printf("testing loose_multiplexing_gadget on 2**%zu pb_variable array inputs\n", n); - protoboard pb; - - pb_variable_array arr; - arr.allocate(pb, UINT64_C(1)< index, result, success_flag; - index.allocate(pb, "index"); - result.allocate(pb, "result"); - success_flag.allocate(pb, "success_flag"); - - loose_multiplexing_gadget g(pb, arr, index, result, success_flag, "g"); - g.generate_r1cs_constraints(); - - for (size_t i = 0; i < UINT64_C(1)< -void create_linear_combination_constraints(protoboard &pb, - const std::vector &base, - const std::vector > &v, - const VarT &target, - const std::string &annotation_prefix) -{ - for (size_t i = 0; i < base.size(); ++i) - { - linear_combination a, b, c; - - a.add_term(ONE); - b.add_term(ONE, base[i]); - - for (auto &p : v) - { - b.add_term(p.first.all_vars[i], p.second); - } - - c.add_term(target.all_vars[i]); - - pb.add_r1cs_constraint(r1cs_constraint(a, b, c), FMT(annotation_prefix, " linear_combination_%zu", i)); - } -} - -template -void create_linear_combination_witness(protoboard &pb, - const std::vector &base, - const std::vector > &v, - const VarT &target) -{ - for (size_t i = 0; i < base.size(); ++i) - { - pb.val(target.all_vars[i]) = base[i]; - - for (auto &p : v) - { - pb.val(target.all_vars[i]) += p.second * pb.val(p.first.all_vars[i]); - } - } -} - -} // libsnark -#endif // BASIC_GADGETS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp deleted file mode 100644 index e4b8a2acf..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a gadget that can be created from an R1CS constraint system. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef GADGET_FROM_R1CS_HPP_ -#define GADGET_FROM_R1CS_HPP_ - -#include - -#include "gadgetlib1/gadget.hpp" - -namespace libsnark { - -template -class gadget_from_r1cs : public gadget { - -private: - const std::vector > vars; - const r1cs_constraint_system cs; - std::map cs_to_vars; - -public: - - gadget_from_r1cs(protoboard &pb, - const std::vector > &vars, - const r1cs_constraint_system &cs, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input); -}; - -} // libsnark - -#include "gadgetlib1/gadgets/gadget_from_r1cs.tcc" - -#endif // GADGET_FROM_R1CS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc deleted file mode 100644 index bc59b4587..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc +++ /dev/null @@ -1,123 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for a gadget that can be created from an R1CS constraint system. - - See gadget_from_r1cs.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef GADGET_FROM_R1CS_TCC_ -#define GADGET_FROM_R1CS_TCC_ - -namespace libsnark { - -template -gadget_from_r1cs::gadget_from_r1cs(protoboard &pb, - const std::vector > &vars, - const r1cs_constraint_system &cs, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - vars(vars), - cs(cs) -{ - cs_to_vars[0] = 0; /* constant term maps to constant term */ - - size_t cs_var_idx = 1; - for (auto va : vars) - { -#ifdef DEBUG - printf("gadget_from_r1cs: translating a block of variables with length %zu\n", va.size()); -#endif - for (auto v : va) - { - cs_to_vars[cs_var_idx] = v.index; - -#ifdef DEBUG - if (v.index != 0) - { - // handle annotations, except for re-annotating constant term - const std::map::const_iterator it = cs.variable_annotations.find(cs_var_idx); - - std::string annotation = FMT(annotation_prefix, " variable_%zu", cs_var_idx); - if (it != cs.variable_annotations.end()) - { - annotation = annotation_prefix + " " + it->second; - } - - pb.augment_variable_annotation(v, annotation); - } -#endif - ++cs_var_idx; - } - } - -#ifdef DEBUG - printf("gadget_from_r1cs: sum of all block lengths: %zu\n", cs_var_idx-1); - printf("gadget_from_r1cs: cs.num_variables(): %zu\n", cs.num_variables()); -#endif - - assert(cs_var_idx - 1 == cs.num_variables()); -} - -template -void gadget_from_r1cs::generate_r1cs_constraints() -{ - for (size_t i = 0; i < cs.num_constraints(); ++i) - { - const r1cs_constraint &constr = cs.constraints[i]; - r1cs_constraint translated_constr; - - for (const linear_term &t: constr.a.terms) - { - translated_constr.a.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); - } - - for (const linear_term &t: constr.b.terms) - { - translated_constr.b.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); - } - - for (const linear_term &t: constr.c.terms) - { - translated_constr.c.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); - } - - std::string annotation = FMT(this->annotation_prefix, " constraint_%zu", i); - -#ifdef DEBUG - auto it = cs.constraint_annotations.find(i); - if (it != cs.constraint_annotations.end()) - { - annotation = this->annotation_prefix + " " + it->second; - } -#endif - this->pb.add_r1cs_constraint(translated_constr, annotation); - } -} - -template -void gadget_from_r1cs::generate_r1cs_witness(const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input) -{ - assert(cs.num_inputs() == primary_input.size()); - assert(cs.num_variables() == primary_input.size() + auxiliary_input.size()); - - for (size_t i = 0; i < primary_input.size(); ++i) - { - this->pb.val(pb_variable(cs_to_vars[i+1])) = primary_input[i]; - } - - for (size_t i = 0; i < auxiliary_input.size(); ++i) - { - this->pb.val(pb_variable(cs_to_vars[primary_input.size()+i+1])) = auxiliary_input[i]; - } -} - -} // libsnark - -#endif // GADGET_FROM_R1CS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp deleted file mode 100644 index a7598b9be..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#ifndef DIGEST_SELECTOR_GADGET_HPP_ -#define DIGEST_SELECTOR_GADGET_HPP_ - -#include - -#include "gadgetlib1/gadgets/basic_gadgets.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" - -namespace libsnark { - -template -class digest_selector_gadget : public gadget { -public: - size_t digest_size; - digest_variable input; - pb_linear_combination is_right; - digest_variable left; - digest_variable right; - - digest_selector_gadget(protoboard &pb, - const size_t digest_size, - const digest_variable &input, - const pb_linear_combination &is_right, - const digest_variable &left, - const digest_variable &right, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -} // libsnark - -#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc" - -#endif // DIGEST_SELECTOR_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc deleted file mode 100644 index 422ee170a..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc +++ /dev/null @@ -1,62 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#ifndef DIGEST_SELECTOR_GADGET_TCC_ -#define DIGEST_SELECTOR_GADGET_TCC_ - -namespace libsnark { - -template -digest_selector_gadget::digest_selector_gadget(protoboard &pb, - const size_t digest_size, - const digest_variable &input, - const pb_linear_combination &is_right, - const digest_variable &left, - const digest_variable &right, - const std::string &annotation_prefix) : -gadget(pb, annotation_prefix), digest_size(digest_size), input(input), is_right(is_right), left(left), right(right) -{ -} - -template -void digest_selector_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < digest_size; ++i) - { - /* - input = is_right * right + (1-is_right) * left - input - left = is_right(right - left) - */ - this->pb.add_r1cs_constraint(r1cs_constraint(is_right, right.bits[i] - left.bits[i], input.bits[i] - left.bits[i]), - FMT(this->annotation_prefix, " propagate_%zu", i)); - } -} - -template -void digest_selector_gadget::generate_r1cs_witness() -{ - is_right.evaluate(this->pb); - - assert(this->pb.lc_val(is_right) == FieldT::one() || this->pb.lc_val(is_right) == FieldT::zero()); - if (this->pb.lc_val(is_right) == FieldT::one()) - { - for (size_t i = 0; i < digest_size; ++i) - { - this->pb.val(right.bits[i]) = this->pb.val(input.bits[i]); - } - } - else - { - for (size_t i = 0; i < digest_size; ++i) - { - this->pb.val(left.bits[i]) = this->pb.val(input.bits[i]); - } - } -} - -} // libsnark - -#endif // DIGEST_SELECTOR_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp deleted file mode 100644 index 80ca19c61..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#ifndef HASH_IO_HPP_ -#define HASH_IO_HPP_ -#include -#include -#include "gadgetlib1/gadgets/basic_gadgets.hpp" - -namespace libsnark { - -template -class digest_variable : public gadget { -public: - size_t digest_size; - pb_variable_array bits; - - digest_variable(protoboard &pb, - const size_t digest_size, - const std::string &annotation_prefix); - - digest_variable(protoboard &pb, - const size_t digest_size, - const pb_variable_array &partial_bits, - const pb_variable &padding, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(const bit_vector& contents); - bit_vector get_digest() const; -}; - -template -class block_variable : public gadget { -public: - size_t block_size; - pb_variable_array bits; - - block_variable(protoboard &pb, - const size_t block_size, - const std::string &annotation_prefix); - - block_variable(protoboard &pb, - const std::vector > &parts, - const std::string &annotation_prefix); - - block_variable(protoboard &pb, - const digest_variable &left, - const digest_variable &right, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(const bit_vector& contents); - bit_vector get_block() const; -}; - -} // libsnark -#include "gadgetlib1/gadgets/hashes/hash_io.tcc" - -#endif // HASH_IO_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc deleted file mode 100644 index b122d8f98..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc +++ /dev/null @@ -1,105 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#ifndef HASH_IO_TCC_ -#define HASH_IO_TCC_ - -namespace libsnark { - -template -digest_variable::digest_variable(protoboard &pb, - const size_t digest_size, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), digest_size(digest_size) -{ - bits.allocate(pb, digest_size, FMT(this->annotation_prefix, " bits")); -} - -template -digest_variable::digest_variable(protoboard &pb, - const size_t digest_size, - const pb_variable_array &partial_bits, - const pb_variable &padding, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), digest_size(digest_size) -{ - assert(bits.size() <= digest_size); - bits = partial_bits; - while (bits.size() != digest_size) - { - bits.emplace_back(padding); - } -} - -template -void digest_variable::generate_r1cs_constraints() -{ - for (size_t i = 0; i < digest_size; ++i) - { - generate_boolean_r1cs_constraint(this->pb, bits[i], FMT(this->annotation_prefix, " bits_%zu", i)); - } -} - -template -void digest_variable::generate_r1cs_witness(const bit_vector& contents) -{ - bits.fill_with_bits(this->pb, contents); -} - -template -bit_vector digest_variable::get_digest() const -{ - return bits.get_bits(this->pb); -} - -template -block_variable::block_variable(protoboard &pb, - const size_t block_size, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), block_size(block_size) -{ - bits.allocate(pb, block_size, FMT(this->annotation_prefix, " bits")); -} - -template -block_variable::block_variable(protoboard &pb, - const std::vector > &parts, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix) -{ - for (auto &part : parts) - { - bits.insert(bits.end(), part.begin(), part.end()); - } -} - -template -block_variable::block_variable(protoboard &pb, - const digest_variable &left, - const digest_variable &right, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix) -{ - assert(left.bits.size() == right.bits.size()); - block_size = 2 * left.bits.size(); - bits.insert(bits.end(), left.bits.begin(), left.bits.end()); - bits.insert(bits.end(), right.bits.begin(), right.bits.end()); -} - -template -void block_variable::generate_r1cs_witness(const bit_vector& contents) -{ - bits.fill_with_bits(this->pb, contents); -} - -template -bit_vector block_variable::get_block() const -{ - return bits.get_bits(this->pb); -} - -} // libsnark -#endif // HASH_IO_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp deleted file mode 100644 index e0c7a7e0b..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp +++ /dev/null @@ -1,160 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for auxiliary gadgets for the SHA256 gadget. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_AUX_HPP_ -#define SHA256_AUX_HPP_ - -#include "gadgetlib1/gadgets/basic_gadgets.hpp" - -namespace libsnark { - -template -class lastbits_gadget : public gadget { -public: - pb_variable X; - size_t X_bits; - pb_variable result; - pb_linear_combination_array result_bits; - - pb_linear_combination_array full_bits; - std::shared_ptr > unpack_bits; - std::shared_ptr > pack_result; - - lastbits_gadget(protoboard &pb, - const pb_variable &X, - const size_t X_bits, - const pb_variable &result, - const pb_linear_combination_array &result_bits, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -class XOR3_gadget : public gadget { -private: - pb_variable tmp; -public: - pb_linear_combination A; - pb_linear_combination B; - pb_linear_combination C; - bool assume_C_is_zero; - pb_linear_combination out; - - XOR3_gadget(protoboard &pb, - const pb_linear_combination &A, - const pb_linear_combination &B, - const pb_linear_combination &C, - const bool assume_C_is_zero, - const pb_linear_combination &out, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -class small_sigma_gadget : public gadget { -private: - pb_variable_array W; - pb_variable result; -public: - pb_variable_array result_bits; - std::vector > > compute_bits; - std::shared_ptr > pack_result; - - small_sigma_gadget(protoboard &pb, - const pb_variable_array &W, - const pb_variable &result, - const size_t rot1, - const size_t rot2, - const size_t shift, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -class big_sigma_gadget : public gadget { -private: - pb_linear_combination_array W; - pb_variable result; -public: - pb_variable_array result_bits; - std::vector > > compute_bits; - std::shared_ptr > pack_result; - - big_sigma_gadget(protoboard &pb, - const pb_linear_combination_array &W, - const pb_variable &result, - const size_t rot1, - const size_t rot2, - const size_t rot3, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -class choice_gadget : public gadget { -private: - pb_variable_array result_bits; -public: - pb_linear_combination_array X; - pb_linear_combination_array Y; - pb_linear_combination_array Z; - pb_variable result; - std::shared_ptr > pack_result; - - choice_gadget(protoboard &pb, - const pb_linear_combination_array &X, - const pb_linear_combination_array &Y, - const pb_linear_combination_array &Z, - const pb_variable &result, const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -class majority_gadget : public gadget { -private: - pb_variable_array result_bits; - std::shared_ptr > pack_result; -public: - pb_linear_combination_array X; - pb_linear_combination_array Y; - pb_linear_combination_array Z; - pb_variable result; - - majority_gadget(protoboard &pb, - const pb_linear_combination_array &X, - const pb_linear_combination_array &Y, - const pb_linear_combination_array &Z, - const pb_variable &result, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -} // libsnark - -#include "gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc" - -#endif // SHA256_AUX_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc deleted file mode 100644 index 0885f0b6d..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc +++ /dev/null @@ -1,297 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for auxiliary gadgets for the SHA256 gadget. - - See sha256_aux.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_AUX_TCC_ -#define SHA256_AUX_TCC_ - -namespace libsnark { - -template -lastbits_gadget::lastbits_gadget(protoboard &pb, - const pb_variable &X, - const size_t X_bits, - const pb_variable &result, - const pb_linear_combination_array &result_bits, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - X(X), - X_bits(X_bits), - result(result), - result_bits(result_bits) -{ - full_bits = result_bits; - for (size_t i = result_bits.size(); i < X_bits; ++i) - { - pb_variable full_bits_overflow; - full_bits_overflow.allocate(pb, FMT(this->annotation_prefix, " full_bits_%zu", i)); - full_bits.emplace_back(full_bits_overflow); - } - - unpack_bits.reset(new packing_gadget(pb, full_bits, X, FMT(this->annotation_prefix, " unpack_bits"))); - pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); -} - -template -void lastbits_gadget::generate_r1cs_constraints() -{ - unpack_bits->generate_r1cs_constraints(true); - pack_result->generate_r1cs_constraints(false); -} - -template -void lastbits_gadget::generate_r1cs_witness() -{ - unpack_bits->generate_r1cs_witness_from_packed(); - pack_result->generate_r1cs_witness_from_bits(); -} - -template -XOR3_gadget::XOR3_gadget(protoboard &pb, - const pb_linear_combination &A, - const pb_linear_combination &B, - const pb_linear_combination &C, - const bool assume_C_is_zero, - const pb_linear_combination &out, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - A(A), - B(B), - C(C), - assume_C_is_zero(assume_C_is_zero), - out(out) -{ - if (!assume_C_is_zero) - { - tmp.allocate(pb, FMT(this->annotation_prefix, " tmp")); - } -} - -template -void XOR3_gadget::generate_r1cs_constraints() -{ - /* - tmp = A + B - 2AB i.e. tmp = A xor B - out = tmp + C - 2tmp C i.e. out = tmp xor C - */ - if (assume_C_is_zero) - { - this->pb.add_r1cs_constraint(r1cs_constraint(2*A, B, A + B - out), FMT(this->annotation_prefix, " implicit_tmp_equals_out")); - } - else - { - this->pb.add_r1cs_constraint(r1cs_constraint(2*A, B, A + B - tmp), FMT(this->annotation_prefix, " tmp")); - this->pb.add_r1cs_constraint(r1cs_constraint(2 * tmp, C, tmp + C - out), FMT(this->annotation_prefix, " out")); - } -} - -template -void XOR3_gadget::generate_r1cs_witness() -{ - if (assume_C_is_zero) - { - this->pb.lc_val(out) = this->pb.lc_val(A) + this->pb.lc_val(B) - FieldT(2) * this->pb.lc_val(A) * this->pb.lc_val(B); - } - else - { - this->pb.val(tmp) = this->pb.lc_val(A) + this->pb.lc_val(B) - FieldT(2) * this->pb.lc_val(A) * this->pb.lc_val(B); - this->pb.lc_val(out) = this->pb.val(tmp) + this->pb.lc_val(C) - FieldT(2) * this->pb.val(tmp) * this->pb.lc_val(C); - } -} - -#define SHA256_GADGET_ROTR(A, i, k) A[((i)+(k)) % 32] - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -small_sigma_gadget::small_sigma_gadget(protoboard &pb, - const pb_variable_array &W, - const pb_variable &result, - const size_t rot1, - const size_t rot2, - const size_t shift, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - W(W), - result(result) -{ - result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); - compute_bits.resize(32); - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i].reset(new XOR3_gadget(pb, SHA256_GADGET_ROTR(W, i, rot1), SHA256_GADGET_ROTR(W, i, rot2), - (i + shift < 32 ? W[i+shift] : ONE), - (i + shift >= 32), result_bits[i], - FMT(this->annotation_prefix, " compute_bits_%zu", i))); - } - pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); -} - -template -void small_sigma_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i]->generate_r1cs_constraints(); - } - - pack_result->generate_r1cs_constraints(false); -} - -template -void small_sigma_gadget::generate_r1cs_witness() -{ - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i]->generate_r1cs_witness(); - } - - pack_result->generate_r1cs_witness_from_bits(); -} - -template -big_sigma_gadget::big_sigma_gadget(protoboard &pb, - const pb_linear_combination_array &W, - const pb_variable &result, - const size_t rot1, - const size_t rot2, - const size_t rot3, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - W(W), - result(result) -{ - result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); - compute_bits.resize(32); - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i].reset(new XOR3_gadget(pb, SHA256_GADGET_ROTR(W, i, rot1), SHA256_GADGET_ROTR(W, i, rot2), SHA256_GADGET_ROTR(W, i, rot3), false, result_bits[i], - FMT(this->annotation_prefix, " compute_bits_%zu", i))); - } - - pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); -} - -template -void big_sigma_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i]->generate_r1cs_constraints(); - } - - pack_result->generate_r1cs_constraints(false); -} - -template -void big_sigma_gadget::generate_r1cs_witness() -{ - for (size_t i = 0; i < 32; ++i) - { - compute_bits[i]->generate_r1cs_witness(); - } - - pack_result->generate_r1cs_witness_from_bits(); -} - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -choice_gadget::choice_gadget(protoboard &pb, - const pb_linear_combination_array &X, - const pb_linear_combination_array &Y, - const pb_linear_combination_array &Z, - const pb_variable &result, const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - X(X), - Y(Y), - Z(Z), - result(result) -{ - result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); - pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " result"))); -} - -template -void choice_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < 32; ++i) - { - /* - result = x * y + (1-x) * z - result - z = x * (y - z) - */ - this->pb.add_r1cs_constraint(r1cs_constraint(X[i], Y[i] - Z[i], result_bits[i] - Z[i]), FMT(this->annotation_prefix, " result_bits_%zu", i)); - } - pack_result->generate_r1cs_constraints(false); -} - -template -void choice_gadget::generate_r1cs_witness() -{ - for (size_t i = 0; i < 32; ++i) - { - this->pb.val(result_bits[i]) = this->pb.lc_val(X[i]) * this->pb.lc_val(Y[i]) + (FieldT::one() - this->pb.lc_val(X[i])) * this->pb.lc_val(Z[i]); - } - pack_result->generate_r1cs_witness_from_bits(); -} - -/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ -template -majority_gadget::majority_gadget(protoboard &pb, - const pb_linear_combination_array &X, - const pb_linear_combination_array &Y, - const pb_linear_combination_array &Z, - const pb_variable &result, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - X(X), - Y(Y), - Z(Z), - result(result) -{ - result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); - pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " result"))); -} - -template -void majority_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < 32; ++i) - { - /* - 2*result + aux = x + y + z - x, y, z, aux -- bits - aux = x + y + z - 2*result - */ - generate_boolean_r1cs_constraint(this->pb, result_bits[i], FMT(this->annotation_prefix, " result_%zu", i)); - this->pb.add_r1cs_constraint(r1cs_constraint(X[i] + Y[i] + Z[i] - 2 * result_bits[i], - 1 - (X[i] + Y[i] + Z[i] - 2 * result_bits[i]), - 0), - FMT(this->annotation_prefix, " result_bits_%zu", i)); - } - pack_result->generate_r1cs_constraints(false); -} - -template -void majority_gadget::generate_r1cs_witness() -{ - for (size_t i = 0; i < 32; ++i) - { - const uint64_t v = (this->pb.lc_val(X[i]) + this->pb.lc_val(Y[i]) + this->pb.lc_val(Z[i])).as_uint64(); - this->pb.val(result_bits[i]) = FieldT(v / 2); - } - - pack_result->generate_r1cs_witness_from_bits(); -} - -} // libsnark - -#endif // SHA256_AUX_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp deleted file mode 100644 index 2f7e71e35..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for gadgets for the SHA256 message schedule and round function. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_COMPONENTS_HPP_ -#define SHA256_COMPONENTS_HPP_ - -#include "gadgetlib1/gadgets/basic_gadgets.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" -#include "gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp" - -namespace libsnark { - -const size_t SHA256_digest_size = 256; -const size_t SHA256_block_size = 512; - -template -pb_linear_combination_array SHA256_default_IV(protoboard &pb); - -template -class sha256_message_schedule_gadget : public gadget { -public: - std::vector > W_bits; - std::vector > > pack_W; - - std::vector > sigma0; - std::vector > sigma1; - std::vector > > compute_sigma0; - std::vector > > compute_sigma1; - std::vector > unreduced_W; - std::vector > > mod_reduce_W; -public: - pb_variable_array M; - pb_variable_array packed_W; - sha256_message_schedule_gadget(protoboard &pb, - const pb_variable_array &M, - const pb_variable_array &packed_W, - const std::string &annotation_prefix); - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -template -class sha256_round_function_gadget : public gadget { -public: - pb_variable sigma0; - pb_variable sigma1; - std::shared_ptr > compute_sigma0; - std::shared_ptr > compute_sigma1; - pb_variable choice; - pb_variable majority; - std::shared_ptr > compute_choice; - std::shared_ptr > compute_majority; - pb_variable packed_d; - std::shared_ptr > pack_d; - pb_variable packed_h; - std::shared_ptr > pack_h; - pb_variable unreduced_new_a; - pb_variable unreduced_new_e; - std::shared_ptr > mod_reduce_new_a; - std::shared_ptr > mod_reduce_new_e; - pb_variable packed_new_a; - pb_variable packed_new_e; -public: - pb_linear_combination_array a; - pb_linear_combination_array b; - pb_linear_combination_array c; - pb_linear_combination_array d; - pb_linear_combination_array e; - pb_linear_combination_array f; - pb_linear_combination_array g; - pb_linear_combination_array h; - pb_variable W; - uint32_t K; - pb_linear_combination_array new_a; - pb_linear_combination_array new_e; - - sha256_round_function_gadget(protoboard &pb, - const pb_linear_combination_array &a, - const pb_linear_combination_array &b, - const pb_linear_combination_array &c, - const pb_linear_combination_array &d, - const pb_linear_combination_array &e, - const pb_linear_combination_array &f, - const pb_linear_combination_array &g, - const pb_linear_combination_array &h, - const pb_variable &W, - const uint32_t &K, - const pb_linear_combination_array &new_a, - const pb_linear_combination_array &new_e, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -} // libsnark - -#include "gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc" - -#endif // SHA256_COMPONENTS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc deleted file mode 100644 index 41ad20883..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc +++ /dev/null @@ -1,250 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for gadgets for the SHA256 message schedule and round function. - - See sha256_components.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_COMPONENTS_TCC_ -#define SHA256_COMPONENTS_TCC_ - -namespace libsnark { - -const uint32_t SHA256_K[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -const uint32_t SHA256_H[8] = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -}; - -template -pb_linear_combination_array SHA256_default_IV(protoboard &pb) -{ - pb_linear_combination_array result; - result.reserve(SHA256_digest_size); - - for (size_t i = 0; i < SHA256_digest_size; ++i) - { - int iv_val = (SHA256_H[i / 32] >> (31-(i % 32))) & 1; - - pb_linear_combination iv_element; - iv_element.assign(pb, iv_val * ONE); - iv_element.evaluate(pb); - - result.emplace_back(iv_element); - } - - return result; -} - -template -sha256_message_schedule_gadget::sha256_message_schedule_gadget(protoboard &pb, - const pb_variable_array &M, - const pb_variable_array &packed_W, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - M(M), - packed_W(packed_W) -{ - W_bits.resize(64); - - pack_W.resize(16); - for (size_t i = 0; i < 16; ++i) - { - W_bits[i] = pb_variable_array(M.rbegin() + (15-i) * 32, M.rbegin() + (16-i) * 32); - pack_W[i].reset(new packing_gadget(pb, W_bits[i], packed_W[i], FMT(this->annotation_prefix, " pack_W_%zu", i))); - } - - /* NB: some of those will be un-allocated */ - sigma0.resize(64); - sigma1.resize(64); - compute_sigma0.resize(64); - compute_sigma1.resize(64); - unreduced_W.resize(64); - mod_reduce_W.resize(64); - - for (size_t i = 16; i < 64; ++i) - { - /* allocate result variables for sigma0/sigma1 invocations */ - sigma0[i].allocate(pb, FMT(this->annotation_prefix, " sigma0_%zu", i)); - sigma1[i].allocate(pb, FMT(this->annotation_prefix, " sigma1_%zu", i)); - - /* compute sigma0/sigma1 */ - compute_sigma0[i].reset(new small_sigma_gadget(pb, W_bits[i-15], sigma0[i], 7, 18, 3, FMT(this->annotation_prefix, " compute_sigma0_%zu", i))); - compute_sigma1[i].reset(new small_sigma_gadget(pb, W_bits[i-2], sigma1[i], 17, 19, 10, FMT(this->annotation_prefix, " compute_sigma1_%zu", i))); - - /* unreduced_W = sigma0(W_{i-15}) + sigma1(W_{i-2}) + W_{i-7} + W_{i-16} before modulo 2^32 */ - unreduced_W[i].allocate(pb, FMT(this->annotation_prefix, "unreduced_W_%zu", i)); - - /* allocate the bit representation of packed_W[i] */ - W_bits[i].allocate(pb, 32, FMT(this->annotation_prefix, " W_bits_%zu", i)); - - /* and finally reduce this into packed and bit representations */ - mod_reduce_W[i].reset(new lastbits_gadget(pb, unreduced_W[i], 32+2, packed_W[i], W_bits[i], FMT(this->annotation_prefix, " mod_reduce_W_%zu", i))); - } -} - -template -void sha256_message_schedule_gadget::generate_r1cs_constraints() -{ - for (size_t i = 0; i < 16; ++i) - { - pack_W[i]->generate_r1cs_constraints(false); // do not enforce bitness here; caller be aware. - } - - for (size_t i = 16; i < 64; ++i) - { - compute_sigma0[i]->generate_r1cs_constraints(); - compute_sigma1[i]->generate_r1cs_constraints(); - - this->pb.add_r1cs_constraint(r1cs_constraint(1, - sigma0[i] + sigma1[i] + packed_W[i-16] + packed_W[i-7], - unreduced_W[i]), - FMT(this->annotation_prefix, " unreduced_W_%zu", i)); - - mod_reduce_W[i]->generate_r1cs_constraints(); - } -} - -template -void sha256_message_schedule_gadget::generate_r1cs_witness() -{ - for (size_t i = 0; i < 16; ++i) - { - pack_W[i]->generate_r1cs_witness_from_bits(); - } - - for (size_t i = 16; i < 64; ++i) - { - compute_sigma0[i]->generate_r1cs_witness(); - compute_sigma1[i]->generate_r1cs_witness(); - - this->pb.val(unreduced_W[i]) = this->pb.val(sigma0[i]) + this->pb.val(sigma1[i]) + this->pb.val(packed_W[i-16]) + this->pb.val(packed_W[i-7]); - mod_reduce_W[i]->generate_r1cs_witness(); - } -} - -template -sha256_round_function_gadget::sha256_round_function_gadget(protoboard &pb, - const pb_linear_combination_array &a, - const pb_linear_combination_array &b, - const pb_linear_combination_array &c, - const pb_linear_combination_array &d, - const pb_linear_combination_array &e, - const pb_linear_combination_array &f, - const pb_linear_combination_array &g, - const pb_linear_combination_array &h, - const pb_variable &W, - const uint32_t &K, - const pb_linear_combination_array &new_a, - const pb_linear_combination_array &new_e, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - a(a), - b(b), - c(c), - d(d), - e(e), - f(f), - g(g), - h(h), - W(W), - K(K), - new_a(new_a), - new_e(new_e) -{ - /* compute sigma0 and sigma1 */ - sigma0.allocate(pb, FMT(this->annotation_prefix, " sigma0")); - sigma1.allocate(pb, FMT(this->annotation_prefix, " sigma1")); - compute_sigma0.reset(new big_sigma_gadget(pb, a, sigma0, 2, 13, 22, FMT(this->annotation_prefix, " compute_sigma0"))); - compute_sigma1.reset(new big_sigma_gadget(pb, e, sigma1, 6, 11, 25, FMT(this->annotation_prefix, " compute_sigma1"))); - - /* compute choice */ - choice.allocate(pb, FMT(this->annotation_prefix, " choice")); - compute_choice.reset(new choice_gadget(pb, e, f, g, choice, FMT(this->annotation_prefix, " compute_choice"))); - - /* compute majority */ - majority.allocate(pb, FMT(this->annotation_prefix, " majority")); - compute_majority.reset(new majority_gadget(pb, a, b, c, majority, FMT(this->annotation_prefix, " compute_majority"))); - - /* pack d */ - packed_d.allocate(pb, FMT(this->annotation_prefix, " packed_d")); - pack_d.reset(new packing_gadget(pb, d, packed_d, FMT(this->annotation_prefix, " pack_d"))); - - /* pack h */ - packed_h.allocate(pb, FMT(this->annotation_prefix, " packed_h")); - pack_h.reset(new packing_gadget(pb, h, packed_h, FMT(this->annotation_prefix, " pack_h"))); - - /* compute the actual results for the round */ - unreduced_new_a.allocate(pb, FMT(this->annotation_prefix, " unreduced_new_a")); - unreduced_new_e.allocate(pb, FMT(this->annotation_prefix, " unreduced_new_e")); - - packed_new_a.allocate(pb, FMT(this->annotation_prefix, " packed_new_a")); - packed_new_e.allocate(pb, FMT(this->annotation_prefix, " packed_new_e")); - - mod_reduce_new_a.reset(new lastbits_gadget(pb, unreduced_new_a, 32+3, packed_new_a, new_a, FMT(this->annotation_prefix, " mod_reduce_new_a"))); - mod_reduce_new_e.reset(new lastbits_gadget(pb, unreduced_new_e, 32+3, packed_new_e, new_e, FMT(this->annotation_prefix, " mod_reduce_new_e"))); -} - -template -void sha256_round_function_gadget::generate_r1cs_constraints() -{ - compute_sigma0->generate_r1cs_constraints(); - compute_sigma1->generate_r1cs_constraints(); - - compute_choice->generate_r1cs_constraints(); - compute_majority->generate_r1cs_constraints(); - - pack_d->generate_r1cs_constraints(false); - pack_h->generate_r1cs_constraints(false); - - this->pb.add_r1cs_constraint(r1cs_constraint(1, - packed_h + sigma1 + choice + K + W + sigma0 + majority, - unreduced_new_a), - FMT(this->annotation_prefix, " unreduced_new_a")); - - this->pb.add_r1cs_constraint(r1cs_constraint(1, - packed_d + packed_h + sigma1 + choice + K + W, - unreduced_new_e), - FMT(this->annotation_prefix, " unreduced_new_e")); - - mod_reduce_new_a->generate_r1cs_constraints(); - mod_reduce_new_e->generate_r1cs_constraints(); -} - -template -void sha256_round_function_gadget::generate_r1cs_witness() -{ - compute_sigma0->generate_r1cs_witness(); - compute_sigma1->generate_r1cs_witness(); - - compute_choice->generate_r1cs_witness(); - compute_majority->generate_r1cs_witness(); - - pack_d->generate_r1cs_witness_from_bits(); - pack_h->generate_r1cs_witness_from_bits(); - - this->pb.val(unreduced_new_a) = this->pb.val(packed_h) + this->pb.val(sigma1) + this->pb.val(choice) + FieldT(K) + this->pb.val(W) + this->pb.val(sigma0) + this->pb.val(majority); - this->pb.val(unreduced_new_e) = this->pb.val(packed_d) + this->pb.val(packed_h) + this->pb.val(sigma1) + this->pb.val(choice) + FieldT(K) + this->pb.val(W); - - mod_reduce_new_a->generate_r1cs_witness(); - mod_reduce_new_e->generate_r1cs_witness(); -} - -} // libsnark - -#endif // SHA256_COMPONENTS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp deleted file mode 100644 index 8cb6365c8..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for top-level SHA256 gadgets. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_GADGET_HPP_ -#define SHA256_GADGET_HPP_ - -#include "common/data_structures/merkle_tree.hpp" -#include "gadgetlib1/gadgets/basic_gadgets.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" -#include "gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp" - -namespace libsnark { - -/** - * Gadget for the SHA256 compression function. - */ -template -class sha256_compression_function_gadget : public gadget { -public: - std::vector > round_a; - std::vector > round_b; - std::vector > round_c; - std::vector > round_d; - std::vector > round_e; - std::vector > round_f; - std::vector > round_g; - std::vector > round_h; - - pb_variable_array packed_W; - std::shared_ptr > message_schedule; - std::vector > round_functions; - - pb_variable_array unreduced_output; - pb_variable_array reduced_output; - std::vector > reduce_output; -public: - pb_linear_combination_array prev_output; - pb_variable_array new_block; - digest_variable output; - - sha256_compression_function_gadget(protoboard &pb, - const pb_linear_combination_array &prev_output, - const pb_variable_array &new_block, - const digest_variable &output, - const std::string &annotation_prefix); - void generate_r1cs_constraints(); - void generate_r1cs_witness(); -}; - -/** - * Gadget for the SHA256 compression function, viewed as a 2-to-1 hash - * function, and using the same initialization vector as in SHA256 - * specification. Thus, any collision for - * sha256_two_to_one_hash_gadget trivially extends to a collision for - * full SHA256 (by appending the same padding). - */ -template -class sha256_two_to_one_hash_gadget : public gadget { -public: - typedef bit_vector hash_value_type; - typedef merkle_authentication_path merkle_authentication_path_type; - - std::shared_ptr > f; - - sha256_two_to_one_hash_gadget(protoboard &pb, - const digest_variable &left, - const digest_variable &right, - const digest_variable &output, - const std::string &annotation_prefix); - sha256_two_to_one_hash_gadget(protoboard &pb, - const size_t block_length, - const block_variable &input_block, - const digest_variable &output, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(const bool ensure_output_bitness=true); // TODO: ignored for now - void generate_r1cs_witness(); - - static size_t get_block_len(); - static size_t get_digest_len(); - static bit_vector get_hash(const bit_vector &input); - - static size_t expected_constraints(const bool ensure_output_bitness=true); // TODO: ignored for now -}; - -} // libsnark - -#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc" - -#endif // SHA256_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc deleted file mode 100644 index 3004f9e83..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc +++ /dev/null @@ -1,230 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for top-level SHA256 gadgets. - - See sha256_gadget.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef SHA256_GADGET_TCC_ -#define SHA256_GADGET_TCC_ - -namespace libsnark { - -template -sha256_compression_function_gadget::sha256_compression_function_gadget(protoboard &pb, - const pb_linear_combination_array &prev_output, - const pb_variable_array &new_block, - const digest_variable &output, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - prev_output(prev_output), - new_block(new_block), - output(output) -{ - /* message schedule and inputs for it */ - packed_W.allocate(pb, 64, FMT(this->annotation_prefix, " packed_W")); - message_schedule.reset(new sha256_message_schedule_gadget(pb, new_block, packed_W, FMT(this->annotation_prefix, " message_schedule"))); - - /* initalize */ - round_a.push_back(pb_linear_combination_array(prev_output.rbegin() + 7*32, prev_output.rbegin() + 8*32)); - round_b.push_back(pb_linear_combination_array(prev_output.rbegin() + 6*32, prev_output.rbegin() + 7*32)); - round_c.push_back(pb_linear_combination_array(prev_output.rbegin() + 5*32, prev_output.rbegin() + 6*32)); - round_d.push_back(pb_linear_combination_array(prev_output.rbegin() + 4*32, prev_output.rbegin() + 5*32)); - round_e.push_back(pb_linear_combination_array(prev_output.rbegin() + 3*32, prev_output.rbegin() + 4*32)); - round_f.push_back(pb_linear_combination_array(prev_output.rbegin() + 2*32, prev_output.rbegin() + 3*32)); - round_g.push_back(pb_linear_combination_array(prev_output.rbegin() + 1*32, prev_output.rbegin() + 2*32)); - round_h.push_back(pb_linear_combination_array(prev_output.rbegin() + 0*32, prev_output.rbegin() + 1*32)); - - /* do the rounds */ - for (size_t i = 0; i < 64; ++i) - { - round_h.push_back(round_g[i]); - round_g.push_back(round_f[i]); - round_f.push_back(round_e[i]); - round_d.push_back(round_c[i]); - round_c.push_back(round_b[i]); - round_b.push_back(round_a[i]); - - pb_variable_array new_round_a_variables; - new_round_a_variables.allocate(pb, 32, FMT(this->annotation_prefix, " new_round_a_variables_%zu", i+1)); - round_a.emplace_back(new_round_a_variables); - - pb_variable_array new_round_e_variables; - new_round_e_variables.allocate(pb, 32, FMT(this->annotation_prefix, " new_round_e_variables_%zu", i+1)); - round_e.emplace_back(new_round_e_variables); - - round_functions.push_back(sha256_round_function_gadget(pb, - round_a[i], round_b[i], round_c[i], round_d[i], - round_e[i], round_f[i], round_g[i], round_h[i], - packed_W[i], SHA256_K[i], round_a[i+1], round_e[i+1], - FMT(this->annotation_prefix, " round_functions_%zu", i))); - } - - /* finalize */ - unreduced_output.allocate(pb, 8, FMT(this->annotation_prefix, " unreduced_output")); - reduced_output.allocate(pb, 8, FMT(this->annotation_prefix, " reduced_output")); - for (size_t i = 0; i < 8; ++i) - { - reduce_output.push_back(lastbits_gadget(pb, - unreduced_output[i], - 32+1, - reduced_output[i], - pb_variable_array(output.bits.rbegin() + (7-i) * 32, output.bits.rbegin() + (8-i) * 32), - FMT(this->annotation_prefix, " reduce_output_%zu", i))); - } -} - -template -void sha256_compression_function_gadget::generate_r1cs_constraints() -{ - message_schedule->generate_r1cs_constraints(); - for (size_t i = 0; i < 64; ++i) - { - round_functions[i].generate_r1cs_constraints(); - } - - for (size_t i = 0; i < 4; ++i) - { - this->pb.add_r1cs_constraint(r1cs_constraint(1, - round_functions[3-i].packed_d + round_functions[63-i].packed_new_a, - unreduced_output[i]), - FMT(this->annotation_prefix, " unreduced_output_%zu", i)); - - this->pb.add_r1cs_constraint(r1cs_constraint(1, - round_functions[3-i].packed_h + round_functions[63-i].packed_new_e, - unreduced_output[4+i]), - FMT(this->annotation_prefix, " unreduced_output_%zu", 4+i)); - } - - for (size_t i = 0; i < 8; ++i) - { - reduce_output[i].generate_r1cs_constraints(); - } -} - -template -void sha256_compression_function_gadget::generate_r1cs_witness() -{ - message_schedule->generate_r1cs_witness(); - -#ifdef DEBUG - printf("Input:\n"); - for (size_t j = 0; j < 16; ++j) - { - printf("%lx ", this->pb.val(packed_W[j]).as_uint64()); - } - printf("\n"); -#endif - - for (size_t i = 0; i < 64; ++i) - { - round_functions[i].generate_r1cs_witness(); - } - - for (size_t i = 0; i < 4; ++i) - { - this->pb.val(unreduced_output[i]) = this->pb.val(round_functions[3-i].packed_d) + this->pb.val(round_functions[63-i].packed_new_a); - this->pb.val(unreduced_output[4+i]) = this->pb.val(round_functions[3-i].packed_h) + this->pb.val(round_functions[63-i].packed_new_e); - } - - for (size_t i = 0; i < 8; ++i) - { - reduce_output[i].generate_r1cs_witness(); - } - -#ifdef DEBUG - printf("Output:\n"); - for (size_t j = 0; j < 8; ++j) - { - printf("%lx ", this->pb.val(reduced_output[j]).as_uint64()); - } - printf("\n"); -#endif -} - -template -sha256_two_to_one_hash_gadget::sha256_two_to_one_hash_gadget(protoboard &pb, - const digest_variable &left, - const digest_variable &right, - const digest_variable &output, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix) -{ - /* concatenate block = left || right */ - pb_variable_array block; - block.insert(block.end(), left.bits.begin(), left.bits.end()); - block.insert(block.end(), right.bits.begin(), right.bits.end()); - - /* compute the hash itself */ - f.reset(new sha256_compression_function_gadget(pb, SHA256_default_IV(pb), block, output, FMT(this->annotation_prefix, " f"))); -} - -template -sha256_two_to_one_hash_gadget::sha256_two_to_one_hash_gadget(protoboard &pb, - const size_t block_length, - const block_variable &input_block, - const digest_variable &output, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix) -{ - assert(block_length == SHA256_block_size); - assert(input_block.bits.size() == block_length); - f.reset(new sha256_compression_function_gadget(pb, SHA256_default_IV(pb), input_block.bits, output, FMT(this->annotation_prefix, " f"))); -} - -template -void sha256_two_to_one_hash_gadget::generate_r1cs_constraints(const bool ensure_output_bitness) -{ - UNUSED(ensure_output_bitness); - f->generate_r1cs_constraints(); -} - -template -void sha256_two_to_one_hash_gadget::generate_r1cs_witness() -{ - f->generate_r1cs_witness(); -} - -template -size_t sha256_two_to_one_hash_gadget::get_block_len() -{ - return SHA256_block_size; -} - -template -size_t sha256_two_to_one_hash_gadget::get_digest_len() -{ - return SHA256_digest_size; -} - -template -bit_vector sha256_two_to_one_hash_gadget::get_hash(const bit_vector &input) -{ - protoboard pb; - - block_variable input_variable(pb, SHA256_block_size, "input"); - digest_variable output_variable(pb, SHA256_digest_size, "output"); - sha256_two_to_one_hash_gadget f(pb, SHA256_block_size, input_variable, output_variable, "f"); - - input_variable.generate_r1cs_witness(input); - f.generate_r1cs_witness(); - - return output_variable.get_digest(); -} - -template -size_t sha256_two_to_one_hash_gadget::expected_constraints(const bool ensure_output_bitness) -{ - UNUSED(ensure_output_bitness); - return 27280; /* hardcoded for now */ -} - -} // libsnark - -#endif // SHA256_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py deleted file mode 100644 index 452317ffb..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -## -# @author This file is part of libsnark, developed by SCIPR Lab -# and contributors (see AUTHORS). -# @copyright MIT license (see LICENSE file) - -import random -import pypy_sha256 # PyPy's implementation of SHA256 compression function; see copyright and authorship notice within. - -BLOCK_LEN = 512 -BLOCK_BYTES = BLOCK_LEN // 8 -HASH_LEN = 256 -HASH_BYTES = HASH_LEN // 8 - -def gen_random_bytes(n): - return [random.randint(0, 255) for i in xrange(n)] - -def words_to_bytes(arr): - return sum(([x >> 24, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff] for x in arr), []) - -def bytes_to_words(arr): - l = len(arr) - assert l % 4 == 0 - return [(arr[i*4 + 3] << 24) + (arr[i*4+2] << 16) + (arr[i*4+1] << 8) + arr[i*4] for i in xrange(l//4)] - -def cpp_val(s, log_radix=32): - if log_radix == 8: - hexfmt = '0x%02x' - elif log_radix == 32: - hexfmt = '0x%08x' - s = bytes_to_words(s) - else: - raise - return 'int_list_to_bits({%s}, %d)' % (', '.join(hexfmt % x for x in s), log_radix) - -def H_bytes(x): - assert len(x) == BLOCK_BYTES - state = pypy_sha256.sha_init() - state['data'] = words_to_bytes(bytes_to_words(x)) - pypy_sha256.sha_transform(state) - return words_to_bytes(bytes_to_words(words_to_bytes(state['digest']))) - -def generate_sha256_gadget_tests(): - left = gen_random_bytes(HASH_BYTES) - right = gen_random_bytes(HASH_BYTES) - hash = H_bytes(left + right) - - print "const bit_vector left_bv = %s;" % cpp_val(left) - print "const bit_vector right_bv = %s;" % cpp_val(right) - print "const bit_vector hash_bv = %s;" % cpp_val(hash) - -if __name__ == '__main__': - random.seed(0) # for reproducibility - generate_sha256_gadget_tests() - diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py deleted file mode 100644 index 496989c11..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/env python -# -# SHA256 compression function implementation below is a verbatim copy of PyPy's implementation from -# https://bitbucket.org/pypy/pypy/raw/f1f064b3faf1e012f7a9a9ab08f18074637ebe8a/lib_pypy/_sha256.py . -# -# It is licensed under the MIT license and copyright PyPy Copyright holders 2003-2015 -# See https://bitbucket.org/pypy/pypy/src/tip/LICENSE for the full copyright notice. -# - -SHA_BLOCKSIZE = 64 -SHA_DIGESTSIZE = 32 - - -def new_shaobject(): - return { - 'digest': [0]*8, - 'count_lo': 0, - 'count_hi': 0, - 'data': [0]* SHA_BLOCKSIZE, - 'local': 0, - 'digestsize': 0 - } - -ROR = lambda x, y: (((x & 0xffffffff) >> (y & 31)) | (x << (32 - (y & 31)))) & 0xffffffff -Ch = lambda x, y, z: (z ^ (x & (y ^ z))) -Maj = lambda x, y, z: (((x | y) & z) | (x & y)) -S = lambda x, n: ROR(x, n) -R = lambda x, n: (x & 0xffffffff) >> n -Sigma0 = lambda x: (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -Sigma1 = lambda x: (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -Gamma0 = lambda x: (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -Gamma1 = lambda x: (S(x, 17) ^ S(x, 19) ^ R(x, 10)) - -def sha_transform(sha_info): - W = [] - - d = sha_info['data'] - for i in range(0,16): - W.append( (d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3]) - - for i in range(16,64): - W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff ) - - ss = sha_info['digest'][:] - - def RND(a,b,c,d,e,f,g,h,i,ki): - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; - t1 = Sigma0(a) + Maj(a, b, c); - d += t0; - h = t0 + t1; - return d & 0xffffffff, h & 0xffffffff - - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],0,0x428a2f98); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],1,0x71374491); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],2,0xb5c0fbcf); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],3,0xe9b5dba5); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],4,0x3956c25b); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],5,0x59f111f1); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],6,0x923f82a4); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],7,0xab1c5ed5); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],8,0xd807aa98); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],9,0x12835b01); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],10,0x243185be); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],11,0x550c7dc3); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],12,0x72be5d74); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],13,0x80deb1fe); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],14,0x9bdc06a7); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],15,0xc19bf174); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],16,0xe49b69c1); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],17,0xefbe4786); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],18,0x0fc19dc6); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],19,0x240ca1cc); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],20,0x2de92c6f); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],21,0x4a7484aa); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],22,0x5cb0a9dc); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],23,0x76f988da); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],24,0x983e5152); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],25,0xa831c66d); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],26,0xb00327c8); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],27,0xbf597fc7); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],28,0xc6e00bf3); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],29,0xd5a79147); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],30,0x06ca6351); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],31,0x14292967); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],32,0x27b70a85); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],33,0x2e1b2138); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],34,0x4d2c6dfc); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],35,0x53380d13); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],36,0x650a7354); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],37,0x766a0abb); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],38,0x81c2c92e); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],39,0x92722c85); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],40,0xa2bfe8a1); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],41,0xa81a664b); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],42,0xc24b8b70); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],43,0xc76c51a3); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],44,0xd192e819); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],45,0xd6990624); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],46,0xf40e3585); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],47,0x106aa070); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],48,0x19a4c116); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],49,0x1e376c08); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],50,0x2748774c); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],51,0x34b0bcb5); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],52,0x391c0cb3); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],53,0x4ed8aa4a); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],54,0x5b9cca4f); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],55,0x682e6ff3); - ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],56,0x748f82ee); - ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],57,0x78a5636f); - ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],58,0x84c87814); - ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],59,0x8cc70208); - ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],60,0x90befffa); - ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],61,0xa4506ceb); - ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],62,0xbef9a3f7); - ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],63,0xc67178f2); - - dig = [] - for i, x in enumerate(sha_info['digest']): - dig.append( (x + ss[i]) & 0xffffffff ) - sha_info['digest'] = dig - -def sha_init(): - sha_info = new_shaobject() - sha_info['digest'] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19] - sha_info['count_lo'] = 0 - sha_info['count_hi'] = 0 - sha_info['local'] = 0 - sha_info['digestsize'] = 32 - return sha_info - -def sha224_init(): - sha_info = new_shaobject() - sha_info['digest'] = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] - sha_info['count_lo'] = 0 - sha_info['count_hi'] = 0 - sha_info['local'] = 0 - sha_info['digestsize'] = 28 - return sha_info - -def sha_update(sha_info, buffer): - if isinstance(buffer, str): - raise TypeError("Unicode strings must be encoded before hashing") - count = len(buffer) - buffer_idx = 0 - clo = (sha_info['count_lo'] + (count << 3)) & 0xffffffff - if clo < sha_info['count_lo']: - sha_info['count_hi'] += 1 - sha_info['count_lo'] = clo - - sha_info['count_hi'] += (count >> 29) - - if sha_info['local']: - i = SHA_BLOCKSIZE - sha_info['local'] - if i > count: - i = count - - # copy buffer - sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i] - - count -= i - buffer_idx += i - - sha_info['local'] += i - if sha_info['local'] == SHA_BLOCKSIZE: - sha_transform(sha_info) - sha_info['local'] = 0 - else: - return - - while count >= SHA_BLOCKSIZE: - # copy buffer - sha_info['data'] = list(buffer[buffer_idx:buffer_idx + SHA_BLOCKSIZE]) - count -= SHA_BLOCKSIZE - buffer_idx += SHA_BLOCKSIZE - sha_transform(sha_info) - - - # copy buffer - pos = sha_info['local'] - sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] - sha_info['local'] = count - -def sha_final(sha_info): - lo_bit_count = sha_info['count_lo'] - hi_bit_count = sha_info['count_hi'] - count = (lo_bit_count >> 3) & 0x3f - sha_info['data'][count] = 0x80; - count += 1 - if count > SHA_BLOCKSIZE - 8: - # zero the bytes in data after the count - sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count)) - sha_transform(sha_info) - # zero bytes in data - sha_info['data'] = [0] * SHA_BLOCKSIZE - else: - sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count)) - - sha_info['data'][56] = (hi_bit_count >> 24) & 0xff - sha_info['data'][57] = (hi_bit_count >> 16) & 0xff - sha_info['data'][58] = (hi_bit_count >> 8) & 0xff - sha_info['data'][59] = (hi_bit_count >> 0) & 0xff - sha_info['data'][60] = (lo_bit_count >> 24) & 0xff - sha_info['data'][61] = (lo_bit_count >> 16) & 0xff - sha_info['data'][62] = (lo_bit_count >> 8) & 0xff - sha_info['data'][63] = (lo_bit_count >> 0) & 0xff - - sha_transform(sha_info) - - dig = [] - for i in sha_info['digest']: - dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) - return ''.join([chr(i) for i in dig]) - -class sha256(object): - digest_size = digestsize = SHA_DIGESTSIZE - block_size = SHA_BLOCKSIZE - - def __init__(self, s=None): - self._sha = sha_init() - if s: - sha_update(self._sha, s) - - def update(self, s): - sha_update(self._sha, s) - - def digest(self): - return sha_final(self._sha.copy())[:self._sha['digestsize']] - - def hexdigest(self): - return ''.join(['%.2x' % ord(i) for i in self.digest()]) - - def copy(self): - new = sha256.__new__(sha256) - new._sha = self._sha.copy() - return new - -class sha224(sha256): - digest_size = digestsize = 28 - - def __init__(self, s=None): - self._sha = sha224_init() - if s: - sha_update(self._sha, s) - - def copy(self): - new = sha224.__new__(sha224) - new._sha = self._sha.copy() - return new - -def test(): - a_str = "just a test string" - - assert 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' == sha256().hexdigest() - assert 'd7b553c6f09ac85d142415f857c5310f3bbbe7cdd787cce4b985acedd585266f' == sha256(a_str).hexdigest() - assert '8113ebf33c97daa9998762aacafe750c7cefc2b2f173c90c59663a57fe626f21' == sha256(a_str*7).hexdigest() - - s = sha256(a_str) - s.update(a_str) - assert '03d9963e05a094593190b6fc794cb1a3e1ac7d7883f0b5855268afeccc70d461' == s.hexdigest() - -if __name__ == "__main__": - test() diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp deleted file mode 100644 index 471928f6a..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#include "common/default_types/ec_pp.hpp" -#include "common/utils.hpp" -#include "common/profiling.hpp" -#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" - -using namespace libsnark; - -template -void test_two_to_one() -{ - protoboard pb; - - digest_variable left(pb, SHA256_digest_size, "left"); - digest_variable right(pb, SHA256_digest_size, "right"); - digest_variable output(pb, SHA256_digest_size, "output"); - - sha256_two_to_one_hash_gadget f(pb, left, right, output, "f"); - f.generate_r1cs_constraints(); - printf("Number of constraints for sha256_two_to_one_hash_gadget: %zu\n", pb.num_constraints()); - - const bit_vector left_bv = int_list_to_bits({0x426bc2d8, 0x4dc86782, 0x81e8957a, 0x409ec148, 0xe6cffbe8, 0xafe6ba4f, 0x9c6f1978, 0xdd7af7e9}, 32); - const bit_vector right_bv = int_list_to_bits({0x038cce42, 0xabd366b8, 0x3ede7e00, 0x9130de53, 0x72cdf73d, 0xee825114, 0x8cb48d1b, 0x9af68ad0}, 32); - const bit_vector hash_bv = int_list_to_bits({0xeffd0b7f, 0x1ccba116, 0x2ee816f7, 0x31c62b48, 0x59305141, 0x990e5c0a, 0xce40d33d, 0x0b1167d1}, 32); - - left.generate_r1cs_witness(left_bv); - right.generate_r1cs_witness(right_bv); - - f.generate_r1cs_witness(); - output.generate_r1cs_witness(hash_bv); - - assert(pb.is_satisfied()); -} - -int main(void) -{ - start_profiling(); - default_ec_pp::init_public_params(); - test_two_to_one >(); -} diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp deleted file mode 100644 index 0efa7cf4d..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP_ -#define MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP_ - -#include "common/data_structures/merkle_tree.hpp" -#include "gadgetlib1/gadget.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" - -namespace libsnark { - -template -class merkle_authentication_path_variable : public gadget { -public: - - const size_t tree_depth; - std::vector > left_digests; - std::vector > right_digests; - - merkle_authentication_path_variable(protoboard &pb, - const size_t tree_depth, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(const size_t address, const merkle_authentication_path &path); - merkle_authentication_path get_authentication_path(const size_t address) const; -}; - -} // libsnark - -#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc" - -#endif // MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc deleted file mode 100644 index b3d805d8e..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc +++ /dev/null @@ -1,76 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC_ -#define MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC_ - -namespace libsnark { - -template -merkle_authentication_path_variable::merkle_authentication_path_variable(protoboard &pb, - const size_t tree_depth, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - tree_depth(tree_depth) -{ - for (size_t i = 0; i < tree_depth; ++i) - { - left_digests.emplace_back(digest_variable(pb, HashT::get_digest_len(), FMT(annotation_prefix, " left_digests_%zu", i))); - right_digests.emplace_back(digest_variable(pb, HashT::get_digest_len(), FMT(annotation_prefix, " right_digests_%zu", i))); - } -} - -template -void merkle_authentication_path_variable::generate_r1cs_constraints() -{ - for (size_t i = 0; i < tree_depth; ++i) - { - left_digests[i].generate_r1cs_constraints(); - right_digests[i].generate_r1cs_constraints(); - } -} - -template -void merkle_authentication_path_variable::generate_r1cs_witness(const size_t address, const merkle_authentication_path &path) -{ - assert(path.size() == tree_depth); - - for (size_t i = 0; i < tree_depth; ++i) - { - if (address & (UINT64_C(1) << (tree_depth-1-i))) - { - left_digests[i].generate_r1cs_witness(path[i]); - } - else - { - right_digests[i].generate_r1cs_witness(path[i]); - } - } -} - -template -merkle_authentication_path merkle_authentication_path_variable::get_authentication_path(const size_t address) const -{ - merkle_authentication_path result; - for (size_t i = 0; i < tree_depth; ++i) - { - if (address & (UINT64_C(1) << (tree_depth-1-i))) - { - result.emplace_back(left_digests[i].get_digest()); - } - else - { - result.emplace_back(right_digests[i].get_digest()); - } - } - - return result; -} - -} // libsnark - -#endif // MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp deleted file mode 100644 index b1e3a4f05..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for the Merkle tree check read gadget. - - The gadget checks the following: given a root R, address A, value V, and - authentication path P, check that P is a valid authentication path for the - value V as the A-th leaf in a Merkle tree with root R. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_CHECK_READ_GADGET_HPP_ -#define MERKLE_TREE_CHECK_READ_GADGET_HPP_ - -#include "common/data_structures/merkle_tree.hpp" -#include "gadgetlib1/gadget.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" -#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp" -#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp" - -namespace libsnark { - -template -class merkle_tree_check_read_gadget : public gadget { -private: - - std::vector hashers; - std::vector > hasher_inputs; - std::vector > propagators; - std::vector > internal_output; - - std::shared_ptr > computed_root; - std::shared_ptr > check_root; - -public: - - const size_t digest_size; - const size_t tree_depth; - pb_linear_combination_array address_bits; - digest_variable leaf; - digest_variable root; - merkle_authentication_path_variable path; - pb_linear_combination read_successful; - - merkle_tree_check_read_gadget(protoboard &pb, - const size_t tree_depth, - const pb_linear_combination_array &address_bits, - const digest_variable &leaf_digest, - const digest_variable &root_digest, - const merkle_authentication_path_variable &path, - const pb_linear_combination &read_successful, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); - - static size_t root_size_in_bits(); - /* for debugging purposes */ - static size_t expected_constraints(const size_t tree_depth); -}; - -template -void test_merkle_tree_check_read_gadget(); - -} // libsnark - -#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc" - -#endif // MERKLE_TREE_CHECK_READ_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc deleted file mode 100644 index 29ce1b8ac..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc +++ /dev/null @@ -1,196 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for the Merkle tree check read. - - See merkle_tree_check_read_gadget.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_CHECK_READ_GADGET_TCC_ -#define MERKLE_TREE_CHECK_READ_GADGET_TCC_ - -namespace libsnark { - -template -merkle_tree_check_read_gadget::merkle_tree_check_read_gadget(protoboard &pb, - const size_t tree_depth, - const pb_linear_combination_array &address_bits, - const digest_variable &leaf, - const digest_variable &root, - const merkle_authentication_path_variable &path, - const pb_linear_combination &read_successful, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - digest_size(HashT::get_digest_len()), - tree_depth(tree_depth), - address_bits(address_bits), - leaf(leaf), - root(root), - path(path), - read_successful(read_successful) -{ - /* - The tricky part here is ordering. For Merkle tree - authentication paths, path[0] corresponds to one layer below - the root (and path[tree_depth-1] corresponds to the layer - containing the leaf), while address_bits has the reverse order: - address_bits[0] is LSB, and corresponds to layer containing the - leaf, and address_bits[tree_depth-1] is MSB, and corresponds to - the subtree directly under the root. - */ - assert(tree_depth > 0); - assert(tree_depth == address_bits.size()); - - for (size_t i = 0; i < tree_depth-1; ++i) - { - internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " internal_output_%zu", i))); - } - - computed_root.reset(new digest_variable(pb, digest_size, FMT(this->annotation_prefix, " computed_root"))); - - for (size_t i = 0; i < tree_depth; ++i) - { - block_variable inp(pb, path.left_digests[i], path.right_digests[i], FMT(this->annotation_prefix, " inp_%zu", i)); - hasher_inputs.emplace_back(inp); - hashers.emplace_back(HashT(pb, 2*digest_size, inp, (i == 0 ? *computed_root : internal_output[i-1]), - FMT(this->annotation_prefix, " load_hashers_%zu", i))); - } - - for (size_t i = 0; i < tree_depth; ++i) - { - /* - The propagators take a computed hash value (or leaf in the - base case) and propagate it one layer up, either in the left - or the right slot of authentication_path_variable. - */ - propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth - 1 ? internal_output[i] : leaf, - address_bits[tree_depth-1-i], path.left_digests[i], path.right_digests[i], - FMT(this->annotation_prefix, " digest_selector_%zu", i))); - } - - check_root.reset(new bit_vector_copy_gadget(pb, computed_root->bits, root.bits, read_successful, FieldT::capacity(), FMT(annotation_prefix, " check_root"))); -} - -template -void merkle_tree_check_read_gadget::generate_r1cs_constraints() -{ - /* ensure correct hash computations */ - for (size_t i = 0; i < tree_depth; ++i) - { - // Note that we check root outside and have enforced booleanity of path.left_digests/path.right_digests outside in path.generate_r1cs_constraints - hashers[i].generate_r1cs_constraints(false); - } - - /* ensure consistency of path.left_digests/path.right_digests with internal_output */ - for (size_t i = 0; i < tree_depth; ++i) - { - propagators[i].generate_r1cs_constraints(); - } - - check_root->generate_r1cs_constraints(false, false); -} - -template -void merkle_tree_check_read_gadget::generate_r1cs_witness() -{ - /* do the hash computations bottom-up */ - for (int i = tree_depth-1; i >= 0; --i) - { - /* propagate previous input */ - propagators[i].generate_r1cs_witness(); - - /* compute hash */ - hashers[i].generate_r1cs_witness(); - } - - check_root->generate_r1cs_witness(); -} - -template -size_t merkle_tree_check_read_gadget::root_size_in_bits() -{ - return HashT::get_digest_len(); -} - -template -size_t merkle_tree_check_read_gadget::expected_constraints(const size_t tree_depth) -{ - /* NB: this includes path constraints */ - const size_t hasher_constraints = tree_depth * HashT::expected_constraints(false); - const size_t propagator_constraints = tree_depth * HashT::get_digest_len(); - const size_t authentication_path_constraints = 2 * tree_depth * HashT::get_digest_len(); - const size_t check_root_constraints = 3 * div_ceil(HashT::get_digest_len(), FieldT::capacity()); - - return hasher_constraints + propagator_constraints + authentication_path_constraints + check_root_constraints; -} - -template -void test_merkle_tree_check_read_gadget() -{ - /* prepare test */ - const size_t digest_len = HashT::get_digest_len(); - const size_t tree_depth = 16; - std::vector path(tree_depth); - - bit_vector prev_hash(digest_len); - std::generate(prev_hash.begin(), prev_hash.end(), [&]() { return std::rand() % 2; }); - bit_vector leaf = prev_hash; - - bit_vector address_bits; - - size_t address = 0; - for (int64_t level = tree_depth-1; level >= 0; --level) - { - const bool computed_is_right = (std::rand() % 2); - address |= (computed_is_right ? UINT64_C(1) << (tree_depth-1-level) : 0); - address_bits.push_back(computed_is_right); - bit_vector other(digest_len); - std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); - - bit_vector block = prev_hash; - block.insert(computed_is_right ? block.begin() : block.end(), other.begin(), other.end()); - bit_vector h = HashT::get_hash(block); - - path[level] = other; - - prev_hash = h; - } - bit_vector root = prev_hash; - - /* execute test */ - protoboard pb; - pb_variable_array address_bits_va; - address_bits_va.allocate(pb, tree_depth, "address_bits"); - digest_variable leaf_digest(pb, digest_len, "input_block"); - digest_variable root_digest(pb, digest_len, "output_digest"); - merkle_authentication_path_variable path_var(pb, tree_depth, "path_var"); - merkle_tree_check_read_gadget ml(pb, tree_depth, address_bits_va, leaf_digest, root_digest, path_var, ONE, "ml"); - - path_var.generate_r1cs_constraints(); - ml.generate_r1cs_constraints(); - - address_bits_va.fill_with_bits(pb, address_bits); - assert(address_bits_va.get_field_element_from_bits(pb).as_uint64() == address); - leaf_digest.generate_r1cs_witness(leaf); - path_var.generate_r1cs_witness(address, path); - ml.generate_r1cs_witness(); - - /* make sure that read checker didn't accidentally overwrite anything */ - address_bits_va.fill_with_bits(pb, address_bits); - leaf_digest.generate_r1cs_witness(leaf); - root_digest.generate_r1cs_witness(root); - assert(pb.is_satisfied()); - - const size_t num_constraints = pb.num_constraints(); - const size_t expected_constraints = merkle_tree_check_read_gadget::expected_constraints(tree_depth); - assert(num_constraints == expected_constraints); -} - -} // libsnark - -#endif // MERKLE_TREE_CHECK_READ_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp deleted file mode 100644 index 2d6840d61..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for the Merkle tree check read gadget. - - The gadget checks the following: given two roots R1 and R2, address A, two - values V1 and V2, and authentication path P, check that - - P is a valid authentication path for the value V1 as the A-th leaf in a Merkle tree with root R1, and - - P is a valid authentication path for the value V2 as the A-th leaf in a Merkle tree with root R2. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ -#define MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ - -#include "common/data_structures/merkle_tree.hpp" -#include "gadgetlib1/gadget.hpp" -#include "gadgetlib1/gadgets/hashes/crh_gadget.hpp" -#include "gadgetlib1/gadgets/hashes/hash_io.hpp" -#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp" -#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp" - -namespace libsnark { - -template -class merkle_tree_check_update_gadget : public gadget { -private: - - std::vector prev_hashers; - std::vector > prev_hasher_inputs; - std::vector > prev_propagators; - std::vector > prev_internal_output; - - std::vector next_hashers; - std::vector > next_hasher_inputs; - std::vector > next_propagators; - std::vector > next_internal_output; - - std::shared_ptr > computed_next_root; - std::shared_ptr > check_next_root; - -public: - - const size_t digest_size; - const size_t tree_depth; - - pb_variable_array address_bits; - digest_variable prev_leaf_digest; - digest_variable prev_root_digest; - merkle_authentication_path_variable prev_path; - digest_variable next_leaf_digest; - digest_variable next_root_digest; - merkle_authentication_path_variable next_path; - pb_linear_combination update_successful; - - /* Note that while it is necessary to generate R1CS constraints - for prev_path, it is not necessary to do so for next_path. See - comment in the implementation of generate_r1cs_constraints() */ - - merkle_tree_check_update_gadget(protoboard &pb, - const size_t tree_depth, - const pb_variable_array &address_bits, - const digest_variable &prev_leaf_digest, - const digest_variable &prev_root_digest, - const merkle_authentication_path_variable &prev_path, - const digest_variable &next_leaf_digest, - const digest_variable &next_root_digest, - const merkle_authentication_path_variable &next_path, - const pb_linear_combination &update_successful, - const std::string &annotation_prefix); - - void generate_r1cs_constraints(); - void generate_r1cs_witness(); - - static size_t root_size_in_bits(); - /* for debugging purposes */ - static size_t expected_constraints(const size_t tree_depth); -}; - -template -void test_merkle_tree_check_update_gadget(); - -} // libsnark - -#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc" - -#endif // MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc deleted file mode 100644 index 507c7526d..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc +++ /dev/null @@ -1,265 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for the Merkle tree check update gadget. - - See merkle_tree_check_update_gadget.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ -#define MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ - -namespace libsnark { - -template -merkle_tree_check_update_gadget::merkle_tree_check_update_gadget(protoboard &pb, - const size_t tree_depth, - const pb_variable_array &address_bits, - const digest_variable &prev_leaf_digest, - const digest_variable &prev_root_digest, - const merkle_authentication_path_variable &prev_path, - const digest_variable &next_leaf_digest, - const digest_variable &next_root_digest, - const merkle_authentication_path_variable &next_path, - const pb_linear_combination &update_successful, - const std::string &annotation_prefix) : - gadget(pb, annotation_prefix), - digest_size(HashT::get_digest_len()), - tree_depth(tree_depth), - address_bits(address_bits), - prev_leaf_digest(prev_leaf_digest), - prev_root_digest(prev_root_digest), - prev_path(prev_path), - next_leaf_digest(next_leaf_digest), - next_root_digest(next_root_digest), - next_path(next_path), - update_successful(update_successful) -{ - assert(tree_depth > 0); - assert(tree_depth == address_bits.size()); - - for (size_t i = 0; i < tree_depth-1; ++i) - { - prev_internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " prev_internal_output_%zu", i))); - next_internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " next_internal_output_%zu", i))); - } - - computed_next_root.reset(new digest_variable(pb, digest_size, FMT(this->annotation_prefix, " computed_root"))); - - for (size_t i = 0; i < tree_depth; ++i) - { - block_variable prev_inp(pb, prev_path.left_digests[i], prev_path.right_digests[i], FMT(this->annotation_prefix, " prev_inp_%zu", i)); - prev_hasher_inputs.emplace_back(prev_inp); - prev_hashers.emplace_back(HashT(pb, 2*digest_size, prev_inp, (i == 0 ? prev_root_digest : prev_internal_output[i-1]), - FMT(this->annotation_prefix, " prev_hashers_%zu", i))); - - block_variable next_inp(pb, next_path.left_digests[i], next_path.right_digests[i], FMT(this->annotation_prefix, " next_inp_%zu", i)); - next_hasher_inputs.emplace_back(next_inp); - next_hashers.emplace_back(HashT(pb, 2*digest_size, next_inp, (i == 0 ? *computed_next_root : next_internal_output[i-1]), - FMT(this->annotation_prefix, " next_hashers_%zu", i))); - } - - for (size_t i = 0; i < tree_depth; ++i) - { - prev_propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth -1 ? prev_internal_output[i] : prev_leaf_digest, - address_bits[tree_depth-1-i], prev_path.left_digests[i], prev_path.right_digests[i], - FMT(this->annotation_prefix, " prev_propagators_%zu", i))); - next_propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth -1 ? next_internal_output[i] : next_leaf_digest, - address_bits[tree_depth-1-i], next_path.left_digests[i], next_path.right_digests[i], - FMT(this->annotation_prefix, " next_propagators_%zu", i))); - } - - check_next_root.reset(new bit_vector_copy_gadget(pb, computed_next_root->bits, next_root_digest.bits, update_successful, FieldT::capacity(), FMT(annotation_prefix, " check_next_root"))); -} - -template -void merkle_tree_check_update_gadget::generate_r1cs_constraints() -{ - /* ensure correct hash computations */ - for (size_t i = 0; i < tree_depth; ++i) - { - prev_hashers[i].generate_r1cs_constraints(false); // we check root outside and prev_left/prev_right above - next_hashers[i].generate_r1cs_constraints(true); // however we must check right side hashes - } - - /* ensure consistency of internal_left/internal_right with internal_output */ - for (size_t i = 0; i < tree_depth; ++i) - { - prev_propagators[i].generate_r1cs_constraints(); - next_propagators[i].generate_r1cs_constraints(); - } - - /* ensure that prev auxiliary input and next auxiliary input match */ - for (size_t i = 0; i < tree_depth; ++i) - { - for (size_t j = 0; j < digest_size; ++j) - { - /* - addr * (prev_left - next_left) + (1 - addr) * (prev_right - next_right) = 0 - addr * (prev_left - next_left - prev_right + next_right) = next_right - prev_right - */ - this->pb.add_r1cs_constraint(r1cs_constraint(address_bits[tree_depth-1-i], - prev_path.left_digests[i].bits[j] - next_path.left_digests[i].bits[j] - prev_path.right_digests[i].bits[j] + next_path.right_digests[i].bits[j], - next_path.right_digests[i].bits[j] - prev_path.right_digests[i].bits[j]), - FMT(this->annotation_prefix, " aux_check_%zu_%zu", i, j)); - } - } - - /* Note that while it is necessary to generate R1CS constraints - for prev_path, it is not necessary to do so for next_path. - - This holds, because { next_path.left_inputs[i], - next_path.right_inputs[i] } is a pair { hash_output, - auxiliary_input }. The bitness for hash_output is enforced - above by next_hashers[i].generate_r1cs_constraints. - - Because auxiliary input is the same for prev_path and next_path - (enforced above), we have that auxiliary_input part is also - constrained to be boolean, because prev_path is *all* - constrained to be all boolean. */ - - check_next_root->generate_r1cs_constraints(false, false); -} - -template -void merkle_tree_check_update_gadget::generate_r1cs_witness() -{ - /* do the hash computations bottom-up */ - for (int i = tree_depth-1; i >= 0; --i) - { - /* ensure consistency of prev_path and next_path */ - if (this->pb.val(address_bits[tree_depth-1-i]) == FieldT::one()) - { - next_path.left_digests[i].generate_r1cs_witness(prev_path.left_digests[i].get_digest()); - } - else - { - next_path.right_digests[i].generate_r1cs_witness(prev_path.right_digests[i].get_digest()); - } - - /* propagate previous input */ - prev_propagators[i].generate_r1cs_witness(); - next_propagators[i].generate_r1cs_witness(); - - /* compute hash */ - prev_hashers[i].generate_r1cs_witness(); - next_hashers[i].generate_r1cs_witness(); - } - - check_next_root->generate_r1cs_witness(); -} - -template -size_t merkle_tree_check_update_gadget::root_size_in_bits() -{ - return HashT::get_digest_len(); -} - -template -size_t merkle_tree_check_update_gadget::expected_constraints(const size_t tree_depth) -{ - /* NB: this includes path constraints */ - const size_t prev_hasher_constraints = tree_depth * HashT::expected_constraints(false); - const size_t next_hasher_constraints = tree_depth * HashT::expected_constraints(true); - const size_t prev_authentication_path_constraints = 2 * tree_depth * HashT::get_digest_len(); - const size_t prev_propagator_constraints = tree_depth * HashT::get_digest_len(); - const size_t next_propagator_constraints = tree_depth * HashT::get_digest_len(); - const size_t check_next_root_constraints = 3 * div_ceil(HashT::get_digest_len(), FieldT::capacity()); - const size_t aux_equality_constraints = tree_depth * HashT::get_digest_len(); - - return (prev_hasher_constraints + next_hasher_constraints + prev_authentication_path_constraints + - prev_propagator_constraints + next_propagator_constraints + check_next_root_constraints + - aux_equality_constraints); -} - -template -void test_merkle_tree_check_update_gadget() -{ - /* prepare test */ - const size_t digest_len = HashT::get_digest_len(); - - const size_t tree_depth = 16; - std::vector prev_path(tree_depth); - - bit_vector prev_load_hash(digest_len); - std::generate(prev_load_hash.begin(), prev_load_hash.end(), [&]() { return std::rand() % 2; }); - bit_vector prev_store_hash(digest_len); - std::generate(prev_store_hash.begin(), prev_store_hash.end(), [&]() { return std::rand() % 2; }); - - bit_vector loaded_leaf = prev_load_hash; - bit_vector stored_leaf = prev_store_hash; - - bit_vector address_bits; - - size_t address = 0; - for (int64_t level = tree_depth-1; level >= 0; --level) - { - const bool computed_is_right = (std::rand() % 2); - address |= (computed_is_right ? UINT64_C(1) << (tree_depth-1-level) : 0); - address_bits.push_back(computed_is_right); - bit_vector other(digest_len); - std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); - - bit_vector load_block = prev_load_hash; - load_block.insert(computed_is_right ? load_block.begin() : load_block.end(), other.begin(), other.end()); - bit_vector store_block = prev_store_hash; - store_block.insert(computed_is_right ? store_block.begin() : store_block.end(), other.begin(), other.end()); - - bit_vector load_h = HashT::get_hash(load_block); - bit_vector store_h = HashT::get_hash(store_block); - - prev_path[level] = other; - - prev_load_hash = load_h; - prev_store_hash = store_h; - } - - bit_vector load_root = prev_load_hash; - bit_vector store_root = prev_store_hash; - - /* execute the test */ - protoboard pb; - pb_variable_array address_bits_va; - address_bits_va.allocate(pb, tree_depth, "address_bits"); - digest_variable prev_leaf_digest(pb, digest_len, "prev_leaf_digest"); - digest_variable prev_root_digest(pb, digest_len, "prev_root_digest"); - merkle_authentication_path_variable prev_path_var(pb, tree_depth, "prev_path_var"); - digest_variable next_leaf_digest(pb, digest_len, "next_leaf_digest"); - digest_variable next_root_digest(pb, digest_len, "next_root_digest"); - merkle_authentication_path_variable next_path_var(pb, tree_depth, "next_path_var"); - merkle_tree_check_update_gadget mls(pb, tree_depth, address_bits_va, - prev_leaf_digest, prev_root_digest, prev_path_var, - next_leaf_digest, next_root_digest, next_path_var, ONE, "mls"); - - prev_path_var.generate_r1cs_constraints(); - mls.generate_r1cs_constraints(); - - address_bits_va.fill_with_bits(pb, address_bits); - assert(address_bits_va.get_field_element_from_bits(pb).as_uint64() == address); - prev_leaf_digest.generate_r1cs_witness(loaded_leaf); - prev_path_var.generate_r1cs_witness(address, prev_path); - next_leaf_digest.generate_r1cs_witness(stored_leaf); - address_bits_va.fill_with_bits(pb, address_bits); - mls.generate_r1cs_witness(); - - /* make sure that update check will check for the right things */ - prev_leaf_digest.generate_r1cs_witness(loaded_leaf); - next_leaf_digest.generate_r1cs_witness(stored_leaf); - prev_root_digest.generate_r1cs_witness(load_root); - next_root_digest.generate_r1cs_witness(store_root); - address_bits_va.fill_with_bits(pb, address_bits); - assert(pb.is_satisfied()); - - const size_t num_constraints = pb.num_constraints(); - const size_t expected_constraints = merkle_tree_check_update_gadget::expected_constraints(tree_depth); - assert(num_constraints == expected_constraints); -} - -} // libsnark - -#endif // MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp deleted file mode 100644 index 8d52c579b..000000000 --- a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifdef CURVE_BN128 -#include "algebra/curves/bn128/bn128_pp.hpp" -#endif -#include "algebra/curves/edwards/edwards_pp.hpp" -#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" -#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" -#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp" -#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" - -using namespace libsnark; - -template -void test_all_merkle_tree_gadgets() -{ - typedef Fr FieldT; - test_merkle_tree_check_read_gadget >(); - test_merkle_tree_check_read_gadget >(); - - test_merkle_tree_check_update_gadget >(); - test_merkle_tree_check_update_gadget >(); -} - -int main(void) -{ - start_profiling(); - -#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled - bn128_pp::init_public_params(); - test_all_merkle_tree_gadgets(); -#endif - - edwards_pp::init_public_params(); - test_all_merkle_tree_gadgets(); - - mnt4_pp::init_public_params(); - test_all_merkle_tree_gadgets(); - - mnt6_pp::init_public_params(); - test_all_merkle_tree_gadgets(); -} diff --git a/src/snark/libsnark/gadgetlib1/pb_variable.hpp b/src/snark/libsnark/gadgetlib1/pb_variable.hpp deleted file mode 100644 index caa44cec1..000000000 --- a/src/snark/libsnark/gadgetlib1/pb_variable.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PB_VARIABLE_HPP_ -#define PB_VARIABLE_HPP_ - -#include -#include -#include -#include "common/utils.hpp" -#include "relations/variable.hpp" - -namespace libsnark { - -typedef size_t lc_index_t; - -template -class protoboard; - -template -class pb_variable : public variable { -public: - pb_variable(const var_index_t index = 0) : variable(index) {}; - - void allocate(protoboard &pb, const std::string &annotation=""); -}; - -template -class pb_variable_array : private std::vector > -{ - typedef std::vector > contents; -public: - using typename contents::iterator; - using typename contents::const_iterator; - using typename contents::reverse_iterator; - using typename contents::const_reverse_iterator; - - using contents::begin; - using contents::end; - using contents::rbegin; - using contents::rend; - using contents::emplace_back; - using contents::insert; - using contents::reserve; - using contents::size; - using contents::empty; - using contents::operator[]; - using contents::resize; - - pb_variable_array() : contents() {}; - pb_variable_array(size_t count, const pb_variable &value) : contents(count, value) {}; - pb_variable_array(typename contents::const_iterator first, typename contents::const_iterator last) : contents(first, last) {}; - pb_variable_array(typename contents::const_reverse_iterator first, typename contents::const_reverse_iterator last) : contents(first, last) {}; - void allocate(protoboard &pb, const size_t n, const std::string &annotation_prefix=""); - - void fill_with_field_elements(protoboard &pb, const std::vector& vals) const; - void fill_with_bits(protoboard &pb, const bit_vector& bits) const; - void fill_with_bits_of_uint64(protoboard &pb, const uint64_t i) const; - void fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const; - - std::vector get_vals(const protoboard &pb) const; - bit_vector get_bits(const protoboard &pb) const; - - FieldT get_field_element_from_bits(const protoboard &pb) const; -}; - -/* index 0 corresponds to the constant term (used in legacy code) */ -#define ONE pb_variable(0) - -template -class pb_linear_combination : public linear_combination { -public: - bool is_variable; - lc_index_t index; - - pb_linear_combination(); - pb_linear_combination(const pb_variable &var); - - void assign(protoboard &pb, const linear_combination &lc); - void evaluate(protoboard &pb) const; - - bool is_constant() const; - FieldT constant_term() const; -}; - -template -class pb_linear_combination_array : private std::vector > -{ - typedef std::vector > contents; -public: - using typename contents::iterator; - using typename contents::const_iterator; - using typename contents::reverse_iterator; - using typename contents::const_reverse_iterator; - - using contents::begin; - using contents::end; - using contents::rbegin; - using contents::rend; - using contents::emplace_back; - using contents::insert; - using contents::reserve; - using contents::size; - using contents::empty; - using contents::operator[]; - using contents::resize; - - pb_linear_combination_array() : contents() {}; - pb_linear_combination_array(const pb_variable_array &arr) { for (auto &v : arr) this->emplace_back(pb_linear_combination(v)); }; - pb_linear_combination_array(size_t count) : contents(count) {}; - pb_linear_combination_array(size_t count, const pb_linear_combination &value) : contents(count, value) {}; - pb_linear_combination_array(typename contents::const_iterator first, typename contents::const_iterator last) : contents(first, last) {}; - pb_linear_combination_array(typename contents::const_reverse_iterator first, typename contents::const_reverse_iterator last) : contents(first, last) {}; - - void evaluate(protoboard &pb) const; - - void fill_with_field_elements(protoboard &pb, const std::vector& vals) const; - void fill_with_bits(protoboard &pb, const bit_vector& bits) const; - void fill_with_bits_of_uint64(protoboard &pb, const uint64_t i) const; - void fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const; - - std::vector get_vals(const protoboard &pb) const; - bit_vector get_bits(const protoboard &pb) const; - - FieldT get_field_element_from_bits(const protoboard &pb) const; -}; - -template -linear_combination pb_sum(const pb_linear_combination_array &v); - -template -linear_combination pb_packing_sum(const pb_linear_combination_array &v); - -template -linear_combination pb_coeff_sum(const pb_linear_combination_array &v, const std::vector &coeffs); - -} // libsnark -#include "gadgetlib1/pb_variable.tcc" - -#endif // PB_VARIABLE_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/pb_variable.tcc b/src/snark/libsnark/gadgetlib1/pb_variable.tcc deleted file mode 100644 index b4c6ad4f9..000000000 --- a/src/snark/libsnark/gadgetlib1/pb_variable.tcc +++ /dev/null @@ -1,330 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PB_VARIABLE_TCC_ -#define PB_VARIABLE_TCC_ -#include -#include "gadgetlib1/protoboard.hpp" -#include "common/utils.hpp" - -namespace libsnark { - -template -void pb_variable::allocate(protoboard &pb, const std::string &annotation) -{ - this->index = pb.allocate_var_index(annotation); -} - -/* allocates pb_variable array in MSB->LSB order */ -template -void pb_variable_array::allocate(protoboard &pb, const size_t n, const std::string &annotation_prefix) -{ -#ifdef DEBUG - assert(annotation_prefix != ""); -#endif - (*this).resize(n); - - for (size_t i = 0; i < n; ++i) - { - (*this)[i].allocate(pb, FMT(annotation_prefix, "_%zu", i)); - } -} - -template -void pb_variable_array::fill_with_field_elements(protoboard &pb, const std::vector& vals) const -{ - assert(this->size() == vals.size()); - for (size_t i = 0; i < vals.size(); ++i) - { - pb.val((*this)[i]) = vals[i]; - } -} - -template -void pb_variable_array::fill_with_bits(protoboard &pb, const bit_vector& bits) const -{ - assert(this->size() == bits.size()); - for (size_t i = 0; i < bits.size(); ++i) - { - pb.val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero()); - } -} - -template -void pb_variable_array::fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const -{ - const bigint rint = r.as_bigint(); - for (size_t i = 0; i < this->size(); ++i) - { - pb.val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero(); - } -} - -template -void pb_variable_array::fill_with_bits_of_uint64(protoboard &pb, const uint64_t i) const -{ - this->fill_with_bits_of_field_element(pb, FieldT(i, true)); -} - -template -std::vector pb_variable_array::get_vals(const protoboard &pb) const -{ - std::vector result(this->size()); - for (size_t i = 0; i < this->size(); ++i) - { - result[i] = pb.val((*this)[i]); - } - return result; -} - -template -bit_vector pb_variable_array::get_bits(const protoboard &pb) const -{ - bit_vector result; - for (size_t i = 0; i < this->size(); ++i) - { - const FieldT v = pb.val((*this)[i]); - assert(v == FieldT::zero() || v == FieldT::one()); - result.push_back(v == FieldT::one()); - } - return result; -} - -template -FieldT pb_variable_array::get_field_element_from_bits(const protoboard &pb) const -{ - FieldT result = FieldT::zero(); - - for (size_t i = 0; i < this->size(); ++i) - { - /* push in the new bit */ - const FieldT v = pb.val((*this)[this->size()-1-i]); - assert(v == FieldT::zero() || v == FieldT::one()); - result += result + v; - } - - return result; -} - -template -pb_linear_combination::pb_linear_combination() -{ - this->is_variable = false; - this->index = 0; -} - -template -pb_linear_combination::pb_linear_combination(const pb_variable &var) -{ - this->is_variable = true; - this->index = var.index; - this->terms.emplace_back(linear_term(var)); -} - -template -void pb_linear_combination::assign(protoboard &pb, const linear_combination &lc) -{ - assert(this->is_variable == false); - this->index = pb.allocate_lc_index(); - this->terms = lc.terms; -} - -template -void pb_linear_combination::evaluate(protoboard &pb) const -{ - if (this->is_variable) - { - return; // do nothing - } - - FieldT sum = 0; - for (auto term : this->terms) - { - sum += term.coeff * pb.val(pb_variable(term.index)); - } - - pb.lc_val(*this) = sum; -} - -template -bool pb_linear_combination::is_constant() const -{ - if (is_variable) - { - return (index == 0); - } - else - { - for (auto term : this->terms) - { - if (term.index != 0) - { - return false; - } - } - - return true; - } -} - -template -FieldT pb_linear_combination::constant_term() const -{ - if (is_variable) - { - return (index == 0 ? FieldT::one() : FieldT::zero()); - } - else - { - FieldT result = FieldT::zero(); - for (auto term : this->terms) - { - if (term.index == 0) - { - result += term.coeff; - } - } - return result; - } -} - -template -void pb_linear_combination_array::evaluate(protoboard &pb) const -{ - for (size_t i = 0; i < this->size(); ++i) - { - (*this)[i].evaluate(pb); - } -} - -template -void pb_linear_combination_array::fill_with_field_elements(protoboard &pb, const std::vector& vals) const -{ - assert(this->size() == vals.size()); - for (size_t i = 0; i < vals.size(); ++i) - { - pb.lc_val((*this)[i]) = vals[i]; - } -} - -template -void pb_linear_combination_array::fill_with_bits(protoboard &pb, const bit_vector& bits) const -{ - assert(this->size() == bits.size()); - for (size_t i = 0; i < bits.size(); ++i) - { - pb.lc_val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero()); - } -} - -template -void pb_linear_combination_array::fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const -{ - const bigint rint = r.as_bigint(); - for (size_t i = 0; i < this->size(); ++i) - { - pb.lc_val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero(); - } -} - -template -void pb_linear_combination_array::fill_with_bits_of_uint64(protoboard &pb, const uint64_t i) const -{ - this->fill_with_bits_of_field_element(pb, FieldT(i)); -} - -template -std::vector pb_linear_combination_array::get_vals(const protoboard &pb) const -{ - std::vector result(this->size()); - for (size_t i = 0; i < this->size(); ++i) - { - result[i] = pb.lc_val((*this)[i]); - } - return result; -} - -template -bit_vector pb_linear_combination_array::get_bits(const protoboard &pb) const -{ - bit_vector result; - for (size_t i = 0; i < this->size(); ++i) - { - const FieldT v = pb.lc_val((*this)[i]); - assert(v == FieldT::zero() || v == FieldT::one()); - result.push_back(v == FieldT::one()); - } - return result; -} - -template -FieldT pb_linear_combination_array::get_field_element_from_bits(const protoboard &pb) const -{ - FieldT result = FieldT::zero(); - - for (size_t i = 0; i < this->size(); ++i) - { - /* push in the new bit */ - const FieldT v = pb.lc_val((*this)[this->size()-1-i]); - assert(v == FieldT::zero() || v == FieldT::one()); - result += result + v; - } - - return result; -} - -template -linear_combination pb_sum(const pb_linear_combination_array &v) -{ - linear_combination result; - for (auto &term : v) - { - result = result + term; - } - - return result; -} - -template -linear_combination pb_packing_sum(const pb_linear_combination_array &v) -{ - FieldT twoi = FieldT::one(); // will hold 2^i entering each iteration - std::vector > all_terms; - for (auto &lc : v) - { - for (auto &term : lc.terms) - { - all_terms.emplace_back(twoi * term); - } - twoi += twoi; - } - - return linear_combination(all_terms); -} - -template -linear_combination pb_coeff_sum(const pb_linear_combination_array &v, const std::vector &coeffs) -{ - assert(v.size() == coeffs.size()); - std::vector > all_terms; - - auto coeff_it = coeffs.begin(); - for (auto &lc : v) - { - for (auto &term : lc.terms) - { - all_terms.emplace_back((*coeff_it) * term); - } - ++coeff_it; - } - - return linear_combination(all_terms); -} - - -} // libsnark -#endif // PB_VARIABLE_TCC diff --git a/src/snark/libsnark/gadgetlib1/protoboard.hpp b/src/snark/libsnark/gadgetlib1/protoboard.hpp deleted file mode 100644 index a910a6df9..000000000 --- a/src/snark/libsnark/gadgetlib1/protoboard.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PROTOBOARD_HPP_ -#define PROTOBOARD_HPP_ - -#include -#include -#include -#include -#include -#include "gadgetlib1/pb_variable.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" -#include "common/utils.hpp" - -namespace libsnark { - -template -class r1cs_constraint; - -template -class r1cs_constraint_system; - -template -class protoboard { -private: - FieldT constant_term; /* only here, because pb.val() needs to be able to return reference to the constant 1 term */ - r1cs_variable_assignment values; /* values[0] will hold the value of the first allocated variable of the protoboard, *NOT* constant 1 */ - var_index_t next_free_var; - lc_index_t next_free_lc; - std::vector lc_values; -public: - r1cs_constraint_system constraint_system; - - protoboard(); - - void clear_values(); - - FieldT& val(const pb_variable &var); - FieldT val(const pb_variable &var) const; - - FieldT& lc_val(const pb_linear_combination &lc); - FieldT lc_val(const pb_linear_combination &lc) const; - - void add_r1cs_constraint(const r1cs_constraint &constr, const std::string &annotation=""); - void augment_variable_annotation(const pb_variable &v, const std::string &postfix); - bool is_satisfied() const; - void dump_variables() const; - - size_t num_constraints() const; - size_t num_inputs() const; - size_t num_variables() const; - - void set_input_sizes(const size_t primary_input_size); - - r1cs_variable_assignment full_variable_assignment() const; - r1cs_primary_input primary_input() const; - r1cs_auxiliary_input auxiliary_input() const; - r1cs_constraint_system get_constraint_system() const; - - friend class pb_variable; - friend class pb_linear_combination; - -private: - var_index_t allocate_var_index(const std::string &annotation=""); - lc_index_t allocate_lc_index(); -}; - -} // libsnark -#include "gadgetlib1/protoboard.tcc" -#endif // PROTOBOARD_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/protoboard.tcc b/src/snark/libsnark/gadgetlib1/protoboard.tcc deleted file mode 100644 index 882af28e6..000000000 --- a/src/snark/libsnark/gadgetlib1/protoboard.tcc +++ /dev/null @@ -1,189 +0,0 @@ -/** @file - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef PROTOBOARD_TCC_ -#define PROTOBOARD_TCC_ - -#include -#include -#include "common/profiling.hpp" - -namespace libsnark { - -template -protoboard::protoboard() -{ - constant_term = FieldT::one(); - -#ifdef DEBUG - constraint_system.variable_annotations[0] = "ONE"; -#endif - - next_free_var = 1; /* to account for constant 1 term */ - next_free_lc = 0; -} - -template -void protoboard::clear_values() -{ - std::fill(values.begin(), values.end(), FieldT::zero()); -} - -template -var_index_t protoboard::allocate_var_index(const std::string &annotation) -{ -#ifdef DEBUG - assert(annotation != ""); - constraint_system.variable_annotations[next_free_var] = annotation; -#else - UNUSED(annotation); -#endif - ++constraint_system.auxiliary_input_size; - values.emplace_back(FieldT::zero()); - return next_free_var++; -} - -template -lc_index_t protoboard::allocate_lc_index() -{ - lc_values.emplace_back(FieldT::zero()); - return next_free_lc++; -} - -template -FieldT& protoboard::val(const pb_variable &var) -{ - assert(var.index <= values.size()); - return (var.index == 0 ? constant_term : values[var.index-1]); -} - -template -FieldT protoboard::val(const pb_variable &var) const -{ - assert(var.index <= values.size()); - return (var.index == 0 ? constant_term : values[var.index-1]); -} - -template -FieldT& protoboard::lc_val(const pb_linear_combination &lc) -{ - if (lc.is_variable) - { - return this->val(pb_variable(lc.index)); - } - else - { - assert(lc.index < lc_values.size()); - return lc_values[lc.index]; - } -} - -template -FieldT protoboard::lc_val(const pb_linear_combination &lc) const -{ - if (lc.is_variable) - { - return this->val(pb_variable(lc.index)); - } - else - { - assert(lc.index < lc_values.size()); - return lc_values[lc.index]; - } -} - -template -void protoboard::add_r1cs_constraint(const r1cs_constraint &constr, const std::string &annotation) -{ -#ifdef DEBUG - assert(annotation != ""); - constraint_system.constraint_annotations[constraint_system.constraints.size()] = annotation; -#else - UNUSED(annotation); -#endif - constraint_system.constraints.emplace_back(constr); -} - -template -void protoboard::augment_variable_annotation(const pb_variable &v, const std::string &postfix) -{ -#ifdef DEBUG - auto it = constraint_system.variable_annotations.find(v.index); - constraint_system.variable_annotations[v.index] = (it == constraint_system.variable_annotations.end() ? "" : it->second + " ") + postfix; -#endif -} - -template -bool protoboard::is_satisfied() const -{ - return constraint_system.is_satisfied(primary_input(), auxiliary_input()); -} - -template -void protoboard::dump_variables() const -{ -#ifdef DEBUG - for (size_t i = 0; i < constraint_system.num_variables; ++i) - { - printf("%-40s --> ", constraint_system.variable_annotations[i].c_str()); - values[i].as_bigint().print_hex(); - } -#endif -} - -template -size_t protoboard::num_constraints() const -{ - return constraint_system.num_constraints(); -} - -template -size_t protoboard::num_inputs() const -{ - return constraint_system.num_inputs(); -} - -template -size_t protoboard::num_variables() const -{ - return next_free_var - 1; -} - -template -void protoboard::set_input_sizes(const size_t primary_input_size) -{ - assert(primary_input_size <= num_variables()); - constraint_system.primary_input_size = primary_input_size; - constraint_system.auxiliary_input_size = num_variables() - primary_input_size; -} - -template -r1cs_variable_assignment protoboard::full_variable_assignment() const -{ - return values; -} - -template -r1cs_primary_input protoboard::primary_input() const -{ - return r1cs_primary_input(values.begin(), values.begin() + num_inputs()); -} - -template -r1cs_auxiliary_input protoboard::auxiliary_input() const -{ - return r1cs_primary_input(values.begin() + num_inputs(), values.end()); -} - -template -r1cs_constraint_system protoboard::get_constraint_system() const -{ - return constraint_system; -} - -} // libsnark -#endif // PROTOBOARD_TCC_ diff --git a/src/snark/libsnark/gtests.cpp b/src/snark/libsnark/gtests.cpp deleted file mode 100644 index 74c66bdad..000000000 --- a/src/snark/libsnark/gtests.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include "common/profiling.hpp" - -int main(int argc, char **argv) { - libsnark::inhibit_profiling_info = true; - libsnark::inhibit_profiling_counters = true; - - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - diff --git a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp deleted file mode 100644 index b3cde710c..000000000 --- a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp +++ /dev/null @@ -1,70 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a R1CS-to-QAP reduction, that is, constructing - a QAP ("Quadratic Arithmetic Program") from a R1CS ("Rank-1 Constraint System"). - - QAPs are defined in \[GGPR13], and construced for R1CS also in \[GGPR13]. - - The implementation of the reduction follows, extends, and optimizes - the efficient approach described in Appendix E of \[BCGTV13]. - - References: - - \[BCGTV13] - "SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge", - Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, Madars Virza, - CRYPTO 2013, - - - \[GGPR13]: - "Quadratic span programs and succinct NIZKs without PCPs", - Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, - EUROCRYPT 2013, - - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_TO_QAP_HPP_ -#define R1CS_TO_QAP_HPP_ - -#include "relations/arithmetic_programs/qap/qap.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" - -namespace libsnark { - -/** - * Instance map for the R1CS-to-QAP reduction. - */ -template -qap_instance r1cs_to_qap_instance_map(const r1cs_constraint_system &cs); - -/** - * Instance map for the R1CS-to-QAP reduction followed by evaluation of the resulting QAP instance. - */ -template -qap_instance_evaluation r1cs_to_qap_instance_map_with_evaluation(const r1cs_constraint_system &cs, - const FieldT &t); - -/** - * Witness map for the R1CS-to-QAP reduction. - * - * The witness map takes zero knowledge into account when d1,d2,d3 are random. - */ -template -qap_witness r1cs_to_qap_witness_map(const r1cs_constraint_system &cs, - const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3); - -} // libsnark - -#include "reductions/r1cs_to_qap/r1cs_to_qap.tcc" - -#endif // R1CS_TO_QAP_HPP_ diff --git a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc deleted file mode 100644 index 3d0bee273..000000000 --- a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc +++ /dev/null @@ -1,338 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for a R1CS-to-QAP reduction. - - See r1cs_to_qap.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_TO_QAP_TCC_ -#define R1CS_TO_QAP_TCC_ - -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "algebra/evaluation_domain/evaluation_domain.hpp" - -namespace libsnark { - -/** - * Instance map for the R1CS-to-QAP reduction. - * - * Namely, given a R1CS constraint system cs, construct a QAP instance for which: - * A := (A_0(z),A_1(z),...,A_m(z)) - * B := (B_0(z),B_1(z),...,B_m(z)) - * C := (C_0(z),C_1(z),...,C_m(z)) - * where - * m = number of variables of the QAP - * and - * each A_i,B_i,C_i is expressed in the Lagrange basis. - */ -template -qap_instance r1cs_to_qap_instance_map(const r1cs_constraint_system &cs) -{ - enter_block("Call to r1cs_to_qap_instance_map"); - - const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); - - std::vector > A_in_Lagrange_basis(cs.num_variables()+1); - std::vector > B_in_Lagrange_basis(cs.num_variables()+1); - std::vector > C_in_Lagrange_basis(cs.num_variables()+1); - - enter_block("Compute polynomials A, B, C in Lagrange basis"); - /** - * add and process the constraints - * input_i * 0 = 0 - * to ensure soundness of input consistency - */ - for (size_t i = 0; i <= cs.num_inputs(); ++i) - { - A_in_Lagrange_basis[i][cs.num_constraints() + i] = FieldT::one(); - } - /* process all other constraints */ - for (size_t i = 0; i < cs.num_constraints(); ++i) - { - for (size_t j = 0; j < cs.constraints[i].a.terms.size(); ++j) - { - A_in_Lagrange_basis[cs.constraints[i].a.terms[j].index][i] += - cs.constraints[i].a.terms[j].coeff; - } - - for (size_t j = 0; j < cs.constraints[i].b.terms.size(); ++j) - { - B_in_Lagrange_basis[cs.constraints[i].b.terms[j].index][i] += - cs.constraints[i].b.terms[j].coeff; - } - - for (size_t j = 0; j < cs.constraints[i].c.terms.size(); ++j) - { - C_in_Lagrange_basis[cs.constraints[i].c.terms[j].index][i] += - cs.constraints[i].c.terms[j].coeff; - } - } - leave_block("Compute polynomials A, B, C in Lagrange basis"); - - leave_block("Call to r1cs_to_qap_instance_map"); - - return qap_instance(domain, - cs.num_variables(), - domain->m, - cs.num_inputs(), - std::move(A_in_Lagrange_basis), - std::move(B_in_Lagrange_basis), - std::move(C_in_Lagrange_basis)); -} - -/** - * Instance map for the R1CS-to-QAP reduction followed by evaluation of the resulting QAP instance. - * - * Namely, given a R1CS constraint system cs and a field element t, construct - * a QAP instance (evaluated at t) for which: - * At := (A_0(t),A_1(t),...,A_m(t)) - * Bt := (B_0(t),B_1(t),...,B_m(t)) - * Ct := (C_0(t),C_1(t),...,C_m(t)) - * Ht := (1,t,t^2,...,t^n) - * Zt := Z(t) = "vanishing polynomial of a certain set S, evaluated at t" - * where - * m = number of variables of the QAP - * n = degree of the QAP - */ -template -qap_instance_evaluation r1cs_to_qap_instance_map_with_evaluation(const r1cs_constraint_system &cs, - const FieldT &t) -{ - enter_block("Call to r1cs_to_qap_instance_map_with_evaluation"); - - const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); - - std::vector At, Bt, Ct, Ht; - - At.resize(cs.num_variables()+1, FieldT::zero()); - Bt.resize(cs.num_variables()+1, FieldT::zero()); - Ct.resize(cs.num_variables()+1, FieldT::zero()); - Ht.reserve(domain->m+1); - - const FieldT Zt = domain->compute_Z(t); - - enter_block("Compute evaluations of A, B, C, H at t"); - const std::vector u = domain->lagrange_coeffs(t); - /** - * add and process the constraints - * input_i * 0 = 0 - * to ensure soundness of input consistency - */ - for (size_t i = 0; i <= cs.num_inputs(); ++i) - { - At[i] = u[cs.num_constraints() + i]; - } - /* process all other constraints */ - for (size_t i = 0; i < cs.num_constraints(); ++i) - { - for (size_t j = 0; j < cs.constraints[i].a.terms.size(); ++j) - { - At[cs.constraints[i].a.terms[j].index] += - u[i]*cs.constraints[i].a.terms[j].coeff; - } - - for (size_t j = 0; j < cs.constraints[i].b.terms.size(); ++j) - { - Bt[cs.constraints[i].b.terms[j].index] += - u[i]*cs.constraints[i].b.terms[j].coeff; - } - - for (size_t j = 0; j < cs.constraints[i].c.terms.size(); ++j) - { - Ct[cs.constraints[i].c.terms[j].index] += - u[i]*cs.constraints[i].c.terms[j].coeff; - } - } - - FieldT ti = FieldT::one(); - for (size_t i = 0; i < domain->m+1; ++i) - { - Ht.emplace_back(ti); - ti *= t; - } - leave_block("Compute evaluations of A, B, C, H at t"); - - leave_block("Call to r1cs_to_qap_instance_map_with_evaluation"); - - return qap_instance_evaluation(domain, - cs.num_variables(), - domain->m, - cs.num_inputs(), - t, - std::move(At), - std::move(Bt), - std::move(Ct), - std::move(Ht), - Zt); -} - -/** - * Witness map for the R1CS-to-QAP reduction. - * - * The witness map takes zero knowledge into account when d1,d2,d3 are random. - * - * More precisely, compute the coefficients - * h_0,h_1,...,h_n - * of the polynomial - * H(z) := (A(z)*B(z)-C(z))/Z(z) - * where - * A(z) := A_0(z) + \sum_{k=1}^{m} w_k A_k(z) + d1 * Z(z) - * B(z) := B_0(z) + \sum_{k=1}^{m} w_k B_k(z) + d2 * Z(z) - * C(z) := C_0(z) + \sum_{k=1}^{m} w_k C_k(z) + d3 * Z(z) - * Z(z) := "vanishing polynomial of set S" - * and - * m = number of variables of the QAP - * n = degree of the QAP - * - * This is done as follows: - * (1) compute evaluations of A,B,C on S = {sigma_1,...,sigma_n} - * (2) compute coefficients of A,B,C - * (3) compute evaluations of A,B,C on T = "coset of S" - * (4) compute evaluation of H on T - * (5) compute coefficients of H - * (6) patch H to account for d1,d2,d3 (i.e., add coefficients of the polynomial (A d2 + B d1 - d3) + d1*d2*Z ) - * - * The code below is not as simple as the above high-level description due to - * some reshuffling to save space. - */ -template -qap_witness r1cs_to_qap_witness_map(const r1cs_constraint_system &cs, - const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3) -{ - enter_block("Call to r1cs_to_qap_witness_map"); - - /* sanity check */ - assert(cs.is_satisfied(primary_input, auxiliary_input)); - - const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); - - r1cs_variable_assignment full_variable_assignment = primary_input; - full_variable_assignment.insert(full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end()); - - enter_block("Compute evaluation of polynomials A, B on set S"); - std::vector aA(domain->m, FieldT::zero()), aB(domain->m, FieldT::zero()); - - /* account for the additional constraints input_i * 0 = 0 */ - for (size_t i = 0; i <= cs.num_inputs(); ++i) - { - aA[i+cs.num_constraints()] = (i > 0 ? full_variable_assignment[i-1] : FieldT::one()); - } - /* account for all other constraints */ - for (size_t i = 0; i < cs.num_constraints(); ++i) - { - aA[i] += cs.constraints[i].a.evaluate(full_variable_assignment); - aB[i] += cs.constraints[i].b.evaluate(full_variable_assignment); - } - leave_block("Compute evaluation of polynomials A, B on set S"); - - enter_block("Compute coefficients of polynomial A"); - domain->iFFT(aA); - leave_block("Compute coefficients of polynomial A"); - - enter_block("Compute coefficients of polynomial B"); - domain->iFFT(aB); - leave_block("Compute coefficients of polynomial B"); - - enter_block("Compute ZK-patch"); - std::vector coefficients_for_H(domain->m+1, FieldT::zero()); -#ifdef MULTICORE -#pragma omp parallel for -#endif - /* add coefficients of the polynomial (d2*A + d1*B - d3) + d1*d2*Z */ - for (size_t i = 0; i < domain->m; ++i) - { - coefficients_for_H[i] = d2*aA[i] + d1*aB[i]; - } - coefficients_for_H[0] -= d3; - domain->add_poly_Z(d1*d2, coefficients_for_H); - leave_block("Compute ZK-patch"); - - enter_block("Compute evaluation of polynomial A on set T"); - domain->cosetFFT(aA, FieldT::multiplicative_generator); - leave_block("Compute evaluation of polynomial A on set T"); - - enter_block("Compute evaluation of polynomial B on set T"); - domain->cosetFFT(aB, FieldT::multiplicative_generator); - leave_block("Compute evaluation of polynomial B on set T"); - - enter_block("Compute evaluation of polynomial H on set T"); - std::vector &H_tmp = aA; // can overwrite aA because it is not used later -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < domain->m; ++i) - { - H_tmp[i] = aA[i]*aB[i]; - } - std::vector().swap(aB); // destroy aB - - enter_block("Compute evaluation of polynomial C on set S"); - std::vector aC(domain->m, FieldT::zero()); - for (size_t i = 0; i < cs.num_constraints(); ++i) - { - aC[i] += cs.constraints[i].c.evaluate(full_variable_assignment); - } - leave_block("Compute evaluation of polynomial C on set S"); - - enter_block("Compute coefficients of polynomial C"); - domain->iFFT(aC); - leave_block("Compute coefficients of polynomial C"); - - enter_block("Compute evaluation of polynomial C on set T"); - domain->cosetFFT(aC, FieldT::multiplicative_generator); - leave_block("Compute evaluation of polynomial C on set T"); - -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < domain->m; ++i) - { - H_tmp[i] = (H_tmp[i]-aC[i]); - } - - enter_block("Divide by Z on set T"); - domain->divide_by_Z_on_coset(H_tmp); - leave_block("Divide by Z on set T"); - - leave_block("Compute evaluation of polynomial H on set T"); - - enter_block("Compute coefficients of polynomial H"); - domain->icosetFFT(H_tmp, FieldT::multiplicative_generator); - leave_block("Compute coefficients of polynomial H"); - - enter_block("Compute sum of H and ZK-patch"); -#ifdef MULTICORE -#pragma omp parallel for -#endif - for (size_t i = 0; i < domain->m; ++i) - { - coefficients_for_H[i] += H_tmp[i]; - } - leave_block("Compute sum of H and ZK-patch"); - - leave_block("Call to r1cs_to_qap_witness_map"); - - return qap_witness(cs.num_variables(), - domain->m, - cs.num_inputs(), - d1, - d2, - d3, - full_variable_assignment, - std::move(coefficients_for_H)); -} - -} // libsnark - -#endif // R1CS_TO_QAP_TCC_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp deleted file mode 100644 index 4991d203b..000000000 --- a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp +++ /dev/null @@ -1,193 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a QAP ("Quadratic Arithmetic Program"). - - QAPs are defined in \[GGPR13]. - - References: - - \[GGPR13]: - "Quadratic span programs and succinct NIZKs without PCPs", - Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, - EUROCRYPT 2013, - - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef QAP_HPP_ -#define QAP_HPP_ - -#include "algebra/evaluation_domain/evaluation_domain.hpp" - -namespace libsnark { - -/* forward declaration */ -template -class qap_witness; - -/** - * A QAP instance. - * - * Specifically, the datastructure stores: - * - a choice of domain (corresponding to a certain subset of the field); - * - the number of variables, the degree, and the number of inputs; and - * - coefficients of the A,B,C polynomials in the Lagrange basis. - * - * There is no need to store the Z polynomial because it is uniquely - * determined by the domain (as Z is its vanishing polynomial). - */ -template -class qap_instance { -private: - size_t num_variables_; - size_t degree_; - size_t num_inputs_; - -public: - std::shared_ptr > domain; - - std::vector > A_in_Lagrange_basis; - std::vector > B_in_Lagrange_basis; - std::vector > C_in_Lagrange_basis; - - qap_instance(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const std::vector > &A_in_Lagrange_basis, - const std::vector > &B_in_Lagrange_basis, - const std::vector > &C_in_Lagrange_basis); - - qap_instance(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - std::vector > &&A_in_Lagrange_basis, - std::vector > &&B_in_Lagrange_basis, - std::vector > &&C_in_Lagrange_basis); - - qap_instance(const qap_instance &other) = default; - qap_instance(qap_instance &&other) = default; - qap_instance& operator=(const qap_instance &other) = default; - qap_instance& operator=(qap_instance &&other) = default; - - size_t num_variables() const; - size_t degree() const; - size_t num_inputs() const; - - bool is_satisfied(const qap_witness &witness) const; -}; - -/** - * A QAP instance evaluation is a QAP instance that is evaluated at a field element t. - * - * Specifically, the datastructure stores: - * - a choice of domain (corresponding to a certain subset of the field); - * - the number of variables, the degree, and the number of inputs; - * - a field element t; - * - evaluations of the A,B,C (and Z) polynomials at t; - * - evaluations of all monomials of t; - * - counts about how many of the above evaluations are in fact non-zero. - */ -template -class qap_instance_evaluation { -private: - size_t num_variables_; - size_t degree_; - size_t num_inputs_; -public: - std::shared_ptr > domain; - - FieldT t; - - std::vector At, Bt, Ct, Ht; - - FieldT Zt; - - qap_instance_evaluation(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &t, - const std::vector &At, - const std::vector &Bt, - const std::vector &Ct, - const std::vector &Ht, - const FieldT &Zt); - qap_instance_evaluation(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &t, - std::vector &&At, - std::vector &&Bt, - std::vector &&Ct, - std::vector &&Ht, - const FieldT &Zt); - - qap_instance_evaluation(const qap_instance_evaluation &other) = default; - qap_instance_evaluation(qap_instance_evaluation &&other) = default; - qap_instance_evaluation& operator=(const qap_instance_evaluation &other) = default; - qap_instance_evaluation& operator=(qap_instance_evaluation &&other) = default; - - size_t num_variables() const; - size_t degree() const; - size_t num_inputs() const; - - bool is_satisfied(const qap_witness &witness) const; -}; - -/** - * A QAP witness. - */ -template -class qap_witness { -private: - size_t num_variables_; - size_t degree_; - size_t num_inputs_; - -public: - FieldT d1, d2, d3; - - std::vector coefficients_for_ABCs; - std::vector coefficients_for_H; - - qap_witness(const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3, - const std::vector &coefficients_for_ABCs, - const std::vector &coefficients_for_H); - - qap_witness(const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3, - const std::vector &coefficients_for_ABCs, - std::vector &&coefficients_for_H); - - qap_witness(const qap_witness &other) = default; - qap_witness(qap_witness &&other) = default; - qap_witness& operator=(const qap_witness &other) = default; - qap_witness& operator=(qap_witness &&other) = default; - - size_t num_variables() const; - size_t degree() const; - size_t num_inputs() const; -}; - -} // libsnark - -#include "relations/arithmetic_programs/qap/qap.tcc" - -#endif // QAP_HPP_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc deleted file mode 100644 index a4a3c96a2..000000000 --- a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc +++ /dev/null @@ -1,324 +0,0 @@ -/** @file -***************************************************************************** - -Implementation of interfaces for a QAP ("Quadratic Arithmetic Program"). - -See qap.hpp . - -***************************************************************************** -* @author This file is part of libsnark, developed by SCIPR Lab -* and contributors (see AUTHORS). -* @copyright MIT license (see LICENSE file) -*****************************************************************************/ - -#ifndef QAP_TCC_ -#define QAP_TCC_ - -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "algebra/evaluation_domain/evaluation_domain.hpp" -#include "algebra/scalar_multiplication/multiexp.hpp" - -namespace libsnark { - -template -qap_instance::qap_instance(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const std::vector > &A_in_Lagrange_basis, - const std::vector > &B_in_Lagrange_basis, - const std::vector > &C_in_Lagrange_basis) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - domain(domain), - A_in_Lagrange_basis(A_in_Lagrange_basis), - B_in_Lagrange_basis(B_in_Lagrange_basis), - C_in_Lagrange_basis(C_in_Lagrange_basis) -{ -} - -template -qap_instance::qap_instance(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - std::vector > &&A_in_Lagrange_basis, - std::vector > &&B_in_Lagrange_basis, - std::vector > &&C_in_Lagrange_basis) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - domain(domain), - A_in_Lagrange_basis(std::move(A_in_Lagrange_basis)), - B_in_Lagrange_basis(std::move(B_in_Lagrange_basis)), - C_in_Lagrange_basis(std::move(C_in_Lagrange_basis)) -{ -} - -template -size_t qap_instance::num_variables() const -{ - return num_variables_; -} - -template -size_t qap_instance::degree() const -{ - return degree_; -} - -template -size_t qap_instance::num_inputs() const -{ - return num_inputs_; -} - -template -bool qap_instance::is_satisfied(const qap_witness &witness) const -{ - const FieldT t = FieldT::random_element(); - - std::vector At(this->num_variables()+1, FieldT::zero()); - std::vector Bt(this->num_variables()+1, FieldT::zero()); - std::vector Ct(this->num_variables()+1, FieldT::zero()); - std::vector Ht(this->degree()+1); - - const FieldT Zt = this->domain->compute_Z(t); - - const std::vector u = this->domain->lagrange_coeffs(t); - - for (size_t i = 0; i < this->num_variables()+1; ++i) - { - for (auto &el : A_in_Lagrange_basis[i]) - { - At[i] += u[el.first] * el.second; - } - - for (auto &el : B_in_Lagrange_basis[i]) - { - Bt[i] += u[el.first] * el.second; - } - - for (auto &el : C_in_Lagrange_basis[i]) - { - Ct[i] += u[el.first] * el.second; - } - } - - FieldT ti = FieldT::one(); - for (size_t i = 0; i < this->degree()+1; ++i) - { - Ht[i] = ti; - ti *= t; - } - - const qap_instance_evaluation eval_qap_inst(this->domain, - this->num_variables(), - this->degree(), - this->num_inputs(), - t, - std::move(At), - std::move(Bt), - std::move(Ct), - std::move(Ht), - Zt); - return eval_qap_inst.is_satisfied(witness); -} - -template -qap_instance_evaluation::qap_instance_evaluation(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &t, - const std::vector &At, - const std::vector &Bt, - const std::vector &Ct, - const std::vector &Ht, - const FieldT &Zt) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - domain(domain), - t(t), - At(At), - Bt(Bt), - Ct(Ct), - Ht(Ht), - Zt(Zt) -{ -} - -template -qap_instance_evaluation::qap_instance_evaluation(const std::shared_ptr > &domain, - const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &t, - std::vector &&At, - std::vector &&Bt, - std::vector &&Ct, - std::vector &&Ht, - const FieldT &Zt) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - domain(domain), - t(t), - At(std::move(At)), - Bt(std::move(Bt)), - Ct(std::move(Ct)), - Ht(std::move(Ht)), - Zt(Zt) -{ -} - -template -size_t qap_instance_evaluation::num_variables() const -{ - return num_variables_; -} - -template -size_t qap_instance_evaluation::degree() const -{ - return degree_; -} - -template -size_t qap_instance_evaluation::num_inputs() const -{ - return num_inputs_; -} - -template -bool qap_instance_evaluation::is_satisfied(const qap_witness &witness) const -{ - - if (this->num_variables() != witness.num_variables()) - { - return false; - } - - if (this->degree() != witness.degree()) - { - return false; - } - - if (this->num_inputs() != witness.num_inputs()) - { - return false; - } - - if (this->num_variables() != witness.coefficients_for_ABCs.size()) - { - return false; - } - - if (this->degree()+1 != witness.coefficients_for_H.size()) - { - return false; - } - - if (this->At.size() != this->num_variables()+1 || this->Bt.size() != this->num_variables()+1 || this->Ct.size() != this->num_variables()+1) - { - return false; - } - - if (this->Ht.size() != this->degree()+1) - { - return false; - } - - if (this->Zt != this->domain->compute_Z(this->t)) - { - return false; - } - - FieldT ans_A = this->At[0] + witness.d1*this->Zt; - FieldT ans_B = this->Bt[0] + witness.d2*this->Zt; - FieldT ans_C = this->Ct[0] + witness.d3*this->Zt; - FieldT ans_H = FieldT::zero(); - - ans_A = ans_A + naive_plain_exp(this->At.begin()+1, this->At.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_B = ans_B + naive_plain_exp(this->Bt.begin()+1, this->Bt.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_C = ans_C + naive_plain_exp(this->Ct.begin()+1, this->Ct.begin()+1+this->num_variables(), - witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); - ans_H = ans_H + naive_plain_exp(this->Ht.begin(), this->Ht.begin()+this->degree()+1, - witness.coefficients_for_H.begin(), witness.coefficients_for_H.begin()+this->degree()+1); - - if (ans_A * ans_B - ans_C != ans_H * this->Zt) - { - return false; - } - - return true; -} - -template -qap_witness::qap_witness(const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3, - const std::vector &coefficients_for_ABCs, - const std::vector &coefficients_for_H) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - d1(d1), - d2(d2), - d3(d3), - coefficients_for_ABCs(coefficients_for_ABCs), - coefficients_for_H(coefficients_for_H) -{ -} - -template -qap_witness::qap_witness(const size_t num_variables, - const size_t degree, - const size_t num_inputs, - const FieldT &d1, - const FieldT &d2, - const FieldT &d3, - const std::vector &coefficients_for_ABCs, - std::vector &&coefficients_for_H) : - num_variables_(num_variables), - degree_(degree), - num_inputs_(num_inputs), - d1(d1), - d2(d2), - d3(d3), - coefficients_for_ABCs(coefficients_for_ABCs), - coefficients_for_H(std::move(coefficients_for_H)) -{ -} - - -template -size_t qap_witness::num_variables() const -{ - return num_variables_; -} - -template -size_t qap_witness::degree() const -{ - return degree_; -} - -template -size_t qap_witness::num_inputs() const -{ - return num_inputs_; -} - - -} // libsnark - -#endif // QAP_TCC_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp b/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp deleted file mode 100644 index 5dd48d1e0..000000000 --- a/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/** - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include -#include -#include -#include -#include - -#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" -#include "algebra/fields/field_utils.hpp" -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" - -using namespace libsnark; - -template -void test_qap(const size_t qap_degree, const size_t num_inputs, const bool binary_input) -{ - /* - We construct an instance where the QAP degree is qap_degree. - So we generate an instance of R1CS where the number of constraints qap_degree - num_inputs - 1. - See the transformation from R1CS to QAP for why this is the case. - So we need that qap_degree >= num_inputs + 1. - */ - assert(num_inputs + 1 <= qap_degree); - enter_block("Call to test_qap"); - - const size_t num_constraints = qap_degree - num_inputs - 1; - - print_indent(); printf("* QAP degree: %zu\n", qap_degree); - print_indent(); printf("* Number of inputs: %zu\n", num_inputs); - print_indent(); printf("* Number of R1CS constraints: %zu\n", num_constraints); - print_indent(); printf("* Input type: %s\n", binary_input ? "binary" : "field"); - - enter_block("Generate constraint system and assignment"); - r1cs_example example; - if (binary_input) - { - example = generate_r1cs_example_with_binary_input(num_constraints, num_inputs); - } - else - { - example = generate_r1cs_example_with_field_input(num_constraints, num_inputs); - } - leave_block("Generate constraint system and assignment"); - - enter_block("Check satisfiability of constraint system"); - assert(example.constraint_system.is_satisfied(example.primary_input, example.auxiliary_input)); - leave_block("Check satisfiability of constraint system"); - - const FieldT t = FieldT::random_element(), - d1 = FieldT::random_element(), - d2 = FieldT::random_element(), - d3 = FieldT::random_element(); - - enter_block("Compute QAP instance 1"); - qap_instance qap_inst_1 = r1cs_to_qap_instance_map(example.constraint_system); - leave_block("Compute QAP instance 1"); - - enter_block("Compute QAP instance 2"); - qap_instance_evaluation qap_inst_2 = r1cs_to_qap_instance_map_with_evaluation(example.constraint_system, t); - leave_block("Compute QAP instance 2"); - - enter_block("Compute QAP witness"); - qap_witness qap_wit = r1cs_to_qap_witness_map(example.constraint_system, example.primary_input, example.auxiliary_input, d1, d2, d3); - leave_block("Compute QAP witness"); - - enter_block("Check satisfiability of QAP instance 1"); - assert(qap_inst_1.is_satisfied(qap_wit)); - leave_block("Check satisfiability of QAP instance 1"); - - enter_block("Check satisfiability of QAP instance 2"); - assert(qap_inst_2.is_satisfied(qap_wit)); - leave_block("Check satisfiability of QAP instance 2"); - - leave_block("Call to test_qap"); -} - -int main() -{ - start_profiling(); - - mnt6_pp::init_public_params(); - - const size_t num_inputs = 10; - - const size_t basic_domain_size = UINT64_C(1)< >(UINT64_C(1) << 21, num_inputs, true); - - leave_block("Test QAP with binary input"); - - enter_block("Test QAP with field input"); - - test_qap >(UINT64_C(1) << 21, num_inputs, false); - - leave_block("Test QAP with field input"); -} diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp deleted file mode 100644 index 47003e959..000000000 --- a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a R1CS example, as well as functions to sample - R1CS examples with prescribed parameters (according to some distribution). - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_EXAMPLES_HPP_ -#define R1CS_EXAMPLES_HPP_ - -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" - -namespace libsnark { - -/** - * A R1CS example comprises a R1CS constraint system, R1CS input, and R1CS witness. - */ -template -struct r1cs_example { - r1cs_constraint_system constraint_system; - r1cs_primary_input primary_input; - r1cs_auxiliary_input auxiliary_input; - - r1cs_example() = default; - r1cs_example(const r1cs_example &other) = default; - r1cs_example(const r1cs_constraint_system &constraint_system, - const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input) : - constraint_system(constraint_system), - primary_input(primary_input), - auxiliary_input(auxiliary_input) - {}; - r1cs_example(r1cs_constraint_system &&constraint_system, - r1cs_primary_input &&primary_input, - r1cs_auxiliary_input &&auxiliary_input) : - constraint_system(std::move(constraint_system)), - primary_input(std::move(primary_input)), - auxiliary_input(std::move(auxiliary_input)) - {}; -}; - -/** - * Generate a R1CS example such that: - * - the number of constraints of the R1CS constraint system is num_constraints; - * - the number of variables of the R1CS constraint system is (approximately) num_constraints; - * - the number of inputs of the R1CS constraint system is num_inputs; - * - the R1CS input consists of ``full'' field elements (typically require the whole log|Field| bits to represent). - */ -template -r1cs_example generate_r1cs_example_with_field_input(const size_t num_constraints, - const size_t num_inputs); - -/** - * Generate a R1CS example such that: - * - the number of constraints of the R1CS constraint system is num_constraints; - * - the number of variables of the R1CS constraint system is (approximately) num_constraints; - * - the number of inputs of the R1CS constraint system is num_inputs; - * - the R1CS input consists of binary values (as opposed to ``full'' field elements). - */ -template -r1cs_example generate_r1cs_example_with_binary_input(const size_t num_constraints, - const size_t num_inputs); - -} // libsnark - -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc" - -#endif // R1CS_EXAMPLES_HPP_ diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc deleted file mode 100644 index defa07721..000000000 --- a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc +++ /dev/null @@ -1,164 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of functions to sample R1CS examples with prescribed parameters - (according to some distribution). - - See r1cs_examples.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_EXAMPLES_TCC_ -#define R1CS_EXAMPLES_TCC_ - -#include - -#include "common/utils.hpp" - -namespace libsnark { - -template -r1cs_example generate_r1cs_example_with_field_input(const size_t num_constraints, - const size_t num_inputs) -{ - enter_block("Call to generate_r1cs_example_with_field_input"); - - assert(num_inputs <= num_constraints + 2); - - r1cs_constraint_system cs; - cs.primary_input_size = num_inputs; - cs.auxiliary_input_size = 2 + num_constraints - num_inputs; // TODO: explain this - - r1cs_variable_assignment full_variable_assignment; - FieldT a = FieldT::random_element(); - FieldT b = FieldT::random_element(); - full_variable_assignment.push_back(a); - full_variable_assignment.push_back(b); - - for (size_t i = 0; i < num_constraints-1; ++i) - { - linear_combination A, B, C; - - if (i % 2) - { - // a * b = c - A.add_term(i+1, 1); - B.add_term(i+2, 1); - C.add_term(i+3, 1); - FieldT tmp = a*b; - full_variable_assignment.push_back(tmp); - a = b; b = tmp; - } - else - { - // a + b = c - B.add_term(0, 1); - A.add_term(i+1, 1); - A.add_term(i+2, 1); - C.add_term(i+3, 1); - FieldT tmp = a+b; - full_variable_assignment.push_back(tmp); - a = b; b = tmp; - } - - cs.add_constraint(r1cs_constraint(A, B, C)); - } - - linear_combination A, B, C; - FieldT fin = FieldT::zero(); - for (size_t i = 1; i < cs.num_variables(); ++i) - { - A.add_term(i, 1); - B.add_term(i, 1); - fin = fin + full_variable_assignment[i-1]; - } - C.add_term(cs.num_variables(), 1); - cs.add_constraint(r1cs_constraint(A, B, C)); - full_variable_assignment.push_back(fin.squared()); - - /* split variable assignment */ - r1cs_primary_input primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + num_inputs); - r1cs_primary_input auxiliary_input(full_variable_assignment.begin() + num_inputs, full_variable_assignment.end()); - - /* sanity checks */ - assert(cs.num_variables() == full_variable_assignment.size()); - assert(cs.num_variables() >= num_inputs); - assert(cs.num_inputs() == num_inputs); - assert(cs.num_constraints() == num_constraints); - assert(cs.is_satisfied(primary_input, auxiliary_input)); - - leave_block("Call to generate_r1cs_example_with_field_input"); - - return r1cs_example(std::move(cs), std::move(primary_input), std::move(auxiliary_input)); -} - -template -r1cs_example generate_r1cs_example_with_binary_input(const size_t num_constraints, - const size_t num_inputs) -{ - enter_block("Call to generate_r1cs_example_with_binary_input"); - - assert(num_inputs >= 1); - - r1cs_constraint_system cs; - cs.primary_input_size = num_inputs; - cs.auxiliary_input_size = num_constraints; /* we will add one auxiliary variable per constraint */ - - r1cs_variable_assignment full_variable_assignment; - for (size_t i = 0; i < num_inputs; ++i) - { - full_variable_assignment.push_back(FieldT(std::rand() % 2)); - } - - size_t lastvar = num_inputs-1; - for (size_t i = 0; i < num_constraints; ++i) - { - ++lastvar; - const size_t u = (i == 0 ? std::rand() % num_inputs : std::rand() % i); - const size_t v = (i == 0 ? std::rand() % num_inputs : std::rand() % i); - - /* chose two random bits and XOR them together: - res = u + v - 2 * u * v - 2 * u * v = u + v - res - */ - linear_combination A, B, C; - A.add_term(u+1, 2); - B.add_term(v+1, 1); - if (u == v) - { - C.add_term(u+1, 2); - } - else - { - C.add_term(u+1, 1); - C.add_term(v+1, 1); - } - C.add_term(lastvar+1, -FieldT::one()); - - cs.add_constraint(r1cs_constraint(A, B, C)); - full_variable_assignment.push_back(full_variable_assignment[u] + full_variable_assignment[v] - full_variable_assignment[u] * full_variable_assignment[v] - full_variable_assignment[u] * full_variable_assignment[v]); - } - - /* split variable assignment */ - r1cs_primary_input primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + num_inputs); - r1cs_primary_input auxiliary_input(full_variable_assignment.begin() + num_inputs, full_variable_assignment.end()); - - /* sanity checks */ - assert(cs.num_variables() == full_variable_assignment.size()); - assert(cs.num_variables() >= num_inputs); - assert(cs.num_inputs() == num_inputs); - assert(cs.num_constraints() == num_constraints); - assert(cs.is_satisfied(primary_input, auxiliary_input)); - - leave_block("Call to generate_r1cs_example_with_binary_input"); - - return r1cs_example(std::move(cs), std::move(primary_input), std::move(auxiliary_input)); -} - -} // libsnark - -#endif // R1CS_EXAMPLES_TCC diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp deleted file mode 100644 index ca3acb3a9..000000000 --- a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp +++ /dev/null @@ -1,153 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for: - - a R1CS constraint, - - a R1CS variable assignment, and - - a R1CS constraint system. - - Above, R1CS stands for "Rank-1 Constraint System". - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_HPP_ -#define R1CS_HPP_ - -#include -#include -#include -#include -#include - -#include "relations/variable.hpp" - -namespace libsnark { - -/************************* R1CS constraint ***********************************/ - -template -class r1cs_constraint; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_constraint &c); - -template -std::istream& operator>>(std::istream &in, r1cs_constraint &c); - -/** - * A R1CS constraint is a formal expression of the form - * - * < A , X > * < B , X > = < C , X > , - * - * where X = (x_0,x_1,...,x_m) is a vector of formal variables and A,B,C each - * consist of 1+m elements in . - * - * A R1CS constraint is used to construct a R1CS constraint system (see below). - */ -template -class r1cs_constraint { -public: - - linear_combination a, b, c; - - r1cs_constraint() {}; - r1cs_constraint(const linear_combination &a, - const linear_combination &b, - const linear_combination &c); - - r1cs_constraint(const std::initializer_list > &A, - const std::initializer_list > &B, - const std::initializer_list > &C); - - bool operator==(const r1cs_constraint &other) const; - - friend std::ostream& operator<< (std::ostream &out, const r1cs_constraint &c); - friend std::istream& operator>> (std::istream &in, r1cs_constraint &c); -}; - -/************************* R1CS variable assignment **************************/ - -/** - * A R1CS variable assignment is a vector of elements that represents - * a candidate solution to a R1CS constraint system (see below). - */ - -/* TODO: specify that it does *NOT* include the constant 1 */ -template -using r1cs_primary_input = std::vector; - -template -using r1cs_auxiliary_input = std::vector; - -template -using r1cs_variable_assignment = std::vector; /* note the changed name! (TODO: remove this comment after primary_input transition is complete) */ - -/************************* R1CS constraint system ****************************/ - -template -class r1cs_constraint_system; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_constraint_system &cs); - -template -std::istream& operator>>(std::istream &in, r1cs_constraint_system &cs); - -/** - * A system of R1CS constraints looks like - * - * { < A_k , X > * < B_k , X > = < C_k , X > }_{k=1}^{n} . - * - * In other words, the system is satisfied if and only if there exist a - * USCS variable assignment for which each R1CS constraint is satisfied. - * - * NOTE: - * The 0-th variable (i.e., "x_{0}") always represents the constant 1. - * Thus, the 0-th variable is not included in num_variables. - */ -template -class r1cs_constraint_system { -public: - size_t primary_input_size; - size_t auxiliary_input_size; - - std::vector > constraints; - - r1cs_constraint_system() : primary_input_size(0), auxiliary_input_size(0) {} - - size_t num_inputs() const; - size_t num_variables() const; - size_t num_constraints() const; - -#ifdef DEBUG - std::map constraint_annotations; - std::map variable_annotations; -#endif - - bool is_valid() const; - bool is_satisfied(const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input) const; - - void add_constraint(const r1cs_constraint &c); - void add_constraint(const r1cs_constraint &c, const std::string &annotation); - - void swap_AB_if_beneficial(); - - bool operator==(const r1cs_constraint_system &other) const; - - friend std::ostream& operator<< (std::ostream &out, const r1cs_constraint_system &cs); - friend std::istream& operator>> (std::istream &in, r1cs_constraint_system &cs); - - void report_linear_constraint_statistics() const; -}; - - -} // libsnark - -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.tcc" - -#endif // R1CS_HPP_ diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc deleted file mode 100644 index 0faa56a87..000000000 --- a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc +++ /dev/null @@ -1,310 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for: - - a R1CS constraint, - - a R1CS variable assignment, and - - a R1CS constraint system. - - See r1cs.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_TCC_ -#define R1CS_TCC_ - -#include -#include -#include -#include "common/utils.hpp" -#include "common/profiling.hpp" -#include "algebra/fields/bigint.hpp" - -namespace libsnark { - -template -r1cs_constraint::r1cs_constraint(const linear_combination &a, - const linear_combination &b, - const linear_combination &c) : - a(a), b(b), c(c) -{ -} - -template -r1cs_constraint::r1cs_constraint(const std::initializer_list > &A, - const std::initializer_list > &B, - const std::initializer_list > &C) -{ - for (auto lc_A : A) - { - a.terms.insert(a.terms.end(), lc_A.terms.begin(), lc_A.terms.end()); - } - for (auto lc_B : B) - { - b.terms.insert(b.terms.end(), lc_B.terms.begin(), lc_B.terms.end()); - } - for (auto lc_C : C) - { - c.terms.insert(c.terms.end(), lc_C.terms.begin(), lc_C.terms.end()); - } -} - -template -bool r1cs_constraint::operator==(const r1cs_constraint &other) const -{ - return (this->a == other.a && - this->b == other.b && - this->c == other.c); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_constraint &c) -{ - out << c.a; - out << c.b; - out << c.c; - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_constraint &c) -{ - in >> c.a; - in >> c.b; - in >> c.c; - - return in; -} - -template -size_t r1cs_constraint_system::num_inputs() const -{ - return primary_input_size; -} - -template -size_t r1cs_constraint_system::num_variables() const -{ - return primary_input_size + auxiliary_input_size; -} - - -template -size_t r1cs_constraint_system::num_constraints() const -{ - return constraints.size(); -} - -template -bool r1cs_constraint_system::is_valid() const -{ - if (this->num_inputs() > this->num_variables()) return false; - - for (size_t c = 0; c < constraints.size(); ++c) - { - if (!(constraints[c].a.is_valid(this->num_variables()) && - constraints[c].b.is_valid(this->num_variables()) && - constraints[c].c.is_valid(this->num_variables()))) - { - return false; - } - } - - return true; -} - -template -void dump_r1cs_constraint(const r1cs_constraint &constraint, - const r1cs_variable_assignment &full_variable_assignment, - const std::map &variable_annotations) -{ - printf("terms for a:\n"); constraint.a.print_with_assignment(full_variable_assignment, variable_annotations); - printf("terms for b:\n"); constraint.b.print_with_assignment(full_variable_assignment, variable_annotations); - printf("terms for c:\n"); constraint.c.print_with_assignment(full_variable_assignment, variable_annotations); -} - -template -bool r1cs_constraint_system::is_satisfied(const r1cs_primary_input &primary_input, - const r1cs_auxiliary_input &auxiliary_input) const -{ - assert(primary_input.size() == num_inputs()); - assert(primary_input.size() + auxiliary_input.size() == num_variables()); - - r1cs_variable_assignment full_variable_assignment = primary_input; - full_variable_assignment.insert(full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end()); - - for (size_t c = 0; c < constraints.size(); ++c) - { - const FieldT ares = constraints[c].a.evaluate(full_variable_assignment); - const FieldT bres = constraints[c].b.evaluate(full_variable_assignment); - const FieldT cres = constraints[c].c.evaluate(full_variable_assignment); - - if (!(ares*bres == cres)) - { -#ifdef DEBUG - auto it = constraint_annotations.find(c); - printf("constraint %zu (%s) unsatisfied\n", c, (it == constraint_annotations.end() ? "no annotation" : it->second.c_str())); - printf(" = "); ares.print(); - printf(" = "); bres.print(); - printf(" = "); cres.print(); - printf("constraint was:\n"); - dump_r1cs_constraint(constraints[c], full_variable_assignment, variable_annotations); -#endif // DEBUG - return false; - } - } - - return true; -} - -template -void r1cs_constraint_system::add_constraint(const r1cs_constraint &c) -{ - constraints.emplace_back(c); -} - -template -void r1cs_constraint_system::add_constraint(const r1cs_constraint &c, const std::string &annotation) -{ -#ifdef DEBUG - constraint_annotations[constraints.size()] = annotation; -#endif - constraints.emplace_back(c); -} - -template -void r1cs_constraint_system::swap_AB_if_beneficial() -{ - enter_block("Call to r1cs_constraint_system::swap_AB_if_beneficial"); - - enter_block("Estimate densities"); - bit_vector touched_by_A(this->num_variables() + 1, false), touched_by_B(this->num_variables() + 1, false); - - for (size_t i = 0; i < this->constraints.size(); ++i) - { - for (size_t j = 0; j < this->constraints[i].a.terms.size(); ++j) - { - touched_by_A[this->constraints[i].a.terms[j].index] = true; - } - - for (size_t j = 0; j < this->constraints[i].b.terms.size(); ++j) - { - touched_by_B[this->constraints[i].b.terms[j].index] = true; - } - } - - size_t non_zero_A_count = 0, non_zero_B_count = 0; - for (size_t i = 0; i < this->num_variables() + 1; ++i) - { - non_zero_A_count += touched_by_A[i] ? 1 : 0; - non_zero_B_count += touched_by_B[i] ? 1 : 0; - } - - if (!inhibit_profiling_info) - { - print_indent(); printf("* Non-zero A-count (estimate): %zu\n", non_zero_A_count); - print_indent(); printf("* Non-zero B-count (estimate): %zu\n", non_zero_B_count); - } - leave_block("Estimate densities"); - - if (non_zero_B_count > non_zero_A_count) - { - enter_block("Perform the swap"); - for (size_t i = 0; i < this->constraints.size(); ++i) - { - std::swap(this->constraints[i].a, this->constraints[i].b); - } - leave_block("Perform the swap"); - } - else - { - print_indent(); printf("Swap is not beneficial, not performing\n"); - } - - leave_block("Call to r1cs_constraint_system::swap_AB_if_beneficial"); -} - -template -bool r1cs_constraint_system::operator==(const r1cs_constraint_system &other) const -{ - return (this->constraints == other.constraints && - this->primary_input_size == other.primary_input_size && - this->auxiliary_input_size == other.auxiliary_input_size); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_constraint_system &cs) -{ - out << cs.primary_input_size << "\n"; - out << cs.auxiliary_input_size << "\n"; - - out << cs.num_constraints() << "\n"; - for (const r1cs_constraint& c : cs.constraints) - { - out << c; - } - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_constraint_system &cs) -{ - in >> cs.primary_input_size; - in >> cs.auxiliary_input_size; - - cs.constraints.clear(); - - size_t s; - in >> s; - - char b; - in.read(&b, 1); - - cs.constraints.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - r1cs_constraint c; - in >> c; - cs.constraints.emplace_back(c); - } - - return in; -} - -template -void r1cs_constraint_system::report_linear_constraint_statistics() const -{ -#ifdef DEBUG - for (size_t i = 0; i < constraints.size(); ++i) - { - auto &constr = constraints[i]; - bool a_is_const = true; - for (auto &t : constr.a.terms) - { - a_is_const = a_is_const && (t.index == 0); - } - - bool b_is_const = true; - for (auto &t : constr.b.terms) - { - b_is_const = b_is_const && (t.index == 0); - } - - if (a_is_const || b_is_const) - { - auto it = constraint_annotations.find(i); - printf("%s\n", (it == constraint_annotations.end() ? FORMAT("", "constraint_%zu", i) : it->second).c_str()); - } - } -#endif -} - -} // libsnark -#endif // R1CS_TCC_ diff --git a/src/snark/libsnark/relations/variable.hpp b/src/snark/libsnark/relations/variable.hpp deleted file mode 100644 index c63f57b42..000000000 --- a/src/snark/libsnark/relations/variable.hpp +++ /dev/null @@ -1,213 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for: - - a variable (i.e., x_i), - - a linear term (i.e., a_i * x_i), and - - a linear combination (i.e., sum_i a_i * x_i). - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef VARIABLE_HPP_ -#define VARIABLE_HPP_ - -#include -#include -#include -#include - -namespace libsnark { - -/** - * Mnemonic typedefs. - */ -typedef size_t var_index_t; -typedef int64_t integer_coeff_t; - -/** - * Forward declaration. - */ -template -class linear_term; - -/** - * Forward declaration. - */ -template -class linear_combination; - -/********************************* Variable **********************************/ - -/** - * A variable represents a formal expresison of the form "x_{index}". - */ -template -class variable { -public: - - var_index_t index; - - variable(const var_index_t index = 0) : index(index) {}; - - linear_term operator*(const integer_coeff_t int_coeff) const; - linear_term operator*(const FieldT &field_coeff) const; - - linear_combination operator+(const linear_combination &other) const; - linear_combination operator-(const linear_combination &other) const; - - linear_term operator-() const; - - bool operator==(const variable &other) const; -}; - -template -linear_term operator*(const integer_coeff_t int_coeff, const variable &var); - -template -linear_term operator*(const FieldT &field_coeff, const variable &var); - -template -linear_combination operator+(const integer_coeff_t int_coeff, const variable &var); - -template -linear_combination operator+(const FieldT &field_coeff, const variable &var); - -template -linear_combination operator-(const integer_coeff_t int_coeff, const variable &var); - -template -linear_combination operator-(const FieldT &field_coeff, const variable &var); - - -/****************************** Linear term **********************************/ - -/** - * A linear term represents a formal expression of the form "coeff * x_{index}". - */ -template -class linear_term { -public: - - var_index_t index = 0; - FieldT coeff; - - linear_term() {}; - linear_term(const variable &var); - linear_term(const variable &var, const integer_coeff_t int_coeff); - linear_term(const variable &var, const FieldT &field_coeff); - - linear_term operator*(const integer_coeff_t int_coeff) const; - linear_term operator*(const FieldT &field_coeff) const; - - linear_combination operator+(const linear_combination &other) const; - linear_combination operator-(const linear_combination &other) const; - - linear_term operator-() const; - - bool operator==(const linear_term &other) const; -}; - -template -linear_term operator*(const integer_coeff_t int_coeff, const linear_term <); - -template -linear_term operator*(const FieldT &field_coeff, const linear_term <); - -template -linear_combination operator+(const integer_coeff_t int_coeff, const linear_term <); - -template -linear_combination operator+(const FieldT &field_coeff, const linear_term <); - -template -linear_combination operator-(const integer_coeff_t int_coeff, const linear_term <); - -template -linear_combination operator-(const FieldT &field_coeff, const linear_term <); - - -/***************************** Linear combination ****************************/ - -template -class linear_combination; - -template -std::ostream& operator<<(std::ostream &out, const linear_combination &lc); - -template -std::istream& operator>>(std::istream &in, linear_combination &lc); - -/** - * A linear combination represents a formal expression of the form "sum_i coeff_i * x_{index_i}". - */ -template -class linear_combination { -public: - - std::vector > terms; - - linear_combination() {}; - linear_combination(const integer_coeff_t int_coeff); - linear_combination(const FieldT &field_coeff); - linear_combination(const variable &var); - linear_combination(const linear_term <); - linear_combination(const std::vector > &all_terms); - - /* for supporting range-based for loops over linear_combination */ - typename std::vector >::const_iterator begin() const; - typename std::vector >::const_iterator end() const; - - void add_term(const variable &var); - void add_term(const variable &var, const integer_coeff_t int_coeff); - void add_term(const variable &var, const FieldT &field_coeff); - - void add_term(const linear_term <); - - FieldT evaluate(const std::vector &assignment) const; - - linear_combination operator*(const integer_coeff_t int_coeff) const; - linear_combination operator*(const FieldT &field_coeff) const; - - linear_combination operator+(const linear_combination &other) const; - - linear_combination operator-(const linear_combination &other) const; - linear_combination operator-() const; - - bool operator==(const linear_combination &other) const; - - bool is_valid(const size_t num_variables) const; - - void print(const std::map &variable_annotations = std::map()) const; - void print_with_assignment(const std::vector &full_assignment, const std::map &variable_annotations = std::map()) const; - - friend std::ostream& operator<< (std::ostream &out, const linear_combination &lc); - friend std::istream& operator>> (std::istream &in, linear_combination &lc); -}; - -template -linear_combination operator*(const integer_coeff_t int_coeff, const linear_combination &lc); - -template -linear_combination operator*(const FieldT &field_coeff, const linear_combination &lc); - -template -linear_combination operator+(const integer_coeff_t int_coeff, const linear_combination &lc); - -template -linear_combination operator+(const FieldT &field_coeff, const linear_combination &lc); - -template -linear_combination operator-(const integer_coeff_t int_coeff, const linear_combination &lc); - -template -linear_combination operator-(const FieldT &field_coeff, const linear_combination &lc); - -} // libsnark - -#include "relations/variable.tcc" - -#endif // VARIABLE_HPP_ diff --git a/src/snark/libsnark/relations/variable.tcc b/src/snark/libsnark/relations/variable.tcc deleted file mode 100644 index 4c4cab97f..000000000 --- a/src/snark/libsnark/relations/variable.tcc +++ /dev/null @@ -1,512 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of interfaces for: - - a variable (i.e., x_i), - - a linear term (i.e., a_i * x_i), and - - a linear combination (i.e., sum_i a_i * x_i). - - See variabe.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef VARIABLE_TCC_ -#define VARIABLE_TCC_ - -#include -#include - -#include "algebra/fields/bigint.hpp" - -namespace libsnark { - -template -linear_term variable::operator*(const integer_coeff_t int_coeff) const -{ - return linear_term(*this, int_coeff); -} - -template -linear_term variable::operator*(const FieldT &field_coeff) const -{ - return linear_term(*this, field_coeff); -} - -template -linear_combination variable::operator+(const linear_combination &other) const -{ - linear_combination result; - - result.add_term(*this); - result.terms.insert(result.terms.begin(), other.terms.begin(), other.terms.end()); - - return result; -} - -template -linear_combination variable::operator-(const linear_combination &other) const -{ - return (*this) + (-other); -} - -template -linear_term variable::operator-() const -{ - return linear_term(*this, -FieldT::one()); -} - -template -bool variable::operator==(const variable &other) const -{ - return (this->index == other.index); -} - -template -linear_term operator*(const integer_coeff_t int_coeff, const variable &var) -{ - return linear_term(var, int_coeff); -} - -template -linear_term operator*(const FieldT &field_coeff, const variable &var) -{ - return linear_term(var, field_coeff); -} - -template -linear_combination operator+(const integer_coeff_t int_coeff, const variable &var) -{ - return linear_combination(int_coeff) + var; -} - -template -linear_combination operator+(const FieldT &field_coeff, const variable &var) -{ - return linear_combination(field_coeff) + var; -} - -template -linear_combination operator-(const integer_coeff_t int_coeff, const variable &var) -{ - return linear_combination(int_coeff) - var; -} - -template -linear_combination operator-(const FieldT &field_coeff, const variable &var) -{ - return linear_combination(field_coeff) - var; -} - -template -linear_term::linear_term(const variable &var) : - index(var.index), coeff(FieldT::one()) -{ -} - -template -linear_term::linear_term(const variable &var, const integer_coeff_t int_coeff) : - index(var.index), coeff(FieldT(int_coeff)) -{ -} - -template -linear_term::linear_term(const variable &var, const FieldT &coeff) : - index(var.index), coeff(coeff) -{ -} - -template -linear_term linear_term::operator*(const integer_coeff_t int_coeff) const -{ - return (this->operator*(FieldT(int_coeff))); -} - -template -linear_term linear_term::operator*(const FieldT &field_coeff) const -{ - return linear_term(this->index, field_coeff * this->coeff); -} - -template -linear_combination operator+(const integer_coeff_t int_coeff, const linear_term <) -{ - return linear_combination(int_coeff) + lt; -} - -template -linear_combination operator+(const FieldT &field_coeff, const linear_term <) -{ - return linear_combination(field_coeff) + lt; -} - -template -linear_combination operator-(const integer_coeff_t int_coeff, const linear_term <) -{ - return linear_combination(int_coeff) - lt; -} - -template -linear_combination operator-(const FieldT &field_coeff, const linear_term <) -{ - return linear_combination(field_coeff) - lt; -} - -template -linear_combination linear_term::operator+(const linear_combination &other) const -{ - return linear_combination(*this) + other; -} - -template -linear_combination linear_term::operator-(const linear_combination &other) const -{ - return (*this) + (-other); -} - -template -linear_term linear_term::operator-() const -{ - return linear_term(this->index, -this->coeff); -} - -template -bool linear_term::operator==(const linear_term &other) const -{ - return (this->index == other.index && - this->coeff == other.coeff); -} - -template -linear_term operator*(const integer_coeff_t int_coeff, const linear_term <) -{ - return FieldT(int_coeff) * lt; -} - -template -linear_term operator*(const FieldT &field_coeff, const linear_term <) -{ - return linear_term(lt.index, field_coeff * lt.coeff); -} - -template -linear_combination::linear_combination(const integer_coeff_t int_coeff) -{ - this->add_term(linear_term(0, int_coeff)); -} - -template -linear_combination::linear_combination(const FieldT &field_coeff) -{ - this->add_term(linear_term(0, field_coeff)); -} - -template -linear_combination::linear_combination(const variable &var) -{ - this->add_term(var); -} - -template -linear_combination::linear_combination(const linear_term <) -{ - this->add_term(lt); -} - -template -typename std::vector >::const_iterator linear_combination::begin() const -{ - return terms.begin(); -} - -template -typename std::vector >::const_iterator linear_combination::end() const -{ - return terms.end(); -} - -template -void linear_combination::add_term(const variable &var) -{ - this->terms.emplace_back(linear_term(var.index, FieldT::one())); -} - -template -void linear_combination::add_term(const variable &var, const integer_coeff_t int_coeff) -{ - this->terms.emplace_back(linear_term(var.index, int_coeff)); -} - -template -void linear_combination::add_term(const variable &var, const FieldT &coeff) -{ - this->terms.emplace_back(linear_term(var.index, coeff)); -} - -template -void linear_combination::add_term(const linear_term &other) -{ - this->terms.emplace_back(other); -} - -template -linear_combination linear_combination::operator*(const integer_coeff_t int_coeff) const -{ - return (*this) * FieldT(int_coeff); -} - -template -FieldT linear_combination::evaluate(const std::vector &assignment) const -{ - FieldT acc = FieldT::zero(); - for (auto < : terms) - { - acc += (lt.index == 0 ? FieldT::one() : assignment[lt.index-1]) * lt.coeff; - } - return acc; -} - -template -linear_combination linear_combination::operator*(const FieldT &field_coeff) const -{ - linear_combination result; - result.terms.reserve(this->terms.size()); - for (const linear_term < : this->terms) - { - result.terms.emplace_back(lt * field_coeff); - } - return result; -} - -template -linear_combination linear_combination::operator+(const linear_combination &other) const -{ - linear_combination result; - - auto it1 = this->terms.begin(); - auto it2 = other.terms.begin(); - - /* invariant: it1 and it2 always point to unprocessed items in the corresponding linear combinations */ - while (it1 != this->terms.end() && it2 != other.terms.end()) - { - if (it1->index < it2->index) - { - result.terms.emplace_back(*it1); - ++it1; - } - else if (it1->index > it2->index) - { - result.terms.emplace_back(*it2); - ++it2; - } - else - { - /* it1->index == it2->index */ - result.terms.emplace_back(linear_term(variable(it1->index), it1->coeff + it2->coeff)); - ++it1; - ++it2; - } - } - - if (it1 != this->terms.end()) - { - result.terms.insert(result.terms.end(), it1, this->terms.end()); - } - else - { - result.terms.insert(result.terms.end(), it2, other.terms.end()); - } - - return result; -} - -template -linear_combination linear_combination::operator-(const linear_combination &other) const -{ - return (*this) + (-other); -} - -template -linear_combination linear_combination::operator-() const -{ - return (*this) * (-FieldT::one()); -} - -template -bool linear_combination::operator==(const linear_combination &other) const -{ - return (this->terms == other.terms); -} - -template -bool linear_combination::is_valid(const size_t num_variables) const -{ - /* check that all terms in linear combination are sorted */ - for (size_t i = 1; i < terms.size(); ++i) - { - if (terms[i-1].index >= terms[i].index) - { - return false; - } - } - - /* check that the variables are in proper range. as the variables - are sorted, it suffices to check the last term */ - if ((--terms.end())->index >= num_variables) - { - return false; - } - - return true; -} - -template -void linear_combination::print(const std::map &variable_annotations) const -{ - for (auto < : terms) - { - if (lt.index == 0) - { - printf(" 1 * "); - lt.coeff.print(); - } - else - { - auto it = variable_annotations.find(lt.index); - printf(" x_%zu (%s) * ", lt.index, (it == variable_annotations.end() ? "no annotation" : it->second.c_str())); - lt.coeff.print(); - } - } -} - -template -void linear_combination::print_with_assignment(const std::vector &full_assignment, const std::map &variable_annotations) const -{ - for (auto < : terms) - { - if (lt.index == 0) - { - printf(" 1 * "); - lt.coeff.print(); - } - else - { - printf(" x_%zu * ", lt.index); - lt.coeff.print(); - - auto it = variable_annotations.find(lt.index); - printf(" where x_%zu (%s) was assigned value ", lt.index, - (it == variable_annotations.end() ? "no annotation" : it->second.c_str())); - full_assignment[lt.index-1].print(); - printf(" i.e. negative of "); - (-full_assignment[lt.index-1]).print(); - } - } -} - -template -std::ostream& operator<<(std::ostream &out, const linear_combination &lc) -{ - out << lc.terms.size() << "\n"; - for (const linear_term& lt : lc.terms) - { - out << lt.index << "\n"; - out << lt.coeff << OUTPUT_NEWLINE; - } - - return out; -} - -template -std::istream& operator>>(std::istream &in, linear_combination &lc) -{ - lc.terms.clear(); - - size_t s; - in >> s; - - consume_newline(in); - - lc.terms.reserve(s); - - for (size_t i = 0; i < s; ++i) - { - linear_term lt; - in >> lt.index; - consume_newline(in); - in >> lt.coeff; - consume_OUTPUT_NEWLINE(in); - lc.terms.emplace_back(lt); - } - - return in; -} - -template -linear_combination operator*(const integer_coeff_t int_coeff, const linear_combination &lc) -{ - return lc * int_coeff; -} - -template -linear_combination operator*(const FieldT &field_coeff, const linear_combination &lc) -{ - return lc * field_coeff; -} - -template -linear_combination operator+(const integer_coeff_t int_coeff, const linear_combination &lc) -{ - return linear_combination(int_coeff) + lc; -} - -template -linear_combination operator+(const FieldT &field_coeff, const linear_combination &lc) -{ - return linear_combination(field_coeff) + lc; -} - -template -linear_combination operator-(const integer_coeff_t int_coeff, const linear_combination &lc) -{ - return linear_combination(int_coeff) - lc; -} - -template -linear_combination operator-(const FieldT &field_coeff, const linear_combination &lc) -{ - return linear_combination(field_coeff) - lc; -} - -template -linear_combination::linear_combination(const std::vector > &all_terms) -{ - if (all_terms.empty()) - { - return; - } - - terms = all_terms; - std::sort(terms.begin(), terms.end(), [](linear_term a, linear_term b) { return a.index < b.index; }); - - auto result_it = terms.begin(); - for (auto it = ++terms.begin(); it != terms.end(); ++it) - { - if (it->index == result_it->index) - { - result_it->coeff += it->coeff; - } - else - { - *(++result_it) = *it; - } - } - terms.resize((result_it - terms.begin()) + 1); -} - -} // libsnark - -#endif // VARIABLE_TCC diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp deleted file mode 100644 index fcd28abf3..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of functionality that runs the R1CS ppzkSNARK for - a given R1CS example. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef RUN_R1CS_PPZKSNARK_HPP_ -#define RUN_R1CS_PPZKSNARK_HPP_ - -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" - -namespace libsnark { - -/** - * Runs the ppzkSNARK (generator, prover, and verifier) for a given - * R1CS example (specified by a constraint system, input, and witness). - * - * Optionally, also test the serialization routines for keys and proofs. - * (This takes additional time.) - */ -template -bool run_r1cs_ppzksnark(const r1cs_example > &example, - const bool test_serialization); - -} // libsnark - -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc" - -#endif // RUN_R1CS_PPZKSNARK_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc deleted file mode 100644 index 9bc875869..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc +++ /dev/null @@ -1,114 +0,0 @@ -/** @file - ***************************************************************************** - - Implementation of functionality that runs the R1CS ppzkSNARK for - a given R1CS example. - - See run_r1cs_ppzksnark.hpp . - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef RUN_R1CS_PPZKSNARK_TCC_ -#define RUN_R1CS_PPZKSNARK_TCC_ - -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" - -#include -#include - -#include "common/profiling.hpp" - -namespace libsnark { - -template -typename std::enable_if::type -test_affine_verifier(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof, - const bool expected_answer) -{ - print_header("R1CS ppzkSNARK Affine Verifier"); - const bool answer = r1cs_ppzksnark_affine_verifier_weak_IC(vk, primary_input, proof); - assert(answer == expected_answer); -} - -template -typename std::enable_if::type -test_affine_verifier(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof, - const bool expected_answer) -{ - UNUSED(vk, primary_input, proof, expected_answer); - print_header("R1CS ppzkSNARK Affine Verifier"); - printf("Affine verifier is not supported; not testing anything.\n"); -} - -/** - * The code below provides an example of all stages of running a R1CS ppzkSNARK. - * - * Of course, in a real-life scenario, we would have three distinct entities, - * mangled into one in the demonstration below. The three entities are as follows. - * (1) The "generator", which runs the ppzkSNARK generator on input a given - * constraint system CS to create a proving and a verification key for CS. - * (2) The "prover", which runs the ppzkSNARK prover on input the proving key, - * a primary input for CS, and an auxiliary input for CS. - * (3) The "verifier", which runs the ppzkSNARK verifier on input the verification key, - * a primary input for CS, and a proof. - */ -template -bool run_r1cs_ppzksnark(const r1cs_example > &example, - const bool test_serialization) -{ - enter_block("Call to run_r1cs_ppzksnark"); - - print_header("R1CS ppzkSNARK Generator"); - r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(example.constraint_system); - printf("\n"); print_indent(); print_mem("after generator"); - - print_header("Preprocess verification key"); - r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(keypair.vk); - - if (test_serialization) - { - enter_block("Test serialization of keys"); - keypair.pk = reserialize >(keypair.pk); - keypair.vk = reserialize >(keypair.vk); - pvk = reserialize >(pvk); - leave_block("Test serialization of keys"); - } - - print_header("R1CS ppzkSNARK Prover"); - r1cs_ppzksnark_proof proof = r1cs_ppzksnark_prover(keypair.pk, example.primary_input, example.auxiliary_input); - printf("\n"); print_indent(); print_mem("after prover"); - - if (test_serialization) - { - enter_block("Test serialization of proof"); - proof = reserialize >(proof); - leave_block("Test serialization of proof"); - } - - print_header("R1CS ppzkSNARK Verifier"); - const bool ans = r1cs_ppzksnark_verifier_strong_IC(keypair.vk, example.primary_input, proof); - printf("\n"); print_indent(); print_mem("after verifier"); - printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL")); - - print_header("R1CS ppzkSNARK Online Verifier"); - const bool ans2 = r1cs_ppzksnark_online_verifier_strong_IC(pvk, example.primary_input, proof); - assert(ans == ans2); - - test_affine_verifier(keypair.vk, example.primary_input, proof, ans); - - leave_block("Call to run_r1cs_ppzksnark"); - - return ans; -} - -} // libsnark - -#endif // RUN_R1CS_PPZKSNARK_TCC_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp deleted file mode 100644 index 5c5415028..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** @file - ***************************************************************************** - Profiling program that exercises the ppzkSNARK (first generator, then prover, - then verifier) on a synthetic R1CS instance. - - The command - - $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 Fr - - exercises the ppzkSNARK (first generator, then prover, then verifier) on an R1CS instance with 1000 equations and an input consisting of 10 field elements. - - (If you get the error `zmInit ERR:can't protect`, see the discussion [above](#elliptic-curve-choices).) - - The command - - $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 bytes - - does the same but now the input consists of 10 bytes. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include -#include - -#include "common/default_types/r1cs_ppzksnark_pp.hpp" -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp" - -using namespace libsnark; - -int main(int argc, const char * argv[]) -{ - default_r1cs_ppzksnark_pp::init_public_params(); - start_profiling(); - - if (argc == 2 && strcmp(argv[1], "-v") == 0) - { - print_compilation_info(); - return 0; - } - - if (argc != 3 && argc != 4) - { - printf("usage: %s num_constraints input_size [Fr|bytes]\n", argv[0]); - return 1; - } - const int num_constraints = atoi(argv[1]); - int input_size = atoi(argv[2]); - if (argc == 4) - { - assert(strcmp(argv[3], "Fr") == 0 || strcmp(argv[3], "bytes") == 0); - if (strcmp(argv[3], "bytes") == 0) - { - input_size = div_ceil(8 * input_size, Fr::capacity()); - } - } - - enter_block("Generate R1CS example"); - r1cs_example > example = generate_r1cs_example_with_field_input >(num_constraints, input_size); - leave_block("Generate R1CS example"); - - print_header("(enter) Profile R1CS ppzkSNARK"); - const bool test_serialization = true; - run_r1cs_ppzksnark(example, test_serialization); - print_header("(leave) Profile R1CS ppzkSNARK"); -} diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp deleted file mode 100644 index 615acd6a6..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp +++ /dev/null @@ -1,485 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of interfaces for a ppzkSNARK for R1CS. - - This includes: - - class for proving key - - class for verification key - - class for processed verification key - - class for key pair (proving key & verification key) - - class for proof - - generator algorithm - - prover algorithm - - verifier algorithm (with strong or weak input consistency) - - online verifier algorithm (with strong or weak input consistency) - - The implementation instantiates (a modification of) the protocol of \[PGHR13], - by following extending, and optimizing the approach described in \[BCTV14]. - - - Acronyms: - - - R1CS = "Rank-1 Constraint Systems" - - ppzkSNARK = "PreProcessing Zero-Knowledge Succinct Non-interactive ARgument of Knowledge" - - References: - - \[BCTV14]: - "Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture", - Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, - USENIX Security 2014, - - - \[PGHR13]: - "Pinocchio: Nearly practical verifiable computation", - Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova, - IEEE S&P 2013, - - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_PPZKSNARK_HPP_ -#define R1CS_PPZKSNARK_HPP_ - -#include - -#include "algebra/curves/public_params.hpp" -#include "common/data_structures/accumulation_vector.hpp" -#include "algebra/knowledge_commitment/knowledge_commitment.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp" - -namespace libsnark { - -/******************************** Proving key ********************************/ - -template -class r1cs_ppzksnark_proving_key; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proving_key &pk); - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proving_key &pk); - -/** - * A proving key for the R1CS ppzkSNARK. - */ -template -class r1cs_ppzksnark_proving_key { -public: - knowledge_commitment_vector, G1 > A_query; - knowledge_commitment_vector, G1 > B_query; - knowledge_commitment_vector, G1 > C_query; - G1_vector H_query; - G1_vector K_query; - - r1cs_ppzksnark_proving_key() {}; - r1cs_ppzksnark_proving_key& operator=(const r1cs_ppzksnark_proving_key &other) = default; - r1cs_ppzksnark_proving_key(const r1cs_ppzksnark_proving_key &other) = default; - r1cs_ppzksnark_proving_key(r1cs_ppzksnark_proving_key &&other) = default; - r1cs_ppzksnark_proving_key(knowledge_commitment_vector, G1 > &&A_query, - knowledge_commitment_vector, G1 > &&B_query, - knowledge_commitment_vector, G1 > &&C_query, - G1_vector &&H_query, - G1_vector &&K_query) : - A_query(std::move(A_query)), - B_query(std::move(B_query)), - C_query(std::move(C_query)), - H_query(std::move(H_query)), - K_query(std::move(K_query)) - {}; - - size_t G1_size() const - { - return 2*(A_query.domain_size() + C_query.domain_size()) + B_query.domain_size() + H_query.size() + K_query.size(); - } - - size_t G2_size() const - { - return B_query.domain_size(); - } - - size_t G1_sparse_size() const - { - return 2*(A_query.size() + C_query.size()) + B_query.size() + H_query.size() + K_query.size(); - } - - size_t G2_sparse_size() const - { - return B_query.size(); - } - - size_t size_in_bits() const - { - return A_query.size_in_bits() + B_query.size_in_bits() + C_query.size_in_bits() + libsnark::size_in_bits(H_query) + libsnark::size_in_bits(K_query); - } - - void print_size() const - { - print_indent(); printf("* G1 elements in PK: %zu\n", this->G1_size()); - print_indent(); printf("* Non-zero G1 elements in PK: %zu\n", this->G1_sparse_size()); - print_indent(); printf("* G2 elements in PK: %zu\n", this->G2_size()); - print_indent(); printf("* Non-zero G2 elements in PK: %zu\n", this->G2_sparse_size()); - print_indent(); printf("* PK size in bits: %zu\n", this->size_in_bits()); - } - - bool operator==(const r1cs_ppzksnark_proving_key &other) const; - friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_proving_key &pk); - friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_proving_key &pk); -}; - - -/******************************* Verification key ****************************/ - -template -class r1cs_ppzksnark_verification_key; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_verification_key &vk); - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_verification_key &vk); - -/** - * A verification key for the R1CS ppzkSNARK. - */ -template -class r1cs_ppzksnark_verification_key { -public: - G2 alphaA_g2; - G1 alphaB_g1; - G2 alphaC_g2; - G2 gamma_g2; - G1 gamma_beta_g1; - G2 gamma_beta_g2; - G2 rC_Z_g2; - - accumulation_vector > encoded_IC_query; - - r1cs_ppzksnark_verification_key() = default; - r1cs_ppzksnark_verification_key(const G2 &alphaA_g2, - const G1 &alphaB_g1, - const G2 &alphaC_g2, - const G2 &gamma_g2, - const G1 &gamma_beta_g1, - const G2 &gamma_beta_g2, - const G2 &rC_Z_g2, - const accumulation_vector > &eIC) : - alphaA_g2(alphaA_g2), - alphaB_g1(alphaB_g1), - alphaC_g2(alphaC_g2), - gamma_g2(gamma_g2), - gamma_beta_g1(gamma_beta_g1), - gamma_beta_g2(gamma_beta_g2), - rC_Z_g2(rC_Z_g2), - encoded_IC_query(eIC) - {}; - - size_t G1_size() const - { - return 2 + encoded_IC_query.size(); - } - - size_t G2_size() const - { - return 5; - } - - size_t size_in_bits() const - { - return (2 * G1::size_in_bits() + encoded_IC_query.size_in_bits() + 5 * G2::size_in_bits()); - } - - void print_size() const - { - print_indent(); printf("* G1 elements in VK: %zu\n", this->G1_size()); - print_indent(); printf("* G2 elements in VK: %zu\n", this->G2_size()); - print_indent(); printf("* VK size in bits: %zu\n", this->size_in_bits()); - } - - bool operator==(const r1cs_ppzksnark_verification_key &other) const; - friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_verification_key &vk); - friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_verification_key &vk); - - static r1cs_ppzksnark_verification_key dummy_verification_key(const size_t input_size); -}; - - -/************************ Processed verification key *************************/ - -template -class r1cs_ppzksnark_processed_verification_key; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk); - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk); - -/** - * A processed verification key for the R1CS ppzkSNARK. - * - * Compared to a (non-processed) verification key, a processed verification key - * contains a small constant amount of additional pre-computed information that - * enables a faster verification time. - */ -template -class r1cs_ppzksnark_processed_verification_key { -public: - G2_precomp pp_G2_one_precomp; - G2_precomp vk_alphaA_g2_precomp; - G1_precomp vk_alphaB_g1_precomp; - G2_precomp vk_alphaC_g2_precomp; - G2_precomp vk_rC_Z_g2_precomp; - G2_precomp vk_gamma_g2_precomp; - G1_precomp vk_gamma_beta_g1_precomp; - G2_precomp vk_gamma_beta_g2_precomp; - - accumulation_vector > encoded_IC_query; - - bool operator==(const r1cs_ppzksnark_processed_verification_key &other) const; - friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk); - friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk); -}; - - -/********************************** Key pair *********************************/ - -/** - * A key pair for the R1CS ppzkSNARK, which consists of a proving key and a verification key. - */ -template -class r1cs_ppzksnark_keypair { -public: - r1cs_ppzksnark_proving_key pk; - r1cs_ppzksnark_verification_key vk; - - r1cs_ppzksnark_keypair() = default; - r1cs_ppzksnark_keypair(const r1cs_ppzksnark_keypair &other) = default; - r1cs_ppzksnark_keypair(r1cs_ppzksnark_proving_key &&pk, - r1cs_ppzksnark_verification_key &&vk) : - pk(std::move(pk)), - vk(std::move(vk)) - {} - - r1cs_ppzksnark_keypair(r1cs_ppzksnark_keypair &&other) = default; -}; - - -/*********************************** Proof ***********************************/ - -template -class r1cs_ppzksnark_proof; - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proof &proof); - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proof &proof); - -/** - * A proof for the R1CS ppzkSNARK. - * - * While the proof has a structure, externally one merely opaquely produces, - * seralizes/deserializes, and verifies proofs. We only expose some information - * about the structure for statistics purposes. - */ -template -class r1cs_ppzksnark_proof { -public: - knowledge_commitment, G1 > g_A; - knowledge_commitment, G1 > g_B; - knowledge_commitment, G1 > g_C; - G1 g_H; - G1 g_K; - - r1cs_ppzksnark_proof() - { - // invalid proof with valid curve points - this->g_A.g = G1 ::one(); - this->g_A.h = G1::one(); - this->g_B.g = G2 ::one(); - this->g_B.h = G1::one(); - this->g_C.g = G1 ::one(); - this->g_C.h = G1::one(); - this->g_H = G1::one(); - this->g_K = G1::one(); - } - r1cs_ppzksnark_proof(knowledge_commitment, G1 > &&g_A, - knowledge_commitment, G1 > &&g_B, - knowledge_commitment, G1 > &&g_C, - G1 &&g_H, - G1 &&g_K) : - g_A(std::move(g_A)), - g_B(std::move(g_B)), - g_C(std::move(g_C)), - g_H(std::move(g_H)), - g_K(std::move(g_K)) - {}; - - size_t G1_size() const - { - return 7; - } - - size_t G2_size() const - { - return 1; - } - - size_t size_in_bits() const - { - return G1_size() * G1::size_in_bits() + G2_size() * G2::size_in_bits(); - } - - void print_size() const - { - print_indent(); printf("* G1 elements in proof: %zu\n", this->G1_size()); - print_indent(); printf("* G2 elements in proof: %zu\n", this->G2_size()); - print_indent(); printf("* Proof size in bits: %zu\n", this->size_in_bits()); - } - - bool is_well_formed() const - { - return (g_A.g.is_well_formed() && g_A.h.is_well_formed() && - g_B.g.is_well_formed() && g_B.h.is_well_formed() && - g_C.g.is_well_formed() && g_C.h.is_well_formed() && - g_H.is_well_formed() && - g_K.is_well_formed()); - } - - bool operator==(const r1cs_ppzksnark_proof &other) const; - friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_proof &proof); - friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_proof &proof); -}; - - -/***************************** Main algorithms *******************************/ - -/** - * A generator algorithm for the R1CS ppzkSNARK. - * - * Given a R1CS constraint system CS, this algorithm produces proving and verification keys for CS. - */ -template -r1cs_ppzksnark_keypair r1cs_ppzksnark_generator(const r1cs_ppzksnark_constraint_system &cs); - -template -r1cs_ppzksnark_keypair r1cs_ppzksnark_generator( - const r1cs_ppzksnark_constraint_system &cs, - const Fr& t, - const Fr& alphaA, - const Fr& alphaB, - const Fr& alphaC, - const Fr& rA, - const Fr& rB, - const Fr& beta, - const Fr& gamma -); - -/** - * A prover algorithm for the R1CS ppzkSNARK. - * - * Given a R1CS primary input X and a R1CS auxiliary input Y, this algorithm - * produces a proof (of knowledge) that attests to the following statement: - * ``there exists Y such that CS(X,Y)=0''. - * Above, CS is the R1CS constraint system that was given as input to the generator algorithm. - */ -template -r1cs_ppzksnark_proof r1cs_ppzksnark_prover(const r1cs_ppzksnark_proving_key &pk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_auxiliary_input &auxiliary_input); - -template -r1cs_ppzksnark_proof r1cs_ppzksnark_prover_streaming(std::ifstream &proving_key_file, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_auxiliary_input &auxiliary_input, - const r1cs_ppzksnark_constraint_system &constraint_system); - -/* - Below are four variants of verifier algorithm for the R1CS ppzkSNARK. - - These are the four cases that arise from the following two choices: - - (1) The verifier accepts a (non-processed) verification key or, instead, a processed verification key. - In the latter case, we call the algorithm an "online verifier". - - (2) The verifier checks for "weak" input consistency or, instead, "strong" input consistency. - Strong input consistency requires that |primary_input| = CS.num_inputs, whereas - weak input consistency requires that |primary_input| <= CS.num_inputs (and - the primary input is implicitly padded with zeros up to length CS.num_inputs). - */ - -/** - * A verifier algorithm for the R1CS ppzkSNARK that: - * (1) accepts a non-processed verification key, and - * (2) has weak input consistency. - */ -template -bool r1cs_ppzksnark_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof); - -/** - * A verifier algorithm for the R1CS ppzkSNARK that: - * (1) accepts a non-processed verification key, and - * (2) has strong input consistency. - */ -template -bool r1cs_ppzksnark_verifier_strong_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof); - -/** - * Convert a (non-processed) verification key into a processed verification key. - */ -template -r1cs_ppzksnark_processed_verification_key r1cs_ppzksnark_verifier_process_vk(const r1cs_ppzksnark_verification_key &vk); - -/** - * A verifier algorithm for the R1CS ppzkSNARK that: - * (1) accepts a processed verification key, and - * (2) has weak input consistency. - */ -template -bool r1cs_ppzksnark_online_verifier_weak_IC(const r1cs_ppzksnark_processed_verification_key &pvk, - const r1cs_ppzksnark_primary_input &input, - const r1cs_ppzksnark_proof &proof); - -/** - * A verifier algorithm for the R1CS ppzkSNARK that: - * (1) accepts a processed verification key, and - * (2) has strong input consistency. - */ -template -bool r1cs_ppzksnark_online_verifier_strong_IC(const r1cs_ppzksnark_processed_verification_key &pvk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof); - -/****************************** Miscellaneous ********************************/ - -/** - * For debugging purposes (of r1cs_ppzksnark_r1cs_ppzksnark_verifier_gadget): - * - * A verifier algorithm for the R1CS ppzkSNARK that: - * (1) accepts a non-processed verification key, - * (2) has weak input consistency, and - * (3) uses affine coordinates for elliptic-curve computations. - */ -template -bool r1cs_ppzksnark_affine_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof); - - -} // libsnark - -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc" - -#endif // R1CS_PPZKSNARK_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc deleted file mode 100644 index 84db9fc1a..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc +++ /dev/null @@ -1,886 +0,0 @@ -/** @file -***************************************************************************** - -Implementation of interfaces for a ppzkSNARK for R1CS. - -See r1cs_ppzksnark.hpp . - -***************************************************************************** -* @author This file is part of libsnark, developed by SCIPR Lab -* and contributors (see AUTHORS). -* @copyright MIT license (see LICENSE file) -*****************************************************************************/ - -#ifndef R1CS_PPZKSNARK_TCC_ -#define R1CS_PPZKSNARK_TCC_ - -#include -#include -#include -#include -#include - -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "algebra/scalar_multiplication/multiexp.hpp" -#include "algebra/scalar_multiplication/kc_multiexp.hpp" -#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp" - -namespace libsnark { - -template -bool r1cs_ppzksnark_proving_key::operator==(const r1cs_ppzksnark_proving_key &other) const -{ - return (this->A_query == other.A_query && - this->B_query == other.B_query && - this->C_query == other.C_query && - this->H_query == other.H_query && - this->K_query == other.K_query); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proving_key &pk) -{ - out << pk.A_query; - out << pk.B_query; - out << pk.C_query; - out << pk.H_query; - out << pk.K_query; - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proving_key &pk) -{ - in >> pk.A_query; - in >> pk.B_query; - in >> pk.C_query; - in >> pk.H_query; - in >> pk.K_query; - - return in; -} - -template -bool r1cs_ppzksnark_verification_key::operator==(const r1cs_ppzksnark_verification_key &other) const -{ - return (this->alphaA_g2 == other.alphaA_g2 && - this->alphaB_g1 == other.alphaB_g1 && - this->alphaC_g2 == other.alphaC_g2 && - this->gamma_g2 == other.gamma_g2 && - this->gamma_beta_g1 == other.gamma_beta_g1 && - this->gamma_beta_g2 == other.gamma_beta_g2 && - this->rC_Z_g2 == other.rC_Z_g2 && - this->encoded_IC_query == other.encoded_IC_query); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_verification_key &vk) -{ - out << vk.alphaA_g2 << OUTPUT_NEWLINE; - out << vk.alphaB_g1 << OUTPUT_NEWLINE; - out << vk.alphaC_g2 << OUTPUT_NEWLINE; - out << vk.gamma_g2 << OUTPUT_NEWLINE; - out << vk.gamma_beta_g1 << OUTPUT_NEWLINE; - out << vk.gamma_beta_g2 << OUTPUT_NEWLINE; - out << vk.rC_Z_g2 << OUTPUT_NEWLINE; - out << vk.encoded_IC_query << OUTPUT_NEWLINE; - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_verification_key &vk) -{ - in >> vk.alphaA_g2; - consume_OUTPUT_NEWLINE(in); - in >> vk.alphaB_g1; - consume_OUTPUT_NEWLINE(in); - in >> vk.alphaC_g2; - consume_OUTPUT_NEWLINE(in); - in >> vk.gamma_g2; - consume_OUTPUT_NEWLINE(in); - in >> vk.gamma_beta_g1; - consume_OUTPUT_NEWLINE(in); - in >> vk.gamma_beta_g2; - consume_OUTPUT_NEWLINE(in); - in >> vk.rC_Z_g2; - consume_OUTPUT_NEWLINE(in); - in >> vk.encoded_IC_query; - consume_OUTPUT_NEWLINE(in); - - return in; -} - -template -bool r1cs_ppzksnark_processed_verification_key::operator==(const r1cs_ppzksnark_processed_verification_key &other) const -{ - return (this->pp_G2_one_precomp == other.pp_G2_one_precomp && - this->vk_alphaA_g2_precomp == other.vk_alphaA_g2_precomp && - this->vk_alphaB_g1_precomp == other.vk_alphaB_g1_precomp && - this->vk_alphaC_g2_precomp == other.vk_alphaC_g2_precomp && - this->vk_rC_Z_g2_precomp == other.vk_rC_Z_g2_precomp && - this->vk_gamma_g2_precomp == other.vk_gamma_g2_precomp && - this->vk_gamma_beta_g1_precomp == other.vk_gamma_beta_g1_precomp && - this->vk_gamma_beta_g2_precomp == other.vk_gamma_beta_g2_precomp && - this->encoded_IC_query == other.encoded_IC_query); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk) -{ - out << pvk.pp_G2_one_precomp << OUTPUT_NEWLINE; - out << pvk.vk_alphaA_g2_precomp << OUTPUT_NEWLINE; - out << pvk.vk_alphaB_g1_precomp << OUTPUT_NEWLINE; - out << pvk.vk_alphaC_g2_precomp << OUTPUT_NEWLINE; - out << pvk.vk_rC_Z_g2_precomp << OUTPUT_NEWLINE; - out << pvk.vk_gamma_g2_precomp << OUTPUT_NEWLINE; - out << pvk.vk_gamma_beta_g1_precomp << OUTPUT_NEWLINE; - out << pvk.vk_gamma_beta_g2_precomp << OUTPUT_NEWLINE; - out << pvk.encoded_IC_query << OUTPUT_NEWLINE; - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk) -{ - in >> pvk.pp_G2_one_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_alphaA_g2_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_alphaB_g1_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_alphaC_g2_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_rC_Z_g2_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_gamma_g2_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_gamma_beta_g1_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.vk_gamma_beta_g2_precomp; - consume_OUTPUT_NEWLINE(in); - in >> pvk.encoded_IC_query; - consume_OUTPUT_NEWLINE(in); - - return in; -} - -template -bool r1cs_ppzksnark_proof::operator==(const r1cs_ppzksnark_proof &other) const -{ - return (this->g_A == other.g_A && - this->g_B == other.g_B && - this->g_C == other.g_C && - this->g_H == other.g_H && - this->g_K == other.g_K); -} - -template -std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proof &proof) -{ - out << proof.g_A << OUTPUT_NEWLINE; - out << proof.g_B << OUTPUT_NEWLINE; - out << proof.g_C << OUTPUT_NEWLINE; - out << proof.g_H << OUTPUT_NEWLINE; - out << proof.g_K << OUTPUT_NEWLINE; - - return out; -} - -template -std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proof &proof) -{ - in >> proof.g_A; - consume_OUTPUT_NEWLINE(in); - in >> proof.g_B; - consume_OUTPUT_NEWLINE(in); - in >> proof.g_C; - consume_OUTPUT_NEWLINE(in); - in >> proof.g_H; - consume_OUTPUT_NEWLINE(in); - in >> proof.g_K; - consume_OUTPUT_NEWLINE(in); - - return in; -} - -template -r1cs_ppzksnark_verification_key r1cs_ppzksnark_verification_key::dummy_verification_key(const size_t input_size) -{ - r1cs_ppzksnark_verification_key result; - result.alphaA_g2 = Fr::random_element() * G2::one(); - result.alphaB_g1 = Fr::random_element() * G1::one(); - result.alphaC_g2 = Fr::random_element() * G2::one(); - result.gamma_g2 = Fr::random_element() * G2::one(); - result.gamma_beta_g1 = Fr::random_element() * G1::one(); - result.gamma_beta_g2 = Fr::random_element() * G2::one(); - result.rC_Z_g2 = Fr::random_element() * G2::one(); - - G1 base = Fr::random_element() * G1::one(); - G1_vector v; - for (size_t i = 0; i < input_size; ++i) - { - v.emplace_back(Fr::random_element() * G1::one()); - } - - result.encoded_IC_query = accumulation_vector >(std::move(base), std::move(v)); - - return result; -} - -template -r1cs_ppzksnark_keypair r1cs_ppzksnark_generator(const r1cs_ppzksnark_constraint_system &cs) -{ - /* draw random element at which the QAP is evaluated */ - const Fr t = Fr::random_element(); - - const Fr alphaA = Fr::random_element(), - alphaB = Fr::random_element(), - alphaC = Fr::random_element(), - rA = Fr::random_element(), - rB = Fr::random_element(), - beta = Fr::random_element(), - gamma = Fr::random_element(); - - return r1cs_ppzksnark_generator(cs, t, alphaA, alphaB, alphaC, rA, rB, beta, gamma); -} - -template -r1cs_ppzksnark_keypair r1cs_ppzksnark_generator( - const r1cs_ppzksnark_constraint_system &cs, - const Fr& t, - const Fr& alphaA, - const Fr& alphaB, - const Fr& alphaC, - const Fr& rA, - const Fr& rB, - const Fr& beta, - const Fr& gamma -) -{ - enter_block("Call to r1cs_ppzksnark_generator"); - - /* make the B_query "lighter" if possible */ - r1cs_ppzksnark_constraint_system cs_copy(cs); - cs_copy.swap_AB_if_beneficial(); - - qap_instance_evaluation > qap_inst = r1cs_to_qap_instance_map_with_evaluation(cs_copy, t); - - print_indent(); printf("* QAP number of variables: %zu\n", qap_inst.num_variables()); - print_indent(); printf("* QAP pre degree: %zu\n", cs_copy.constraints.size()); - print_indent(); printf("* QAP degree: %zu\n", qap_inst.degree()); - print_indent(); printf("* QAP number of input variables: %zu\n", qap_inst.num_inputs()); - - enter_block("Compute query densities"); - size_t non_zero_At = 0, non_zero_Bt = 0, non_zero_Ct = 0, non_zero_Ht = 0; - for (size_t i = 0; i < qap_inst.num_variables()+1; ++i) - { - if (!qap_inst.At[i].is_zero()) - { - ++non_zero_At; - } - if (!qap_inst.Bt[i].is_zero()) - { - ++non_zero_Bt; - } - if (!qap_inst.Ct[i].is_zero()) - { - ++non_zero_Ct; - } - } - for (size_t i = 0; i < qap_inst.degree()+1; ++i) - { - if (!qap_inst.Ht[i].is_zero()) - { - ++non_zero_Ht; - } - } - leave_block("Compute query densities"); - - Fr_vector At = std::move(qap_inst.At); // qap_inst.At is now in unspecified state, but we do not use it later - Fr_vector Bt = std::move(qap_inst.Bt); // qap_inst.Bt is now in unspecified state, but we do not use it later - Fr_vector Ct = std::move(qap_inst.Ct); // qap_inst.Ct is now in unspecified state, but we do not use it later - Fr_vector Ht = std::move(qap_inst.Ht); // qap_inst.Ht is now in unspecified state, but we do not use it later - - /* append Zt to At,Bt,Ct with */ - At.emplace_back(qap_inst.Zt); - Bt.emplace_back(qap_inst.Zt); - Ct.emplace_back(qap_inst.Zt); - - const Fr rC = rA * rB; - - // consrtuct the same-coefficient-check query (must happen before zeroing out the prefix of At) - Fr_vector Kt; - Kt.reserve(qap_inst.num_variables()+4); - for (size_t i = 0; i < qap_inst.num_variables()+1; ++i) - { - Kt.emplace_back( beta * (rA * At[i] + rB * Bt[i] + rC * Ct[i] ) ); - } - Kt.emplace_back(beta * rA * qap_inst.Zt); - Kt.emplace_back(beta * rB * qap_inst.Zt); - Kt.emplace_back(beta * rC * qap_inst.Zt); - - /* zero out prefix of At and stick it into IC coefficients */ - Fr_vector IC_coefficients; - IC_coefficients.reserve(qap_inst.num_inputs() + 1); - for (size_t i = 0; i < qap_inst.num_inputs() + 1; ++i) - { - IC_coefficients.emplace_back(At[i]); - assert(!IC_coefficients[i].is_zero()); - At[i] = Fr::zero(); - } - - const size_t g1_exp_count = 2*(non_zero_At - qap_inst.num_inputs() + non_zero_Ct) + non_zero_Bt + non_zero_Ht + Kt.size(); - const size_t g2_exp_count = non_zero_Bt; - - size_t g1_window = get_exp_window_size >(g1_exp_count); - size_t g2_window = get_exp_window_size >(g2_exp_count); - print_indent(); printf("* G1 window: %zu\n", g1_window); - print_indent(); printf("* G2 window: %zu\n", g2_window); - -#ifdef MULTICORE - const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() -#else - const size_t chunks = 1; -#endif - - enter_block("Generating G1 multiexp table"); - window_table > g1_table = get_window_table(Fr::size_in_bits(), g1_window, G1::one()); - leave_block("Generating G1 multiexp table"); - - enter_block("Generating G2 multiexp table"); - window_table > g2_table = get_window_table(Fr::size_in_bits(), g2_window, G2::one()); - leave_block("Generating G2 multiexp table"); - - enter_block("Generate R1CS proving key"); - - enter_block("Generate knowledge commitments"); - enter_block("Compute the A-query", false); - knowledge_commitment_vector, G1 > A_query = kc_batch_exp(Fr::size_in_bits(), g1_window, g1_window, g1_table, g1_table, rA, rA*alphaA, At, chunks); - leave_block("Compute the A-query", false); - - enter_block("Compute the B-query", false); - knowledge_commitment_vector, G1 > B_query = kc_batch_exp(Fr::size_in_bits(), g2_window, g1_window, g2_table, g1_table, rB, rB*alphaB, Bt, chunks); - leave_block("Compute the B-query", false); - - enter_block("Compute the C-query", false); - knowledge_commitment_vector, G1 > C_query = kc_batch_exp(Fr::size_in_bits(), g1_window, g1_window, g1_table, g1_table, rC, rC*alphaC, Ct, chunks); - leave_block("Compute the C-query", false); - - enter_block("Compute the H-query", false); - G1_vector H_query = batch_exp(Fr::size_in_bits(), g1_window, g1_table, Ht); - leave_block("Compute the H-query", false); - - enter_block("Compute the K-query", false); - G1_vector K_query = batch_exp(Fr::size_in_bits(), g1_window, g1_table, Kt); -#ifdef USE_MIXED_ADDITION - batch_to_special >(K_query); -#endif - leave_block("Compute the K-query", false); - - leave_block("Generate knowledge commitments"); - - leave_block("Generate R1CS proving key"); - - enter_block("Generate R1CS verification key"); - G2 alphaA_g2 = alphaA * G2::one(); - G1 alphaB_g1 = alphaB * G1::one(); - G2 alphaC_g2 = alphaC * G2::one(); - G2 gamma_g2 = gamma * G2::one(); - G1 gamma_beta_g1 = (gamma * beta) * G1::one(); - G2 gamma_beta_g2 = (gamma * beta) * G2::one(); - G2 rC_Z_g2 = (rC * qap_inst.Zt) * G2::one(); - - enter_block("Encode IC query for R1CS verification key"); - G1 encoded_IC_base = (rA * IC_coefficients[0]) * G1::one(); - Fr_vector multiplied_IC_coefficients; - multiplied_IC_coefficients.reserve(qap_inst.num_inputs()); - for (size_t i = 1; i < qap_inst.num_inputs() + 1; ++i) - { - multiplied_IC_coefficients.emplace_back(rA * IC_coefficients[i]); - } - G1_vector encoded_IC_values = batch_exp(Fr::size_in_bits(), g1_window, g1_table, multiplied_IC_coefficients); - - leave_block("Encode IC query for R1CS verification key"); - leave_block("Generate R1CS verification key"); - - leave_block("Call to r1cs_ppzksnark_generator"); - - accumulation_vector > encoded_IC_query(std::move(encoded_IC_base), std::move(encoded_IC_values)); - - r1cs_ppzksnark_verification_key vk = r1cs_ppzksnark_verification_key(alphaA_g2, - alphaB_g1, - alphaC_g2, - gamma_g2, - gamma_beta_g1, - gamma_beta_g2, - rC_Z_g2, - encoded_IC_query); - r1cs_ppzksnark_proving_key pk = r1cs_ppzksnark_proving_key(std::move(A_query), - std::move(B_query), - std::move(C_query), - std::move(H_query), - std::move(K_query)); - - pk.print_size(); - vk.print_size(); - - return r1cs_ppzksnark_keypair(std::move(pk), std::move(vk)); -} - -template -knowledge_commitment r1cs_compute_proof_kc(const qap_witness > &qap_wit, - const knowledge_commitment_vector &kcv, - const Fr &zk_shift) -{ - knowledge_commitment returnval = kcv[0] + (zk_shift * kcv[qap_wit.num_variables()+1]); - -#ifdef DEBUG - assert(kcv.domain_size() == qap_wit.num_variables()+2); -#endif - -#ifdef MULTICORE - const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() -#else - const size_t chunks = 1; -#endif - - returnval = returnval + kc_multi_exp_with_mixed_addition >( - kcv, - 1, - 1 + qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, - true - ); - - return returnval; -} - - - -template -G1 r1cs_compute_proof_K(const qap_witness> &qap_wit, const G1_vector &K_query, const G1 &zk_shift) -{ -#ifdef DEBUG - assert(K_query.size() == qap_wit.num_variables()+4); -#endif - -#ifdef MULTICORE - const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() -#else - const size_t chunks = 1; -#endif - - G1 g_K = K_query[0] + zk_shift; - g_K = g_K + multi_exp_with_mixed_addition, Fr >( - K_query.begin()+1, - K_query.begin()+1+qap_wit.num_variables(), - qap_wit.coefficients_for_ABCs.begin(), - qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), - chunks, - true - ); - - return g_K; -} - - -template -G1 r1cs_compute_proof_H(const qap_witness > &qap_wit, const G1_vector &H_query) -{ - G1 g_H = G1::zero(); - -#ifdef DEBUG - assert(H_query.size() == qap_wit.degree()+1); -#endif - -#ifdef MULTICORE - const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() -#else - const size_t chunks = 1; -#endif - - g_H = g_H + multi_exp, Fr >( - H_query.begin(), - H_query.begin()+qap_wit.degree()+1, - qap_wit.coefficients_for_H.begin(), - qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, - chunks, - true - ); - - return g_H; -} - -template -r1cs_ppzksnark_proof r1cs_ppzksnark_prover(const r1cs_ppzksnark_proving_key &pk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_auxiliary_input &auxiliary_input, - const r1cs_ppzksnark_constraint_system &constraint_system) -{ - enter_block("Call to r1cs_ppzksnark_prover"); - -#ifdef DEBUG - assert(constraint_system.is_satisfied(primary_input, auxiliary_input)); -#endif - - const Fr d1 = Fr::random_element(), - d2 = Fr::random_element(), - d3 = Fr::random_element(); - - enter_block("Compute the polynomial H"); - const qap_witness > qap_wit = r1cs_to_qap_witness_map(constraint_system, primary_input, auxiliary_input, d1, d2, d3); - leave_block("Compute the polynomial H"); - -#ifdef DEBUG - const Fr t = Fr::random_element(); - qap_instance_evaluation > qap_inst = r1cs_to_qap_instance_map_with_evaluation(constraint_system, t); - assert(qap_inst.is_satisfied(qap_wit)); -#endif - -#ifdef DEBUG - for (size_t i = 0; i < qap_wit.num_inputs() + 1; ++i) - { - assert(pk.A_query[i].g == G1::zero()); - } -#endif - - enter_block("Compute the proof"); - - enter_block("Compute answer to A-query", false); - auto g_A = r1cs_compute_proof_kc, G1 >(qap_wit, pk.A_query, qap_wit.d1); - leave_block("Compute answer to A-query", false); - - enter_block("Compute answer to B-query", false); - auto g_B = r1cs_compute_proof_kc, G1 >(qap_wit, pk.B_query, qap_wit.d2); - leave_block("Compute answer to B-query", false); - - enter_block("Compute answer to C-query", false); - auto g_C = r1cs_compute_proof_kc, G1 >(qap_wit, pk.C_query, qap_wit.d3); - leave_block("Compute answer to C-query", false); - - enter_block("Compute answer to H-query", false); - auto g_H = r1cs_compute_proof_H(qap_wit, pk.H_query); - leave_block("Compute answer to H-query", false); - - enter_block("Compute answer to K-query", false); - G1 zk_shift = qap_wit.d1*pk.K_query[qap_wit.num_variables()+1] + - qap_wit.d2*pk.K_query[qap_wit.num_variables()+2] + - qap_wit.d3*pk.K_query[qap_wit.num_variables()+3]; - G1 g_K = r1cs_compute_proof_K(qap_wit, pk.K_query, zk_shift); - leave_block("Compute answer to K-query", false); - - leave_block("Compute the proof"); - - leave_block("Call to r1cs_ppzksnark_prover"); - - r1cs_ppzksnark_proof proof = r1cs_ppzksnark_proof(std::move(g_A), std::move(g_B), std::move(g_C), std::move(g_H), std::move(g_K)); - - return proof; -} - -template -r1cs_ppzksnark_proof r1cs_ppzksnark_prover_streaming(std::ifstream &proving_key_file, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_auxiliary_input &auxiliary_input, - const r1cs_ppzksnark_constraint_system &constraint_system) -{ - enter_block("Call to r1cs_ppzksnark_prover_streaming"); - - const Fr d1 = Fr::random_element(), - d2 = Fr::random_element(), - d3 = Fr::random_element(); - - enter_block("Compute the polynomial H"); - const qap_witness > qap_wit = r1cs_to_qap_witness_map(constraint_system, primary_input, auxiliary_input, d1, d2, d3); - leave_block("Compute the polynomial H"); - - enter_block("Compute the proof"); - - r1cs_ppzksnark_proof proof; - - enter_block("Compute answer to A-query", false); - { - knowledge_commitment_vector, G1 > A_query; - proving_key_file >> A_query; - proof.g_A = r1cs_compute_proof_kc, G1 >(qap_wit, A_query, qap_wit.d1); - } - leave_block("Compute answer to A-query", false); - - enter_block("Compute answer to B-query", false); - { - knowledge_commitment_vector, G1 > B_query; - proving_key_file >> B_query; - proof.g_B = r1cs_compute_proof_kc, G1 >(qap_wit, B_query, qap_wit.d2); - } - leave_block("Compute answer to B-query", false); - - enter_block("Compute answer to C-query", false); - { - knowledge_commitment_vector, G1 > C_query; - proving_key_file >> C_query; - proof.g_C = r1cs_compute_proof_kc, G1 >(qap_wit, C_query, qap_wit.d3); - } - leave_block("Compute answer to C-query", false); - - enter_block("Compute answer to H-query", false); - { - G1_vector H_query; - proving_key_file >> H_query; - proof.g_H = r1cs_compute_proof_H(qap_wit, H_query); - } - leave_block("Compute answer to H-query", false); - - enter_block("Compute answer to K-query", false); - { - G1_vector K_query; - proving_key_file >> K_query; - G1 zk_shift = qap_wit.d1*K_query[qap_wit.num_variables()+1] + - qap_wit.d2*K_query[qap_wit.num_variables()+2] + - qap_wit.d3*K_query[qap_wit.num_variables()+3]; - proof.g_K = r1cs_compute_proof_K(qap_wit, K_query, zk_shift); - } - leave_block("Compute answer to K-query", false); - - leave_block("Compute the proof"); - - leave_block("Call to r1cs_ppzksnark_prover_streaming"); - - return proof; -} - -template -r1cs_ppzksnark_processed_verification_key r1cs_ppzksnark_verifier_process_vk(const r1cs_ppzksnark_verification_key &vk) -{ - enter_block("Call to r1cs_ppzksnark_verifier_process_vk"); - - r1cs_ppzksnark_processed_verification_key pvk; - pvk.pp_G2_one_precomp = ppT::precompute_G2(G2::one()); - pvk.vk_alphaA_g2_precomp = ppT::precompute_G2(vk.alphaA_g2); - pvk.vk_alphaB_g1_precomp = ppT::precompute_G1(vk.alphaB_g1); - pvk.vk_alphaC_g2_precomp = ppT::precompute_G2(vk.alphaC_g2); - pvk.vk_rC_Z_g2_precomp = ppT::precompute_G2(vk.rC_Z_g2); - pvk.vk_gamma_g2_precomp = ppT::precompute_G2(vk.gamma_g2); - pvk.vk_gamma_beta_g1_precomp = ppT::precompute_G1(vk.gamma_beta_g1); - pvk.vk_gamma_beta_g2_precomp = ppT::precompute_G2(vk.gamma_beta_g2); - - pvk.encoded_IC_query = vk.encoded_IC_query; - - leave_block("Call to r1cs_ppzksnark_verifier_process_vk"); - - return pvk; -} - -template -bool r1cs_ppzksnark_online_verifier_weak_IC(const r1cs_ppzksnark_processed_verification_key &pvk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof) -{ - assert(pvk.encoded_IC_query.domain_size() >= primary_input.size()); - - const accumulation_vector > accumulated_IC = pvk.encoded_IC_query.template accumulate_chunk >(primary_input.begin(), primary_input.end(), 0); - const G1 &acc = accumulated_IC.first; - - if (!proof.is_well_formed()) - { - return false; - } - - G1_precomp proof_g_A_g_precomp = ppT::precompute_G1(proof.g_A.g); - G1_precomp proof_g_A_h_precomp = ppT::precompute_G1(proof.g_A.h); - Fqk kc_A_1 = ppT::miller_loop(proof_g_A_g_precomp, pvk.vk_alphaA_g2_precomp); - Fqk kc_A_2 = ppT::miller_loop(proof_g_A_h_precomp, pvk.pp_G2_one_precomp); - GT kc_A = ppT::final_exponentiation(kc_A_1 * kc_A_2.unitary_inverse()); - if (kc_A != GT::one()) - { - return false; - } - - G2_precomp proof_g_B_g_precomp = ppT::precompute_G2(proof.g_B.g); - G1_precomp proof_g_B_h_precomp = ppT::precompute_G1(proof.g_B.h); - Fqk kc_B_1 = ppT::miller_loop(pvk.vk_alphaB_g1_precomp, proof_g_B_g_precomp); - Fqk kc_B_2 = ppT::miller_loop(proof_g_B_h_precomp, pvk.pp_G2_one_precomp); - GT kc_B = ppT::final_exponentiation(kc_B_1 * kc_B_2.unitary_inverse()); - if (kc_B != GT::one()) - { - return false; - } - - G1_precomp proof_g_C_g_precomp = ppT::precompute_G1(proof.g_C.g); - G1_precomp proof_g_C_h_precomp = ppT::precompute_G1(proof.g_C.h); - Fqk kc_C_1 = ppT::miller_loop(proof_g_C_g_precomp, pvk.vk_alphaC_g2_precomp); - Fqk kc_C_2 = ppT::miller_loop(proof_g_C_h_precomp, pvk.pp_G2_one_precomp); - GT kc_C = ppT::final_exponentiation(kc_C_1 * kc_C_2.unitary_inverse()); - if (kc_C != GT::one()) - { - return false; - } - - // check that g^((A+acc)*B)=g^(H*\Prod(t-\sigma)+C) - // equivalently, via pairings, that e(g^(A+acc), g^B) = e(g^H, g^Z) + e(g^C, g^1) - G1_precomp proof_g_A_g_acc_precomp = ppT::precompute_G1(proof.g_A.g + acc); - G1_precomp proof_g_H_precomp = ppT::precompute_G1(proof.g_H); - Fqk QAP_1 = ppT::miller_loop(proof_g_A_g_acc_precomp, proof_g_B_g_precomp); - Fqk QAP_23 = ppT::double_miller_loop(proof_g_H_precomp, pvk.vk_rC_Z_g2_precomp, proof_g_C_g_precomp, pvk.pp_G2_one_precomp); - GT QAP = ppT::final_exponentiation(QAP_1 * QAP_23.unitary_inverse()); - if (QAP != GT::one()) - { - return false; - } - - G1_precomp proof_g_K_precomp = ppT::precompute_G1(proof.g_K); - G1_precomp proof_g_A_g_acc_C_precomp = ppT::precompute_G1((proof.g_A.g + acc) + proof.g_C.g); - Fqk K_1 = ppT::miller_loop(proof_g_K_precomp, pvk.vk_gamma_g2_precomp); - Fqk K_23 = ppT::double_miller_loop(proof_g_A_g_acc_C_precomp, pvk.vk_gamma_beta_g2_precomp, pvk.vk_gamma_beta_g1_precomp, proof_g_B_g_precomp); - GT K = ppT::final_exponentiation(K_1 * K_23.unitary_inverse()); - if (K != GT::one()) - { - return false; - } - - return true; -} - -template -bool r1cs_ppzksnark_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof) -{ - enter_block("Call to r1cs_ppzksnark_verifier_weak_IC"); - r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(vk); - bool result = r1cs_ppzksnark_online_verifier_weak_IC(pvk, primary_input, proof); - leave_block("Call to r1cs_ppzksnark_verifier_weak_IC"); - return result; -} - -template -bool r1cs_ppzksnark_online_verifier_strong_IC(const r1cs_ppzksnark_processed_verification_key &pvk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof) -{ - bool result = true; - enter_block("Call to r1cs_ppzksnark_online_verifier_strong_IC"); - - if (pvk.encoded_IC_query.domain_size() != primary_input.size()) - { - print_indent(); printf("Input length differs from expected (got %zu, expected %zu).\n", primary_input.size(), pvk.encoded_IC_query.domain_size()); - result = false; - } - else - { - result = r1cs_ppzksnark_online_verifier_weak_IC(pvk, primary_input, proof); - } - - leave_block("Call to r1cs_ppzksnark_online_verifier_strong_IC"); - return result; -} - -template -bool r1cs_ppzksnark_verifier_strong_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof) -{ - enter_block("Call to r1cs_ppzksnark_verifier_strong_IC"); - r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(vk); - bool result = r1cs_ppzksnark_online_verifier_strong_IC(pvk, primary_input, proof); - leave_block("Call to r1cs_ppzksnark_verifier_strong_IC"); - return result; -} - -template -bool r1cs_ppzksnark_affine_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, - const r1cs_ppzksnark_primary_input &primary_input, - const r1cs_ppzksnark_proof &proof) -{ - enter_block("Call to r1cs_ppzksnark_affine_verifier_weak_IC"); - assert(vk.encoded_IC_query.domain_size() >= primary_input.size()); - - affine_ate_G2_precomp pvk_pp_G2_one_precomp = ppT::affine_ate_precompute_G2(G2::one()); - affine_ate_G2_precomp pvk_vk_alphaA_g2_precomp = ppT::affine_ate_precompute_G2(vk.alphaA_g2); - affine_ate_G1_precomp pvk_vk_alphaB_g1_precomp = ppT::affine_ate_precompute_G1(vk.alphaB_g1); - affine_ate_G2_precomp pvk_vk_alphaC_g2_precomp = ppT::affine_ate_precompute_G2(vk.alphaC_g2); - affine_ate_G2_precomp pvk_vk_rC_Z_g2_precomp = ppT::affine_ate_precompute_G2(vk.rC_Z_g2); - affine_ate_G2_precomp pvk_vk_gamma_g2_precomp = ppT::affine_ate_precompute_G2(vk.gamma_g2); - affine_ate_G1_precomp pvk_vk_gamma_beta_g1_precomp = ppT::affine_ate_precompute_G1(vk.gamma_beta_g1); - affine_ate_G2_precomp pvk_vk_gamma_beta_g2_precomp = ppT::affine_ate_precompute_G2(vk.gamma_beta_g2); - - enter_block("Compute input-dependent part of A"); - const accumulation_vector > accumulated_IC = vk.encoded_IC_query.template accumulate_chunk >(primary_input.begin(), primary_input.end(), 0); - assert(accumulated_IC.is_fully_accumulated()); - const G1 &acc = accumulated_IC.first; - leave_block("Compute input-dependent part of A"); - - bool result = true; - enter_block("Check knowledge commitment for A is valid"); - affine_ate_G1_precomp proof_g_A_g_precomp = ppT::affine_ate_precompute_G1(proof.g_A.g); - affine_ate_G1_precomp proof_g_A_h_precomp = ppT::affine_ate_precompute_G1(proof.g_A.h); - Fqk kc_A_miller = ppT::affine_ate_e_over_e_miller_loop(proof_g_A_g_precomp, pvk_vk_alphaA_g2_precomp, proof_g_A_h_precomp, pvk_pp_G2_one_precomp); - GT kc_A = ppT::final_exponentiation(kc_A_miller); - - if (kc_A != GT::one()) - { - print_indent(); printf("Knowledge commitment for A query incorrect.\n"); - result = false; - } - leave_block("Check knowledge commitment for A is valid"); - - enter_block("Check knowledge commitment for B is valid"); - affine_ate_G2_precomp proof_g_B_g_precomp = ppT::affine_ate_precompute_G2(proof.g_B.g); - affine_ate_G1_precomp proof_g_B_h_precomp = ppT::affine_ate_precompute_G1(proof.g_B.h); - Fqk kc_B_miller = ppT::affine_ate_e_over_e_miller_loop(pvk_vk_alphaB_g1_precomp, proof_g_B_g_precomp, proof_g_B_h_precomp, pvk_pp_G2_one_precomp); - GT kc_B = ppT::final_exponentiation(kc_B_miller); - if (kc_B != GT::one()) - { - print_indent(); printf("Knowledge commitment for B query incorrect.\n"); - result = false; - } - leave_block("Check knowledge commitment for B is valid"); - - enter_block("Check knowledge commitment for C is valid"); - affine_ate_G1_precomp proof_g_C_g_precomp = ppT::affine_ate_precompute_G1(proof.g_C.g); - affine_ate_G1_precomp proof_g_C_h_precomp = ppT::affine_ate_precompute_G1(proof.g_C.h); - Fqk kc_C_miller = ppT::affine_ate_e_over_e_miller_loop(proof_g_C_g_precomp, pvk_vk_alphaC_g2_precomp, proof_g_C_h_precomp, pvk_pp_G2_one_precomp); - GT kc_C = ppT::final_exponentiation(kc_C_miller); - if (kc_C != GT::one()) - { - print_indent(); printf("Knowledge commitment for C query incorrect.\n"); - result = false; - } - leave_block("Check knowledge commitment for C is valid"); - - enter_block("Check QAP divisibility"); - affine_ate_G1_precomp proof_g_A_g_acc_precomp = ppT::affine_ate_precompute_G1(proof.g_A.g + acc); - affine_ate_G1_precomp proof_g_H_precomp = ppT::affine_ate_precompute_G1(proof.g_H); - Fqk QAP_miller = ppT::affine_ate_e_times_e_over_e_miller_loop(proof_g_H_precomp, pvk_vk_rC_Z_g2_precomp, proof_g_C_g_precomp, pvk_pp_G2_one_precomp, proof_g_A_g_acc_precomp, proof_g_B_g_precomp); - GT QAP = ppT::final_exponentiation(QAP_miller); - if (QAP != GT::one()) - { - print_indent(); printf("QAP divisibility check failed.\n"); - result = false; - } - leave_block("Check QAP divisibility"); - - enter_block("Check same coefficients were used"); - affine_ate_G1_precomp proof_g_K_precomp = ppT::affine_ate_precompute_G1(proof.g_K); - affine_ate_G1_precomp proof_g_A_g_acc_C_precomp = ppT::affine_ate_precompute_G1((proof.g_A.g + acc) + proof.g_C.g); - Fqk K_miller = ppT::affine_ate_e_times_e_over_e_miller_loop(proof_g_A_g_acc_C_precomp, pvk_vk_gamma_beta_g2_precomp, pvk_vk_gamma_beta_g1_precomp, proof_g_B_g_precomp, proof_g_K_precomp, pvk_vk_gamma_g2_precomp); - GT K = ppT::final_exponentiation(K_miller); - if (K != GT::one()) - { - print_indent(); printf("Same-coefficient check failed.\n"); - result = false; - } - leave_block("Check same coefficients were used"); - - leave_block("Call to r1cs_ppzksnark_affine_verifier_weak_IC"); - - return result; -} - -} // libsnark -#endif // R1CS_PPZKSNARK_TCC_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp deleted file mode 100644 index 4054b8e3b..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/** @file - ***************************************************************************** - - Declaration of public-parameter selector for the R1CS ppzkSNARK. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ - -#ifndef R1CS_PPZKSNARK_PARAMS_HPP_ -#define R1CS_PPZKSNARK_PARAMS_HPP_ - -#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" - -namespace libsnark { - -/** - * Below are various template aliases (used for convenience). - */ - -template -using r1cs_ppzksnark_constraint_system = r1cs_constraint_system >; - -template -using r1cs_ppzksnark_primary_input = r1cs_primary_input >; - -template -using r1cs_ppzksnark_auxiliary_input = r1cs_auxiliary_input >; - -} // libsnark - -#endif // R1CS_PPZKSNARK_PARAMS_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp deleted file mode 100644 index 6f8b575f2..000000000 --- a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/** @file - ***************************************************************************** - Test program that exercises the ppzkSNARK (first generator, then - prover, then verifier) on a synthetic R1CS instance. - - ***************************************************************************** - * @author This file is part of libsnark, developed by SCIPR Lab - * and contributors (see AUTHORS). - * @copyright MIT license (see LICENSE file) - *****************************************************************************/ -#include -#include - -#include "common/default_types/r1cs_ppzksnark_pp.hpp" -#include "common/profiling.hpp" -#include "common/utils.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp" - -using namespace libsnark; - -template -void test_r1cs_ppzksnark(size_t num_constraints, - size_t input_size) -{ - print_header("(enter) Test R1CS ppzkSNARK"); - - const bool test_serialization = true; - r1cs_example > example = generate_r1cs_example_with_binary_input >(num_constraints, input_size); - const bool bit = run_r1cs_ppzksnark(example, test_serialization); - assert(bit); - - print_header("(leave) Test R1CS ppzkSNARK"); -} - -int main() -{ - default_r1cs_ppzksnark_pp::init_public_params(); - start_profiling(); - - test_r1cs_ppzksnark(1000, 100); -} From 447ec28997d96dadcee9278a45e1436501111fbe Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 23 Jan 2020 18:45:41 -0500 Subject: [PATCH 002/220] Delete a lot of libsnark stuff --- configure.ac | 31 +---------------------- contrib/debian/copyright | 4 --- qa/hush/full_test_suite.py | 2 -- src/Makefile.am | 14 ++--------- src/Makefile.gtest.include | 2 +- src/Makefile.test.include | 2 +- src/Makefile.zcash.include | 1 - src/init.cpp | 9 ------- src/zcash/JoinSplit.cpp | 50 +------------------------------------- 9 files changed, 6 insertions(+), 109 deletions(-) diff --git a/configure.ac b/configure.ac index b57e0969f..e06bfb402 100644 --- a/configure.ac +++ b/configure.ac @@ -756,27 +756,6 @@ fi #AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) #AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) -# libsnark header layout is broken unless cpp's -I is passed with the -# libsnark directory, so for now we use this hideous workaround: -echo 'Hunting for libsnark include directory...' -[LIBSNARK_INCDIR="$(echo "$CPPFLAGS" | sed 's,^.*-I\([^ ]*/include\).*$,\1/libsnark,')"] -if test -d "$LIBSNARK_INCDIR"; then - echo "Found libsnark include directory: $LIBSNARK_INCDIR" -else -#AC_MSG_ERROR(libsnark include directory not found) -echo "libsnark include directory not found ($LIBSNARK_INCDIR)" -fi - -CPPFLAGS="-I$LIBSNARK_INCDIR $CPPFLAGS" - -# Now check for libsnark compilability using traditional autoconf tests: -if test x$TARGET_OS = xdarwin; then -AC_CHECK_HEADER([libsnark/gadgetlib1/gadget.hpp],,AC_MSG_ERROR(libsnark headers missing)) -AC_CHECK_LIB([snark],[main],LIBSNARK_LIBS=-lsnark, [AC_MSG_ERROR(libsnark missing)], [-lgmpxx]) -fi -#AC_CHECK_HEADER([libsnark/gadgetlib1/gadget.hpp],,AC_MSG_ERROR(libsnark headers missing)) -#AC_CHECK_LIB([snark],[main],LIBSNARK_LIBS=-lsnark, [AC_MSG_ERROR(libsnark missing)], [-lgmpxx]) - RUST_LIBS="-lrustzcash" case $host in *mingw*) @@ -796,13 +775,6 @@ AX_OPENMP( AC_DEFINE(HAVE_OPENMP, 0, [Define if OpenMP is enabled]) AM_CONDITIONAL([HAVE_OPENMP], [false])]) -# Gitian uses a config.site that sets depends_prefix, and then sets --prefix=/ -# build.sh just uses --prefix -if test x$depends_prefix != x; then - LIBSNARK_DEPINST="$depends_prefix" -else - LIBSNARK_DEPINST="$prefix" -fi # Additional Zcash flags AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) @@ -944,7 +916,6 @@ AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(GMP_LIBS) AC_SUBST(GMPXX_LIBS) -AC_SUBST(LIBSNARK_DEPINST) AC_SUBST(LIBZCASH_LIBS) AC_SUBST(PROTON_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile src/test/buildenv.py]) @@ -975,7 +946,7 @@ unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" -AC_CONFIG_SUBDIRS([src/secp256k1 src/snark src/univalue src/cryptoconditions]) +AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue src/cryptoconditions]) AC_OUTPUT diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 3c93ce7a9..9371b7022 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -16,10 +16,6 @@ Files: depends/sources/libsodium-*.tar.gz Copyright: 2013-2016 Frank Denis License: ISC -Files: depends/sources/libsnark-*.tar.gz -Copyright: 2012-2016 SCIPR Lab and contributors; 2016 The Zcash developers -License: Expat - Files: depends/sources/gmp-*.tar.bz2 Copyright: 1991, 1996, 1999, 2000, 2007 Free Software Foundation, Inc. License: LGPL diff --git a/qa/hush/full_test_suite.py b/qa/hush/full_test_suite.py index 0e8605cc3..fcbdf0cd8 100755 --- a/qa/hush/full_test_suite.py +++ b/qa/hush/full_test_suite.py @@ -138,7 +138,6 @@ STAGES = [ 'no-dot-so', 'util-test', 'secp256k1', - 'libsnark', 'univalue', 'rpc', ] @@ -150,7 +149,6 @@ STAGE_COMMANDS = { 'no-dot-so': ensure_no_dot_so_in_depends, 'util-test': util_test, 'secp256k1': ['make', '-C', repofile('src/secp256k1'), 'check'], - 'libsnark': ['make', '-C', repofile('src'), 'libsnark-tests'], 'univalue': ['make', '-C', repofile('src/univalue'), 'check'], 'rpc': [repofile('qa/pull-tester/rpc-tests.sh')], } diff --git a/src/Makefile.am b/src/Makefile.am index 2a304c5a5..c9f7cdc4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,8 +27,6 @@ BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src/asn -BITCOIN_INCLUDES += -I$(srcdir)/snark -BITCOIN_INCLUDES += -I$(srcdir)/snark/libsnark BITCOIN_INCLUDES += -I$(srcdir)/univalue/include if TARGET_WINDOWS @@ -48,7 +46,6 @@ LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBSECP256K1=secp256k1/libsecp256k1.la LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la -LIBSNARK=snark/libsnark.a LIBUNIVALUE=univalue/libunivalue.la LIBZCASH=libzcash.a @@ -77,12 +74,6 @@ if TARGET_DARWIN LIBSNARK_CONFIG_FLAGS += PLATFORM=darwin endif -$(LIBSNARK): $(wildcard snark/src/*) - $(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" - -libsnark-tests: $(wildcard snark/src/*) - $(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" - $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " @@ -139,7 +130,7 @@ LIBZCASH_H = \ zcash/Zcash.h \ zcash/zip32.h -.PHONY: FORCE collate-libsnark check-symbols check-security +.PHONY: FORCE check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ addressindex.h \ @@ -708,12 +699,11 @@ CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno */*.gcno wal DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb snark +EXTRA_DIST = leveldb clean-local: -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean - -$(MAKE) -C snark clean -$(MAKE) -C univalue clean rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno -rm -f config.h diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index cb9aa844a..1f1b511db 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -63,7 +63,7 @@ if ENABLE_WALLET komodo_gtest_LDADD += $(LIBBITCOIN_WALLET) endif -komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS) +komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) if ENABLE_PROTON komodo_gtest_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 59c66ad43..14324b02b 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -123,7 +123,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C $(LIBLEVELDB) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS) +test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ diff --git a/src/Makefile.zcash.include b/src/Makefile.zcash.include index da5b4344d..0eb4582c1 100644 --- a/src/Makefile.zcash.include +++ b/src/Makefile.zcash.include @@ -9,7 +9,6 @@ zcash_GenerateParams_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) zcash_GenerateParams_LDADD = \ $(BOOST_LIBS) \ $(LIBZCASH) \ - $(LIBSNARK) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) diff --git a/src/init.cpp b/src/init.cpp index 36ed5e0cb..aaa1aa12a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -79,8 +79,6 @@ #include #include -#include - #if ENABLE_ZMQ #include "zmq/zmqnotificationinterface.h" #endif @@ -569,9 +567,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); } - // Disabled until we can lock notes and also tune performance of libsnark which by default uses multiple threads - //strUsage += HelpMessageOpt("-rpcasyncthreads=", strprintf(_("Set the number of threads to service Async RPC calls (default: %d)"), 1)); - if (mode == HMM_BITCOIND) { strUsage += HelpMessageGroup(_("Metrics Options (only if -daemon and -printtoconsole are not set):")); strUsage += HelpMessageOpt("-showmetrics", _("Show metrics on stdout (default: 1 if running in a console, 0 otherwise)")); @@ -1456,10 +1451,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } //fprintf(stderr,"%s tik15\n", __FUNCTION__); - // These must be disabled for now, they are buggy and we probably don't - // want any of libsnark's profiling in production anyway. - libsnark::inhibit_profiling_info = true; - libsnark::inhibit_profiling_counters = true; if ( KOMODO_NSPV_FULLNODE ) { diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index ac59ccfa3..d24f2174f 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -10,10 +10,6 @@ #include #include #include -#include -#include -#include -#include #include "tinyformat.h" #include "sync.h" #include "amount.h" @@ -321,51 +317,7 @@ public: return proof; } - if (!computeProof) { - return PHGRProof(); - } - - protoboard pb; - { - joinsplit_gadget g(pb); - g.generate_r1cs_constraints(); - g.generate_r1cs_witness( - phi, - rt, - h_sig, - inputs, - out_notes, - vpub_old, - vpub_new - ); - } - - // The constraint system must be satisfied or there is an unimplemented - // or incorrect sanity check above. Or the constraint system is broken! - assert(pb.is_satisfied()); - - // TODO: These are copies, which is not strictly necessary. - std::vector primary_input = pb.primary_input(); - std::vector aux_input = pb.auxiliary_input(); - - // Swap A and B if it's beneficial (less arithmetic in G2) - // In our circuit, we already know that it's beneficial - // to swap, but it takes so little time to perform this - // estimate that it doesn't matter if we check every time. - pb.constraint_system.swap_AB_if_beneficial(); - - std::ifstream fh(pkPath, std::ios::binary); - - if(!fh.is_open()) { - throw std::runtime_error(strprintf("could not load param file at %s", pkPath)); - } - - return PHGRProof(r1cs_ppzksnark_prover_streaming( - fh, - primary_input, - aux_input, - pb.constraint_system - )); + throw std::invalid_argument("Cannot create non-Groth16 Sprout proofs"); } }; From 4a3a7acc90b9fdcbae631fad6b2fb71ffb250054 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 05:43:11 -0500 Subject: [PATCH 003/220] Remove more libsnark stuff --- src/zcash/JoinSplit.cpp | 218 +++++++++------------------------------- src/zcash/JoinSplit.hpp | 20 +--- 2 files changed, 48 insertions(+), 190 deletions(-) diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index d24f2174f..0a052209a 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -13,131 +13,22 @@ #include "tinyformat.h" #include "sync.h" #include "amount.h" -extern int64_t MAX_MONEY; #include "librustzcash.h" #include "streams.h" #include "version.h" -using namespace libsnark; - namespace libzcash { -#include "zcash/circuit/gadget.tcc" - static CCriticalSection cs_ParamsIO; -template -void saveToFile(const std::string path, T& obj) { - LOCK(cs_ParamsIO); - - std::stringstream ss; - ss << obj; - std::ofstream fh; - fh.open(path, std::ios::binary); - ss.rdbuf()->pubseekpos(0, std::ios_base::out); - fh << ss.rdbuf(); - fh.flush(); - fh.close(); -} - -template -void loadFromFile(const std::string path, T& objIn) { - LOCK(cs_ParamsIO); - - std::stringstream ss; - std::ifstream fh(path, std::ios::binary); - - if(!fh.is_open()) { - throw std::runtime_error(strprintf("could not load param file at %s", path)); - } - - ss << fh.rdbuf(); - fh.close(); - - ss.rdbuf()->pubseekpos(0, std::ios_base::in); - - T obj; - ss >> obj; - - objIn = std::move(obj); -} - template class JoinSplitCircuit : public JoinSplit { public: - typedef default_r1cs_ppzksnark_pp ppzksnark_ppT; - typedef Fr FieldT; - - r1cs_ppzksnark_verification_key vk; - r1cs_ppzksnark_processed_verification_key vk_precomp; - std::string pkPath; - - JoinSplitCircuit(const std::string vkPath, const std::string pkPath) : pkPath(pkPath) { - loadFromFile(vkPath, vk); - vk_precomp = r1cs_ppzksnark_verifier_process_vk(vk); - } + JoinSplitCircuit() {} ~JoinSplitCircuit() {} - static void generate(const std::string r1csPath, - const std::string vkPath, - const std::string pkPath) - { - protoboard pb; - - joinsplit_gadget g(pb); - g.generate_r1cs_constraints(); - - auto r1cs = pb.get_constraint_system(); - - saveToFile(r1csPath, r1cs); - - r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(r1cs); - - saveToFile(vkPath, keypair.vk); - saveToFile(pkPath, keypair.pk); - } - - bool verify( - const PHGRProof& proof, - ProofVerifier& verifier, - const uint256& joinSplitPubKey, - const uint256& randomSeed, - const std::array& macs, - const std::array& nullifiers, - const std::array& commitments, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt - ) { - try { - auto r1cs_proof = proof.to_libsnark_proof>(); - - uint256 h_sig = this->h_sig(randomSeed, nullifiers, joinSplitPubKey); - - auto witness = joinsplit_gadget::witness_map( - rt, - h_sig, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new - ); - - return verifier.check( - vk, - vk_precomp, - witness, - r1cs_proof - ); - } catch (...) { - return false; - } - } - SproutProof prove( - bool makeGrothProof, const std::array& inputs, const std::array& outputs, std::array& out_notes, @@ -268,74 +159,59 @@ public: out_macs[i] = PRF_pk(inputs[i].key, i, h_sig); } - if (makeGrothProof) { - if (!computeProof) { - return GrothProof(); - } - - GrothProof proof; - - CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION); - ss1 << inputs[0].witness.path(); - std::vector auth1(ss1.begin(), ss1.end()); - - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << inputs[1].witness.path(); - std::vector auth2(ss2.begin(), ss2.end()); - - librustzcash_sprout_prove( - proof.begin(), - - phi.begin(), - rt.begin(), - h_sig.begin(), - - inputs[0].key.begin(), - inputs[0].note.value(), - inputs[0].note.rho.begin(), - inputs[0].note.r.begin(), - auth1.data(), - - inputs[1].key.begin(), - inputs[1].note.value(), - inputs[1].note.rho.begin(), - inputs[1].note.r.begin(), - auth2.data(), - - out_notes[0].a_pk.begin(), - out_notes[0].value(), - out_notes[0].r.begin(), - - out_notes[1].a_pk.begin(), - out_notes[1].value(), - out_notes[1].r.begin(), - - vpub_old, - vpub_new - ); - - return proof; + if (!computeProof) { + return GrothProof(); } - throw std::invalid_argument("Cannot create non-Groth16 Sprout proofs"); + GrothProof proof; + + CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION); + ss1 << inputs[0].witness.path(); + std::vector auth1(ss1.begin(), ss1.end()); + + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << inputs[1].witness.path(); + std::vector auth2(ss2.begin(), ss2.end()); + + librustzcash_sprout_prove( + proof.begin(), + + phi.begin(), + rt.begin(), + h_sig.begin(), + + inputs[0].key.begin(), + inputs[0].note.value(), + inputs[0].note.rho.begin(), + inputs[0].note.r.begin(), + auth1.data(), + + inputs[1].key.begin(), + inputs[1].note.value(), + inputs[1].note.rho.begin(), + inputs[1].note.r.begin(), + auth2.data(), + + out_notes[0].a_pk.begin(), + out_notes[0].value(), + out_notes[0].r.begin(), + + out_notes[1].a_pk.begin(), + out_notes[1].value(), + out_notes[1].r.begin(), + + vpub_old, + vpub_new + ); + + return proof; } }; template -void JoinSplit::Generate(const std::string r1csPath, - const std::string vkPath, - const std::string pkPath) +JoinSplit* JoinSplit::Prepared() { - initialize_curve_params(); - JoinSplitCircuit::generate(r1csPath, vkPath, pkPath); -} - -template -JoinSplit* JoinSplit::Prepared(const std::string vkPath, - const std::string pkPath) -{ - initialize_curve_params(); - return new JoinSplitCircuit(vkPath, pkPath); + return new JoinSplitCircuit(); } template diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index c37926ede..09e31570f 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -56,11 +56,7 @@ class JoinSplit { public: virtual ~JoinSplit() {} - static void Generate(const std::string r1csPath, - const std::string vkPath, - const std::string pkPath); - static JoinSplit* Prepared(const std::string vkPath, - const std::string pkPath); + static JoinSplit* Prepared(); static uint256 h_sig(const uint256& randomSeed, const std::array& nullifiers, @@ -69,7 +65,6 @@ public: // Compute nullifiers, macs, note commitments & encryptions, and SNARK proof virtual SproutProof prove( - bool makeGrothProof, const std::array& inputs, const std::array& outputs, std::array& out_notes, @@ -90,19 +85,6 @@ public: uint256 *out_esk = nullptr ) = 0; - virtual bool verify( - const PHGRProof& proof, - ProofVerifier& verifier, - const uint256& joinSplitPubKey, - const uint256& randomSeed, - const std::array& hmacs, - const std::array& nullifiers, - const std::array& commitments, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt - ) = 0; - protected: JoinSplit() {} }; From 7e078e58c16f46e924df418bda004f53e074db02 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 05:48:43 -0500 Subject: [PATCH 004/220] Remove more libsnark stuff from the build system --- src/Makefile.am | 12 ------------ src/Makefile.zcash.include | 1 - 2 files changed, 13 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c9f7cdc4d..25f48a557 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,15 +65,6 @@ endif $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " -LIBSNARK_CXXFLAGS = $(AM_CXXFLAGS) $(PIC_FLAGS) -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all -LIBSNARK_CONFIG_FLAGS = CURVE=ALT_BN128 NO_PROCPS=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT NO_COPY_DEPINST=1 NO_COMPILE_LIBGTEST=1 -if HAVE_OPENMP -LIBSNARK_CONFIG_FLAGS += MULTICORE=1 -endif -if TARGET_DARWIN -LIBSNARK_CONFIG_FLAGS += PLATFORM=darwin -endif - $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " @@ -520,7 +511,6 @@ komodod_LDADD = \ $(LIBBITCOIN_PROTON) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH) \ - $(LIBSNARK) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ $(LIBSECP256K1) \ @@ -605,7 +595,6 @@ wallet_utility_LDADD = \ $(BDB_LIBS) \ $(CRYPTO_LIBS) \ $(LIBZCASH) \ - $(LIBSNARK) \ $(LIBZCASH_LIBS)\ $(LIBCRYPTOCONDITIONS) endif @@ -627,7 +616,6 @@ komodo_tx_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBSECP256K1) \ $(LIBZCASH) \ - $(LIBSNARK) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) \ $(LIBCRYPTOCONDITIONS) diff --git a/src/Makefile.zcash.include b/src/Makefile.zcash.include index 0eb4582c1..c77fe121c 100644 --- a/src/Makefile.zcash.include +++ b/src/Makefile.zcash.include @@ -20,7 +20,6 @@ zcash_CreateJoinSplit_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) zcash_CreateJoinSplit_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBZCASH) \ - $(LIBSNARK) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(BOOST_LIBS) \ From 4d965f53eb2a0948f3c4db37a6ef783a1ede9152 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 06:32:13 -0500 Subject: [PATCH 005/220] A bunch more libsnark deletions/updates --- build-aux/m4/ax_openmp.m4 | 123 ----- configure.ac | 33 +- depends/packages/libgmp.mk | 44 -- depends/packages/packages.mk | 4 +- qa/hush/full-test-suite.sh | 18 +- src/Makefile.am | 10 +- src/Makefile.zcash.include | 29 - src/gtest/main.cpp | 10 +- src/gtest/test_circuit.cpp | 183 ------- src/gtest/test_joinsplit.cpp | 61 +-- src/gtest/test_merkletree.cpp | 90 +--- src/gtest/test_proofs.cpp | 702 ------------------------- src/primitives/transaction.h | 1 + src/zcash/CreateJoinSplit.cpp | 40 -- src/zcash/GenerateParams.cpp | 26 - src/zcash/IncrementalMerkleTree.cpp | 788 ++++++++++++++++++++++++++++ src/zcash/IncrementalMerkleTree.hpp | 13 +- src/zcash/Proof.cpp | 233 -------- src/zcash/Proof.hpp | 35 -- src/zcash/circuit/commitment.tcc | 100 ---- src/zcash/circuit/gadget.tcc | 349 ------------ src/zcash/circuit/merkle.tcc | 60 --- src/zcash/circuit/note.tcc | 244 --------- src/zcash/circuit/prfs.tcc | 109 ---- src/zcash/circuit/utils.tcc | 75 --- src/zcbenchmarks.cpp | 23 +- src/zcbenchmarks.h | 2 +- zcutil/build-win.sh | 2 +- 28 files changed, 847 insertions(+), 2560 deletions(-) delete mode 100644 build-aux/m4/ax_openmp.m4 delete mode 100644 depends/packages/libgmp.mk delete mode 100644 src/Makefile.zcash.include delete mode 100644 src/gtest/test_circuit.cpp delete mode 100644 src/gtest/test_proofs.cpp delete mode 100644 src/zcash/CreateJoinSplit.cpp delete mode 100644 src/zcash/GenerateParams.cpp delete mode 100644 src/zcash/circuit/commitment.tcc delete mode 100644 src/zcash/circuit/gadget.tcc delete mode 100644 src/zcash/circuit/merkle.tcc delete mode 100644 src/zcash/circuit/note.tcc delete mode 100644 src/zcash/circuit/prfs.tcc delete mode 100644 src/zcash/circuit/utils.tcc diff --git a/build-aux/m4/ax_openmp.m4 b/build-aux/m4/ax_openmp.m4 deleted file mode 100644 index 866e1d664..000000000 --- a/build-aux/m4/ax_openmp.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_openmp.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro tries to find out how to compile programs that use OpenMP a -# standard API and set of compiler directives for parallel programming -# (see http://www-unix.mcs/) -# -# On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS -# output variable to the flag (e.g. -omp) used both to compile *and* link -# OpenMP programs in the current language. -# -# NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. -# -# If you want to compile everything with OpenMP, you should set: -# -# CFLAGS="$CFLAGS $OPENMP_CFLAGS" -# #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" -# #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" -# -# (depending on the selected language). -# -# The user can override the default choice by setting the corresponding -# environment variable (e.g. OPENMP_CFLAGS). -# -# ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is -# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is -# not found. If ACTION-IF-FOUND is not specified, the default action will -# define HAVE_OPENMP. -# -# LICENSE -# -# Copyright (c) 2008 Steven G. Johnson -# Copyright (c) 2015 John W. Peterson -# Copyright (c) 2016 Nick R. Papior -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 13 - -AC_DEFUN([AX_OPENMP], [ -AC_PREREQ([2.69]) dnl for _AC_LANG_PREFIX - -AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS -ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown -# Flags to try: -fopenmp (gcc), -mp (SGI & PGI), -# -qopenmp (icc>=15), -openmp (icc), -# -xopenmp (Sun), -omp (Tru64), -# -qsmp=omp (AIX), -# none -ax_openmp_flags="-fopenmp -openmp -qopenmp -mp -xopenmp -omp -qsmp=omp none" -if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then - ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" -fi -for ax_openmp_flag in $ax_openmp_flags; do - case $ax_openmp_flag in - none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; - *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; - esac - AC_LINK_IFELSE([AC_LANG_SOURCE([[ -@%:@include - -static void -parallel_fill(int * data, int n) -{ - int i; -@%:@pragma omp parallel for - for (i = 0; i < n; ++i) - data[i] = i; -} - -int -main() -{ - int arr[100000]; - omp_set_num_threads(2); - parallel_fill(arr, 100000); - return 0; -} -]])],[ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break],[]) -done -[]_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS -]) -if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then - m4_default([$2],:) -else - if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then - OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp - fi - m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) -fi -])dnl AX_OPENMP diff --git a/configure.ac b/configure.ac index e06bfb402..9b5c0335b 100644 --- a/configure.ac +++ b/configure.ac @@ -700,7 +700,7 @@ if test x$use_pkgconfig = xyes; then ) else # BUG: Fix this: - echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, libgmp' + echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++' AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -740,22 +740,6 @@ else fi fi -# These packages don't provide pkgconfig config files across all -# platforms, so we use older autoconf detection mechanisms: -if test x$TARGET_OS = xdarwin; then -AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) -AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) - -AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) -AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) -fi - -#AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) -#AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) - -#AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) -#AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) - RUST_LIBS="-lrustzcash" case $host in *mingw*) @@ -765,23 +749,12 @@ case $host in ;; esac -dnl Check for OpenMP support -AX_OPENMP( - [AC_DEFINE(HAVE_OPENMP, 1, [Define if OpenMP is enabled]) - AM_CONDITIONAL([HAVE_OPENMP], [true]) - CPPFLAGS="$CPPFLAGS -DMULTICORE" - CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS"], - [AC_MSG_WARN([OpenMP not supported, disabling multithreading]) - AC_DEFINE(HAVE_OPENMP, 0, [Define if OpenMP is enabled]) - AM_CONDITIONAL([HAVE_OPENMP], [false])]) - - -# Additional Zcash flags +# Additional Zcash internals flags AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) -LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" +LIBZCASH_LIBS="$BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" AC_MSG_CHECKING([whether to build komodod]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) diff --git a/depends/packages/libgmp.mk b/depends/packages/libgmp.mk deleted file mode 100644 index acd5d4c0e..000000000 --- a/depends/packages/libgmp.mk +++ /dev/null @@ -1,44 +0,0 @@ -package=libgmp - -ifeq ($(host_os),mingw32) -$(package)_download_path=https://github.com/joshuayabut/$(package)/archive -$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz -$(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f -$(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -else ifeq ($(build_os),darwin) -$(package)_download_path=https://github.com/ca333/$(package)/archive -$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz -$(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c -$(package)_git_commit=aece03c7b6967f91f3efdac8c673f55adff53ab1 -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -else -$(package)_version=6.1.1 -$(package)_download_path=https://github.com/MyHush/libgmp/releases/download/v6.1.1 -$(package)_file_name=gmp-$($(package)_version).tar.bz2 -$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6 -$(package)_dependencies= -$(package)_config_opts=--enable-cxx --disable-shared -endif - -define $(package)_config_cmds - $($(package)_autoconf) --host=$(host) --build=$(build) -endef - -ifeq ($(build_os),darwin) -define $(package)_build_cmds - $(MAKE) -endef -else -define $(package)_build_cmds - $(MAKE) CPPFLAGS='-fPIC' -endef -endif - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install ; echo '=== staging find for $(package):' ; find $($(package)_staging_dir) -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 1c1a50668..5aee77182 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,10 +1,10 @@ rust_packages := rust librustzcash ifeq ($(build_os),darwin) - zcash_packages := libsnark libgmp libsodium utfcpp + zcash_packages := libsnark libsodium utfcpp else proton_packages := proton - zcash_packages := libgmp libsodium utfcpp + zcash_packages := libsodium utfcpp endif rust_crates := \ diff --git a/qa/hush/full-test-suite.sh b/qa/hush/full-test-suite.sh index 0a19b32c8..5c048ff9d 100755 --- a/qa/hush/full-test-suite.sh +++ b/qa/hush/full-test-suite.sh @@ -64,21 +64,19 @@ def check_security_hardening(): # PIE, RELRO, Canary, and NX are tested by make check-security. ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 - ret &= test_rpath_runpath('src/zcashd') - ret &= test_rpath_runpath('src/zcash-cli') - ret &= test_rpath_runpath('src/zcash-gtest') - ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/hushd') + ret &= test_rpath_runpath('src/hush-cli') + ret &= test_rpath_runpath('src/hush-gtest') + ret &= test_rpath_runpath('src/hush-tx') ret &= test_rpath_runpath('src/test/test_bitcoin') - ret &= test_rpath_runpath('src/zcash/GenerateParams') # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE # is enabled for the entire binary. See issue #915. - ret &= test_fortify_source('src/zcashd') - ret &= test_fortify_source('src/zcash-cli') - ret &= test_fortify_source('src/zcash-gtest') - ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/hushd') + ret &= test_fortify_source('src/hush-cli') + ret &= test_fortify_source('src/hush-gtest') + ret &= test_fortify_source('src/hush-tx') ret &= test_fortify_source('src/test/test_bitcoin') - ret &= test_fortify_source('src/zcash/GenerateParams') return ret diff --git a/src/Makefile.am b/src/Makefile.am index 25f48a557..8863b6e98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -633,15 +633,9 @@ libzcash_a_SOURCES = \ zcash/Note.cpp \ zcash/prf.cpp \ zcash/util.cpp \ - zcash/zip32.cpp \ - zcash/circuit/commitment.tcc \ - zcash/circuit/gadget.tcc \ - zcash/circuit/merkle.tcc \ - zcash/circuit/note.tcc \ - zcash/circuit/prfs.tcc \ - zcash/circuit/utils.tcc + zcash/zip32.cpp -libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) +libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) #libzcash_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) #libzcash_a_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) diff --git a/src/Makefile.zcash.include b/src/Makefile.zcash.include deleted file mode 100644 index c77fe121c..000000000 --- a/src/Makefile.zcash.include +++ /dev/null @@ -1,29 +0,0 @@ -noinst_PROGRAMS += \ - zcash/GenerateParams \ - zcash/CreateJoinSplit - -# tool for generating our public parameters -zcash_GenerateParams_SOURCES = zcash/GenerateParams.cpp -zcash_GenerateParams_CPPFLAGS = $(AM_CPPFLAGS) -zcash_GenerateParams_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -zcash_GenerateParams_LDADD = \ - $(BOOST_LIBS) \ - $(LIBZCASH) \ - $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ - $(LIBZCASH_LIBS) - -# tool for profiling the creation of joinsplits -zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp -zcash_CreateJoinSplit_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -zcash_CreateJoinSplit_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -zcash_CreateJoinSplit_LDADD = \ - $(LIBBITCOIN_COMMON) \ - $(LIBZCASH) \ - $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ - $(BOOST_LIBS) \ - $(LIBZCASH_LIBS) \ - $(LIBCRYPTOCONDITIONS) \ - $(LIBSECP256K1) - diff --git a/src/gtest/main.cpp b/src/gtest/main.cpp index bdebedeb5..28114834c 100644 --- a/src/gtest/main.cpp +++ b/src/gtest/main.cpp @@ -5,9 +5,6 @@ #include "zcash/JoinSplit.hpp" #include "util.h" -#include -#include - #include "librustzcash.h" struct ECCryptoClosure @@ -23,12 +20,7 @@ int main(int argc, char **argv) { assert(init_and_check_sodium() != -1); ECC_Start(); - libsnark::default_r1cs_ppzksnark_pp::init_public_params(); - libsnark::inhibit_profiling_info = true; - libsnark::inhibit_profiling_counters = true; - boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; - boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; - params = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); + params = ZCJoinSplit::Prepared(); boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params"; boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params"; diff --git a/src/gtest/test_circuit.cpp b/src/gtest/test_circuit.cpp deleted file mode 100644 index ab2a8ecb6..000000000 --- a/src/gtest/test_circuit.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include "uint256.h" - -#include "zcash/util.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "zcash/IncrementalMerkleTree.hpp" - -using namespace libsnark; -using namespace libzcash; - -#include "zcash/circuit/utils.tcc" -#include "zcash/circuit/merkle.tcc" - -template -void test_value_equals(uint64_t i) { - protoboard pb; - pb_variable_array num; - num.allocate(pb, 64, ""); - num.fill_with_bits(pb, uint64_to_bool_vector(i)); - pb.add_r1cs_constraint(r1cs_constraint( - packed_addition(num), - FieldT::one(), - FieldT::one() * i - ), ""); - ASSERT_TRUE(pb.is_satisfied()); -} - -TEST(circuit, values) -{ - typedef Fr FieldT; - test_value_equals(0); - test_value_equals(1); - test_value_equals(3); - test_value_equals(5391); - test_value_equals(883128374); - test_value_equals(173419028459); - test_value_equals(2205843009213693953); -} - -TEST(circuit, endianness) -{ - std::vector before = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63 - }; - auto result = swap_endianness_u64(before); - - std::vector after = { - 56, 57, 58, 59, 60, 61, 62, 63, - 48, 49, 50, 51, 52, 53, 54, 55, - 40, 41, 42, 43, 44, 45, 46, 47, - 32, 33, 34, 35, 36, 37, 38, 39, - 24, 25, 26, 27, 28, 29, 30, 31, - 16, 17, 18, 19, 20, 21, 22, 23, - 8, 9, 10, 11, 12, 13, 14, 15, - 0, 1, 2, 3, 4, 5, 6, 7 - }; - - EXPECT_EQ(after, result); - - std::vector bad = {0, 1, 2, 3}; - - ASSERT_THROW(swap_endianness_u64(bad), std::length_error); -} - -template -bool test_merkle_gadget( - bool enforce_a, - bool enforce_b, - bool write_root_first -) -{ - protoboard pb; - digest_variable root(pb, 256, "root"); - pb.set_input_sizes(256); - - digest_variable commitment1(pb, 256, "commitment1"); - digest_variable commitment2(pb, 256, "commitment2"); - - pb_variable commitment1_read; - commitment1_read.allocate(pb); - pb_variable commitment2_read; - commitment2_read.allocate(pb); - - merkle_tree_gadget mgadget1(pb, commitment1, root, commitment1_read); - merkle_tree_gadget mgadget2(pb, commitment2, root, commitment2_read); - - commitment1.generate_r1cs_constraints(); - commitment2.generate_r1cs_constraints(); - root.generate_r1cs_constraints(); - mgadget1.generate_r1cs_constraints(); - mgadget2.generate_r1cs_constraints(); - - SproutMerkleTree tree; - uint256 commitment1_data = uint256S("54d626e08c1c802b305dad30b7e54a82f102390cc92c7d4db112048935236e9c"); - uint256 commitment2_data = uint256S("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"); - tree.append(commitment1_data); - auto wit1 = tree.witness(); - tree.append(commitment2_data); - wit1.append(commitment2_data); - auto wit2 = tree.witness(); - auto expected_root = tree.root(); - tree.append(uint256S("3e243c8798678570bb8d42616c23a536af44be15c4eef073490c2a44ae5f32c3")); - auto unexpected_root = tree.root(); - tree.append(uint256S("26d9b20c7f1c3d2528bbcd43cd63344b0afd3b6a0a8ebd37ec51cba34907bec7")); - auto badwit1 = tree.witness(); - tree.append(uint256S("02c2467c9cd15e0d150f74cd636505ed675b0b71b66a719f6f52fdb49a5937bb")); - auto badwit2 = tree.witness(); - - // Perform the test - - pb.val(commitment1_read) = enforce_a ? FieldT::one() : FieldT::zero(); - pb.val(commitment2_read) = enforce_b ? FieldT::one() : FieldT::zero(); - - commitment1.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment1_data)); - commitment2.bits.fill_with_bits(pb, uint256_to_bool_vector(commitment2_data)); - - if (write_root_first) { - root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root)); - } - - mgadget1.generate_r1cs_witness(wit1.path()); - mgadget2.generate_r1cs_witness(wit2.path()); - - // Overwrite with our expected root - root.bits.fill_with_bits(pb, uint256_to_bool_vector(expected_root)); - - return pb.is_satisfied(); -} - -TEST(circuit, merkle_tree_gadget_weirdness) -{ - /* - The merkle tree gadget takes a leaf in the merkle tree (the Note commitment), - a merkle tree authentication path, and a root (anchor). It also takes a parameter - called read_success, which is used to determine if the commitment actually needs to - appear in the tree. - - If two input notes use the same root (which our protocol does) then if `read_success` - is disabled on the first note but enabled on the second note (i.e., the first note - has value of zero and second note has nonzero value) then there is an edge case in - the witnessing behavior. The first witness will accidentally constrain the root to - equal null (the default value of the anchor) and the second witness will actually - copy the bits, violating the constraint system. - - Notice that this edge case is not in the constraint system but in the witnessing - behavior. - */ - - typedef Fr FieldT; - - // Test the normal case - ASSERT_TRUE(test_merkle_gadget(true, true, false)); - ASSERT_TRUE(test_merkle_gadget(true, true, true)); - - // Test the case where the first commitment is enforced but the second isn't - // Works because the first read is performed before the second one - ASSERT_TRUE(test_merkle_gadget(true, false, false)); - ASSERT_TRUE(test_merkle_gadget(true, false, true)); - - // Test the case where the first commitment isn't enforced but the second is - // Doesn't work because the first multipacker witnesses the existing root (which - // is null) - ASSERT_TRUE(!test_merkle_gadget(false, true, false)); - - // Test the last again, except this time write the root first. - ASSERT_TRUE(test_merkle_gadget(false, true, true)); -} diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 4de2fc471..8032fc972 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -22,10 +22,9 @@ using namespace libzcash; extern ZCJoinSplit* params; -typedef std::array SproutProofs; -// Make both the PHGR and Groth proof for a Sprout statement, -// and store the results in JSDescription objects. -SproutProofs makeSproutProofs( +// Make the Groth proof for a Sprout statement, +// and store the result in a JSDescription object. +JSDescription makeSproutProof( ZCJoinSplit& js, const std::array& inputs, const std::array& outputs, @@ -34,25 +33,17 @@ SproutProofs makeSproutProofs( uint64_t vpub_new, const uint256& rt ){ - //Making the PHGR proof - JSDescription phgr(false, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); - //Making the Groth proof - JSDescription groth(true, js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); - - return {phgr, groth}; - + return JSDescription(js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); } -bool verifySproutProofs( +bool verifySproutProof( ZCJoinSplit& js, - const SproutProofs& jsdescs, + const JSDescription& jsdesc, const uint256& joinSplitPubKey ) { auto verifier = libzcash::ProofVerifier::Strict(); - bool phgrPassed = jsdescs[0].Verify(js, verifier, joinSplitPubKey); - bool grothPassed = jsdescs[1].Verify(js, verifier, joinSplitPubKey); - return phgrPassed && grothPassed; + return jsdesc.Verify(js, verifier, joinSplitPubKey); } @@ -73,7 +64,7 @@ void test_full_api(ZCJoinSplit* js) uint64_t vpub_new = 0; uint256 joinSplitPubKey = random_uint256(); uint256 rt = tree.root(); - SproutProofs jsdescs; + JSDescription jsdesc; { std::array inputs = { @@ -89,7 +80,7 @@ void test_full_api(ZCJoinSplit* js) std::array output_notes; // Perform the proofs - jsdescs = makeSproutProofs( + jsdesc = makeSproutProof( *js, inputs, outputs, @@ -101,13 +92,11 @@ void test_full_api(ZCJoinSplit* js) } // Verify both PHGR and Groth Proof: - ASSERT_TRUE(verifySproutProofs(*js, jsdescs, joinSplitPubKey)); + ASSERT_TRUE(verifySproutProof(*js, jsdesc, joinSplitPubKey)); - // Run tests using both phgr and groth as basis for field values - for (auto jsdesc : jsdescs) { SproutMerkleTree tree; - SproutProofs jsdescs2; + JSDescription jsdesc2; // Recipient should decrypt // Now the recipient should spend the money again auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey); @@ -153,7 +142,7 @@ void test_full_api(ZCJoinSplit* js) // Perform the proofs - jsdescs2 = makeSproutProofs( + jsdesc2 = makeSproutProof( *js, inputs, outputs, @@ -166,8 +155,8 @@ void test_full_api(ZCJoinSplit* js) } - // Verify both PHGR and Groth Proof: - ASSERT_TRUE(verifySproutProofs(*js, jsdescs2, joinSplitPubKey2)); + // Verify Groth Proof: + ASSERT_TRUE(verifySproutProof(*js, jsdesc2, joinSplitPubKey2)); } } @@ -191,28 +180,8 @@ void invokeAPI( std::array output_notes; - // PHGR - SproutProof proof = js->prove( - false, - inputs, - outputs, - output_notes, - ciphertexts, - ephemeralKey, - joinSplitPubKey, - randomSeed, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new, - rt, - false - ); - // Groth - proof = js->prove( - true, + SproutProof proof = js->prove( inputs, outputs, output_notes, diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index 23c39c044..ad3c2ad06 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -1,14 +1,12 @@ #include #include "test/data/merkle_roots.json.h" -#include "test/data/merkle_roots_empty.json.h" #include "test/data/merkle_serialization.json.h" #include "test/data/merkle_witness_serialization.json.h" #include "test/data/merkle_path.json.h" #include "test/data/merkle_commitments.json.h" #include "test/data/merkle_roots_sapling.json.h" -#include "test/data/merkle_roots_empty_sapling.json.h" #include "test/data/merkle_serialization_sapling.json.h" #include "test/data/merkle_witness_serialization_sapling.json.h" #include "test/data/merkle_path_sapling.json.h" @@ -26,17 +24,11 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "zcash/util.h" -#include -#include -#include -#include - #include #include "json_test_vectors.h" using namespace std; -using namespace libsnark; template<> void expect_deser_same(const SproutTestingWitness& expected) @@ -58,8 +50,7 @@ void test_tree( UniValue root_tests, UniValue ser_tests, UniValue witness_ser_tests, - UniValue path_tests, - bool libsnark_test + UniValue path_tests ) { size_t witness_ser_i = 0; @@ -115,55 +106,6 @@ void test_tree( } else { auto path = wit.path(); expect_test_vector(path_tests[path_i++], path); - - if (libsnark_test) { - typedef Fr FieldT; - - protoboard pb; - pb_variable_array positions; - digest_variable commitment(pb, 256, "commitment"); - digest_variable root(pb, 256, "root"); - positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "pos"); - merkle_authentication_path_variable> authvars(pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, "auth"); - merkle_tree_check_read_gadget> auth( - pb, INCREMENTAL_MERKLE_TREE_DEPTH_TESTING, positions, commitment, root, authvars, ONE, "path" - ); - commitment.generate_r1cs_constraints(); - root.generate_r1cs_constraints(); - authvars.generate_r1cs_constraints(); - auth.generate_r1cs_constraints(); - - std::vector commitment_bv; - { - uint256 witnessed_commitment = wit.element(); - std::vector commitment_v(witnessed_commitment.begin(), witnessed_commitment.end()); - commitment_bv = convertBytesVectorToVector(commitment_v); - } - - size_t path_index = convertVectorToInt(path.index); - - commitment.bits.fill_with_bits(pb, bit_vector(commitment_bv)); - positions.fill_with_bits_of_uint64(pb, path_index); - - authvars.generate_r1cs_witness(path_index, path.authentication_path); - auth.generate_r1cs_witness(); - - std::vector root_bv; - { - uint256 witroot = wit.root(); - std::vector root_v(witroot.begin(), witroot.end()); - root_bv = convertBytesVectorToVector(root_v); - } - - root.bits.fill_with_bits(pb, bit_vector(root_bv)); - - ASSERT_TRUE(pb.is_satisfied()); - - root_bv[0] = !root_bv[0]; - root.bits.fill_with_bits(pb, bit_vector(root_bv)); - - ASSERT_TRUE(!pb.is_satisfied()); - } } // Check witness serialization @@ -200,8 +142,7 @@ TEST(merkletree, vectors) { root_tests, ser_tests, witness_ser_tests, - path_tests, - true + path_tests ); } @@ -217,18 +158,19 @@ TEST(merkletree, SaplingVectors) { root_tests, ser_tests, witness_ser_tests, - path_tests, - false + path_tests ); } TEST(merkletree, emptyroots) { - UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty)); - libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots; + std::array computed; - for (size_t depth = 0; depth <= 64; depth++) { - expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); + computed.at(0) = libzcash::SHA256Compress::uncommitted(); + ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0)); + for (size_t d = 1; d <= 64; d++) { + computed.at(d) = libzcash::SHA256Compress::combine(computed.at(d-1), computed.at(d-1), d-1); + ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d)); } // Double check that we're testing (at least) all the empty roots we'll use. @@ -236,12 +178,14 @@ TEST(merkletree, emptyroots) { } TEST(merkletree, EmptyrootsSapling) { - UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty_sapling)); - libzcash::EmptyMerkleRoots<62, libzcash::PedersenHash> emptyroots; + std::array computed; - for (size_t depth = 0; depth <= 62; depth++) { - expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); + computed.at(0) = libzcash::PedersenHash::uncommitted(); + ASSERT_TRUE(emptyroots.empty_root(0) == computed.at(0)); + for (size_t d = 1; d <= 62; d++) { + computed.at(d) = libzcash::PedersenHash::combine(computed.at(d-1), computed.at(d-1), d-1); + ASSERT_TRUE(emptyroots.empty_root(d) == computed.at(d)); } // Double check that we're testing (at least) all the empty roots we'll use. @@ -249,7 +193,7 @@ TEST(merkletree, EmptyrootsSapling) { } TEST(merkletree, emptyroot) { - // This literal is the depth-20 empty tree root with the bytes reversed to + // This literal is the depth-29 empty tree root with the bytes reversed to // account for the fact that uint256S() loads a big-endian representation of // an integer which converted to little-endian internally. uint256 expected = uint256S("59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7"); @@ -258,7 +202,7 @@ TEST(merkletree, emptyroot) { } TEST(merkletree, EmptyrootSapling) { - // This literal is the depth-20 empty tree root with the bytes reversed to + // This literal is the depth-32 empty tree root with the bytes reversed to // account for the fact that uint256S() loads a big-endian representation of // an integer which converted to little-endian internally. uint256 expected = uint256S("3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb"); diff --git a/src/gtest/test_proofs.cpp b/src/gtest/test_proofs.cpp deleted file mode 100644 index 5b5c19395..000000000 --- a/src/gtest/test_proofs.cpp +++ /dev/null @@ -1,702 +0,0 @@ -#include -#include "zcash/Proof.hpp" - -#include - -#include -#include -#include - -using namespace libzcash; - -typedef libsnark::default_r1cs_ppzksnark_pp curve_pp; -typedef libsnark::default_r1cs_ppzksnark_pp::G1_type curve_G1; -typedef libsnark::default_r1cs_ppzksnark_pp::G2_type curve_G2; -typedef libsnark::default_r1cs_ppzksnark_pp::GT_type curve_GT; -typedef libsnark::default_r1cs_ppzksnark_pp::Fp_type curve_Fr; -typedef libsnark::default_r1cs_ppzksnark_pp::Fq_type curve_Fq; -typedef libsnark::default_r1cs_ppzksnark_pp::Fqe_type curve_Fq2; - -#include "streams.h" -#include "version.h" -#include "utilstrencodings.h" - -TEST(proofs, g1_pairing_at_infinity) -{ - for (size_t i = 0; i < 100; i++) { - auto r1 = curve_G1::random_element(); - auto r2 = curve_G2::random_element(); - ASSERT_TRUE( - curve_pp::reduced_pairing(curve_G1::zero(), r2) == - curve_GT::one() - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2) - ) - ) == - curve_GT::one() - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(r1), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2) - ) - ) == - curve_pp::reduced_pairing(r1, r2) - ); - ASSERT_TRUE( - curve_pp::final_exponentiation( - curve_pp::double_miller_loop( - curve_pp::precompute_G1(curve_G1::zero()), - curve_pp::precompute_G2(r2), - curve_pp::precompute_G1(r1), - curve_pp::precompute_G2(r2) - ) - ) == - curve_pp::reduced_pairing(r1, r2) - ); - } -} - -TEST(proofs, g2_subgroup_check) -{ - // all G2 elements are order r - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * curve_G2::random_element() == curve_G2::zero()); - - // but that doesn't mean all elements that satisfy the curve equation are in G2... - curve_G2 p = curve_G2::one(); - - while (1) { - // This will construct an order r(2q-r) point with high probability - p.X = curve_Fq2::random_element(); - try { - p.Y = ((p.X.squared() * p.X) + libsnark::alt_bn128_twist_coeff_b).sqrt(); - break; - } catch(...) {} - } - - ASSERT_TRUE(p.is_well_formed()); // it's on the curve - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p != curve_G2::zero()); // but not the order r subgroup.. - - { - // libsnark unfortunately doesn't check, and the pairing will complete - auto e = curve_Fr("149"); - auto a = curve_pp::reduced_pairing(curve_G1::one(), p); - auto b = curve_pp::reduced_pairing(e * curve_G1::one(), p); - - // though it will not preserve bilinearity - ASSERT_TRUE((a^e) != b); - } - - { - // so, our decompression API should not allow you to decompress G2 elements of that form! - CompressedG2 badp(p); - try { - auto newp = badp.to_libsnark_g2(); - FAIL() << "Expected std::runtime_error"; - } catch (std::runtime_error const & err) { - EXPECT_EQ(err.what(), std::string("point is not in G2")); - } catch(...) { - FAIL() << "Expected std::runtime_error"; - } - } - - // educational purposes: showing that E'(Fp2) is of order r(2q-r), - // by multiplying our random point in E' by (2q-r) = (q + q - r) to - // get an element in G2 - { - auto p1 = libsnark::alt_bn128_modulus_q * p; - p1 = p1 + p1; - p1 = p1 - (libsnark::alt_bn128_modulus_r * p); - - ASSERT_TRUE(p1.is_well_formed()); - ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p1 == curve_G2::zero()); - - CompressedG2 goodp(p1); - auto newp = goodp.to_libsnark_g2(); - - ASSERT_TRUE(newp == p1); - } -} - -TEST(proofs, sqrt_zero) -{ - ASSERT_TRUE(curve_Fq::zero() == curve_Fq::zero().sqrt()); - ASSERT_TRUE(curve_Fq2::zero() == curve_Fq2::zero().sqrt()); -} - -TEST(proofs, sqrt_fq) -{ - // Poor man's PRNG - curve_Fq acc = curve_Fq("348957923485290374852379485") ^ 1000; - - size_t quadratic_residues = 0; - size_t quadratic_nonresidues = 0; - - for (size_t i = 1; i < 1000; i++) { - try { - acc += curve_Fq("45634563456") ^ i; - - curve_Fq x = acc.sqrt(); - ASSERT_TRUE((x*x) == acc); - quadratic_residues += 1; - } catch (std::runtime_error &e) { - quadratic_nonresidues += 1; - } - } - - // Half of all nonzero elements in Fp are quadratic residues - ASSERT_TRUE(quadratic_residues == 511); - ASSERT_TRUE(quadratic_nonresidues == 488); - - for (size_t i = 0; i < 1000; i++) { - curve_Fq x = curve_Fq::random_element(); - curve_Fq x2 = x * x; - - ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x)); - } - - // Test vectors - ASSERT_TRUE( - curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601") - == - curve_Fq("348579348568").sqrt() - ); - ASSERT_THROW(curve_Fq("348579348569").sqrt(), std::runtime_error); -} - -TEST(proofs, sqrt_fq2) -{ - curve_Fq2 acc = curve_Fq2( - curve_Fq("3456293840592348059238409578239048769348760238476029347885092384059238459834") ^ 1000, - curve_Fq("2394578084760439457823945729347502374590283479582739485723945729384759823745") ^ 1000 - ); - - size_t quadratic_residues = 0; - size_t quadratic_nonresidues = 0; - - for (size_t i = 1; i < 1000; i++) { - try { - acc = acc + curve_Fq2( - curve_Fq("5204065062716160319596273903996315000119019512886596366359652578430118331601") ^ i, - curve_Fq("348957923485290374852379485348957923485290374852379485348957923485290374852") ^ i - ); - - curve_Fq2 x = acc.sqrt(); - ASSERT_TRUE((x*x) == acc); - quadratic_residues += 1; - } catch (std::runtime_error &e) { - quadratic_nonresidues += 1; - } - } - - // Half of all nonzero elements in Fp^k are quadratic residues as long - // as p != 2 - ASSERT_TRUE(quadratic_residues == 505); - ASSERT_TRUE(quadratic_nonresidues == 494); - - for (size_t i = 0; i < 1000; i++) { - curve_Fq2 x = curve_Fq2::random_element(); - curve_Fq2 x2 = x * x; - - ASSERT_TRUE((x2.sqrt() == x) || (x2.sqrt() == -x)); - } - - // Test vectors - ASSERT_THROW(curve_Fq2( - curve_Fq("2"), - curve_Fq("1") - ).sqrt(), std::runtime_error); - - ASSERT_THROW(curve_Fq2( - curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589473"), - curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676") - ).sqrt(), std::runtime_error); - - curve_Fq2 x = curve_Fq2( - curve_Fq("12844195307879678418043983815760255909500142247603239203345049921980497041944"), - curve_Fq("7476417578426924565731404322659619974551724117137577781074613937423560117731") - ); - - curve_Fq2 nx = -x; - - curve_Fq2 x2 = curve_Fq2( - curve_Fq("3345897230485723946872934576923485762803457692345760237495682347502347589474"), - curve_Fq("1234912378405347958234756902345768290345762348957605678245967234857634857676") - ); - - ASSERT_TRUE(x == x2.sqrt()); - ASSERT_TRUE(nx == -x2.sqrt()); - ASSERT_TRUE(x*x == x2); - ASSERT_TRUE(nx*nx == x2); -} - -TEST(proofs, size_is_expected) -{ - PHGRProof p; - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << p; - - ASSERT_EQ(ss.size(), 296); -} - -TEST(proofs, fq_serializes_properly) -{ - for (size_t i = 0; i < 1000; i++) { - curve_Fq e = curve_Fq::random_element(); - - Fq e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - Fq e3; - ss >> e3; - - curve_Fq e4 = e3.to_libsnark_fq(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, fq2_serializes_properly) -{ - for (size_t i = 0; i < 1000; i++) { - curve_Fq2 e = curve_Fq2::random_element(); - - Fq2 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - Fq2 e3; - ss >> e3; - - curve_Fq2 e4 = e3.to_libsnark_fq2(); - - ASSERT_TRUE(e == e4); - } -} - -template -T deserialize_tv(std::string s) -{ - T e; - CDataStream ss(ParseHex(s), SER_NETWORK, PROTOCOL_VERSION); - ss >> e; - - return e; -} - -curve_Fq deserialize_fq(std::string s) -{ - return deserialize_tv(s).to_libsnark_fq(); -} - -curve_Fq2 deserialize_fq2(std::string s) -{ - return deserialize_tv(s).to_libsnark_fq2(); -} - -TEST(proofs, fq_valid) -{ - curve_Fq e = deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"); - - ASSERT_TRUE(e == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - ASSERT_TRUE(e != curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208581")); - - curve_Fq e2 = deserialize_fq("30644e72e131a029b75045b68181585d97816a916871ca8d3c208c16d87cfd46"); - - ASSERT_TRUE(e2 == curve_Fq("21888242871839275222221885816603420866962577604863418715751138068690288573766")); -} - -TEST(proofs, fq_invalid) -{ - // Should not be able to deserialize the modulus - ASSERT_THROW( - deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"), - std::logic_error - ); - - // Should not be able to deserialize the modulus plus one - ASSERT_THROW( - deserialize_fq("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd48"), - std::logic_error - ); - - // Should not be able to deserialize a ridiculously out of bound int - ASSERT_THROW( - deserialize_fq("ff644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), - std::logic_error - ); -} - -TEST(proofs, fq2_valid) -{ - // (q - 1) * q + q - curve_Fq2 e = deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"); - ASSERT_TRUE(e.c0 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - ASSERT_TRUE(e.c1 == curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582")); - - curve_Fq2 e2 = deserialize_fq2("000000000000000000000000000000000000000000000000010245be1c91e3186bbbe1c430a93fcfc5aada4ab10c3492f70eea97a91c7b29554db55acffa34d2"); - ASSERT_TRUE(e2.c0 == curve_Fq("238769481237490823")); - ASSERT_TRUE(e2.c1 == curve_Fq("384579238459723485")); - - curve_Fq2 e3 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - ASSERT_TRUE(e3.c0 == curve_Fq("0")); - ASSERT_TRUE(e3.c1 == curve_Fq("0")); - - curve_Fq2 e4 = deserialize_fq2("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"); - ASSERT_TRUE(e4.c0 == curve_Fq("1")); - ASSERT_TRUE(e4.c1 == curve_Fq("0")); -} - -TEST(proofs, fq2_invalid) -{ - // (q - 1) * q + q is invalid - ASSERT_THROW( - deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b1"), - std::logic_error - ); - - // q * q + (q - 1) is invalid - ASSERT_THROW( - deserialize_fq2("0925c4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d34cced085b43e2f202a05e52ef18233a3d8371be725c8b8e7774e4b8ffda66f7"), - std::logic_error - ); - - // Ridiculously out of bounds - ASSERT_THROW( - deserialize_fq2("0fffc4b8763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"), - std::logic_error - ); - ASSERT_THROW( - deserialize_fq2("ffffffff763cbf9c599a6f7c0348d21cb00b85511637560626edfa5c34c6b38d04689e957a1242c84a50189c6d96cadca602072d09eac1013b5458a2275d69b0"), - std::logic_error - ); -} - -TEST(proofs, g1_serializes_properly) -{ - // Cannot serialize zero - { - ASSERT_THROW({CompressedG1 g = CompressedG1(curve_G1::zero());}, std::domain_error); - } - - for (size_t i = 0; i < 1000; i++) { - curve_G1 e = curve_G1::random_element(); - - CompressedG1 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - CompressedG1 e3; - ss >> e3; - - ASSERT_TRUE(e2 == e3); - - curve_G1 e4 = e3.to_libsnark_g1(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, g2_serializes_properly) -{ - // Cannot serialize zero - { - ASSERT_THROW({CompressedG2 g = CompressedG2(curve_G2::zero());}, std::domain_error); - } - - for (size_t i = 0; i < 1000; i++) { - curve_G2 e = curve_G2::random_element(); - - CompressedG2 e2(e); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << e2; - - CompressedG2 e3; - ss >> e3; - - ASSERT_TRUE(e2 == e3); - - curve_G2 e4 = e3.to_libsnark_g2(); - - ASSERT_TRUE(e == e4); - } -} - -TEST(proofs, zksnark_serializes_properly) -{ - auto example = libsnark::generate_r1cs_example_with_field_input(250, 4); - example.constraint_system.swap_AB_if_beneficial(); - auto kp = libsnark::r1cs_ppzksnark_generator(example.constraint_system); - auto vkprecomp = libsnark::r1cs_ppzksnark_verifier_process_vk(kp.vk); - - for (size_t i = 0; i < 20; i++) { - auto badproof = PHGRProof::random_invalid(); - auto proof = badproof.to_libsnark_proof>(); - - auto verifierEnabled = ProofVerifier::Strict(); - auto verifierDisabled = ProofVerifier::Disabled(); - // This verifier should catch the bad proof - ASSERT_FALSE(verifierEnabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - // This verifier won't! - ASSERT_TRUE(verifierDisabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - } - - for (size_t i = 0; i < 20; i++) { - auto proof = libsnark::r1cs_ppzksnark_prover( - kp.pk, - example.primary_input, - example.auxiliary_input, - example.constraint_system - ); - - { - auto verifierEnabled = ProofVerifier::Strict(); - auto verifierDisabled = ProofVerifier::Disabled(); - ASSERT_TRUE(verifierEnabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - ASSERT_TRUE(verifierDisabled.check( - kp.vk, - vkprecomp, - example.primary_input, - proof - )); - } - - ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC( - kp.vk, - example.primary_input, - proof - )); - - PHGRProof compressed_proof_0(proof); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << compressed_proof_0; - - PHGRProof compressed_proof_1; - ss >> compressed_proof_1; - - ASSERT_TRUE(compressed_proof_0 == compressed_proof_1); - - auto newproof = compressed_proof_1.to_libsnark_proof>(); - - ASSERT_TRUE(proof == newproof); - ASSERT_TRUE(libsnark::r1cs_ppzksnark_verifier_strong_IC( - kp.vk, - example.primary_input, - newproof - )); - } -} - -TEST(proofs, g1_deserialization) -{ - CompressedG1 g; - curve_G1 expected; - - // Valid G1 element. - { - CDataStream ss(ParseHex("0230644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776"); - expected.Z = curve_Fq::one(); - - ASSERT_TRUE(g.to_libsnark_g1() == expected); - } - - // Its negation. - { - CDataStream ss(ParseHex("0330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - expected.Y = curve_Fq("3969792565221544645472939191694882283483352126195956956354061729942568608776"); - expected.Z = curve_Fq::one(); - - ASSERT_TRUE(g.to_libsnark_g1() == -expected); - } - - // Invalid leading bytes - { - CDataStream ss(ParseHex("ff30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"), SER_NETWORK, PROTOCOL_VERSION); - - ASSERT_THROW(ss >> g, std::ios_base::failure); - } - - // Invalid point - { - CDataStream ss(ParseHex("0208c6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g1(), std::runtime_error); - } - - // Point with out of bounds Fq - { - CDataStream ss(ParseHex("02ffc6d2adffacbc8438f09f321874ea66e2fcc29f8dcfec2caefa21ec8c96a77c"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g1(), std::logic_error); - } - - // Randomly produce valid G1 representations and fail/succeed to - // turn them into G1 points based on whether they are valid. - for (size_t i = 0; i < 5000; i++) { - curve_Fq e = curve_Fq::random_element(); - CDataStream ss(ParseHex("02"), SER_NETWORK, PROTOCOL_VERSION); - ss << Fq(e); - CompressedG1 g; - ss >> g; - - try { - curve_G1 g_real = g.to_libsnark_g1(); - } catch(...) { - - } - } -} - -TEST(proofs, g2_deserialization) -{ - CompressedG2 g; - curve_G2 expected = curve_G2::random_element(); - - // Valid G2 point - { - CDataStream ss(ParseHex("0a023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq2( - curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"), - curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570") - ); - expected.Y = curve_Fq2( - curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"), - curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932") - ); - expected.Z = curve_Fq2::one(); - - ASSERT_TRUE(g.to_libsnark_g2() == expected); - } - - // Its negation - { - CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - expected.X = curve_Fq2( - curve_Fq("5923585509243758863255447226263146374209884951848029582715967108651637186684"), - curve_Fq("5336385337059958111259504403491065820971993066694750945459110579338490853570") - ); - expected.Y = curve_Fq2( - curve_Fq("10374495865873200088116930399159835104695426846400310764827677226300185211748"), - curve_Fq("5256529835065685814318509161957442385362539991735248614869838648137856366932") - ); - expected.Z = curve_Fq2::one(); - - ASSERT_TRUE(g.to_libsnark_g2() == -expected); - } - - // Invalid leading bytes - { - CDataStream ss(ParseHex("ff023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - - ASSERT_THROW(ss >> g, std::ios_base::failure); - } - - - // Invalid point - { - CDataStream ss(ParseHex("0b023aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984b"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g2(), std::runtime_error); - } - - // Point with out of bounds Fq2 - { - CDataStream ss(ParseHex("0a0f3aed31b5a9e486366ea9988b05dba469c6206e58361d9c065bbea7d928204a761efc6e4fa08ed227650134b52c7f7dd0463963e8a4bf21f4899fe5da7f984a"), SER_NETWORK, PROTOCOL_VERSION); - ss >> g; - - ASSERT_THROW(g.to_libsnark_g2(), std::logic_error); - } - - // Randomly produce valid G2 representations and fail/succeed to - // turn them into G2 points based on whether they are valid. - for (size_t i = 0; i < 5000; i++) { - curve_Fq2 e = curve_Fq2::random_element(); - CDataStream ss(ParseHex("0a"), SER_NETWORK, PROTOCOL_VERSION); - ss << Fq2(e); - CompressedG2 g; - ss >> g; - - try { - curve_G2 g_real = g.to_libsnark_g2(); - } catch(...) { - - } - } -} - -#include "json_test_vectors.h" -#include "test/data/g1_compressed.json.h" - -TEST(proofs, g1_test_vectors) -{ - UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed))); - - curve_G1 e = curve_Fr("34958239045823") * curve_G1::one(); - for (size_t i = 0; i < 10000; i++) { - e = (curve_Fr("34958239045823") ^ i) * e; - auto expected = CompressedG1(e); - - expect_test_vector(v[i], expected); - ASSERT_TRUE(expected.to_libsnark_g1() == e); - } -} - -#include "test/data/g2_compressed.json.h" - -TEST(proofs, g2_test_vectors) -{ - UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed))); - - curve_G2 e = curve_Fr("34958239045823") * curve_G2::one(); - for (size_t i = 0; i < 10000; i++) { - e = (curve_Fr("34958239045823") ^ i) * e; - auto expected = CompressedG2(e); - - expect_test_vector(v[i], expected); - ASSERT_TRUE(expected.to_libsnark_g2() == e); - } -} diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index e83a519b1..2bc7b48c6 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/zcash/CreateJoinSplit.cpp b/src/zcash/CreateJoinSplit.cpp deleted file mode 100644 index 06b76bb9b..000000000 --- a/src/zcash/CreateJoinSplit.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "../util.h" -#include "primitives/transaction.h" -#include "zcash/JoinSplit.hpp" - -#include "libsnark/common/profiling.hpp" -#include "komodo_defs.h" -char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -uint16_t BITCOIND_RPCPORT = 7771; -uint32_t ASSETCHAINS_CC = 0; - -using namespace libzcash; - -int main(int argc, char **argv) -{ - libsnark::start_profiling(); - - auto p = ZCJoinSplit::Prepared((ZC_GetParamsDir() / "sprout-verifying.key").string(), - (ZC_GetParamsDir() / "sprout-proving.key").string()); - - // construct a proof. - - for (int i = 0; i < 5; i++) { - uint256 anchor = ZCIncrementalMerkleTree().root(); - uint256 pubKeyHash; - - JSDescription jsdesc(*p, - pubKeyHash, - anchor, - {JSInput(), JSInput()}, - {JSOutput(), JSOutput()}, - 0, - 0); - } - - delete p; // not that it matters -} diff --git a/src/zcash/GenerateParams.cpp b/src/zcash/GenerateParams.cpp deleted file mode 100644 index 94f1c73c1..000000000 --- a/src/zcash/GenerateParams.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "zcash/JoinSplit.hpp" - -#include -#include "crypto/common.h" - -int64_t MAX_MONEY = 200000000 * 100000000LL; - -int main(int argc, char **argv) -{ - if (init_and_check_sodium() == -1) { - return 1; - } - - if(argc != 4) { - std::cerr << "Usage: " << argv[0] << " provingKeyFileName verificationKeyFileName r1csFileName" << std::endl; - return 1; - } - - std::string pkFile = argv[1]; - std::string vkFile = argv[2]; - std::string r1csFile = argv[3]; - - ZCJoinSplit::Generate(r1csFile, vkFile, pkFile); - - return 0; -} diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index f8d5fad61..b8b3cd183 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -35,6 +35,391 @@ PedersenHash PedersenHash::uncommitted() { return res; } +static const std::array pedersen_empty_roots = { + uint256(std::vector{ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }), + uint256(std::vector{ + 0x81, 0x7d, 0xe3, 0x6a, 0xb2, 0xd5, 0x7f, 0xeb, + 0x07, 0x76, 0x34, 0xbc, 0xa7, 0x78, 0x19, 0xc8, + 0xe0, 0xbd, 0x29, 0x8c, 0x04, 0xf6, 0xfe, 0xd0, + 0xe6, 0xa8, 0x3c, 0xc1, 0x35, 0x6c, 0xa1, 0x55, + }), + uint256(std::vector{ + 0xff, 0xe9, 0xfc, 0x03, 0xf1, 0x8b, 0x17, 0x6c, + 0x99, 0x88, 0x06, 0x43, 0x9f, 0xf0, 0xbb, 0x8a, + 0xd1, 0x93, 0xaf, 0xdb, 0x27, 0xb2, 0xcc, 0xbc, + 0x88, 0x85, 0x69, 0x16, 0xdd, 0x80, 0x4e, 0x34, + }), + uint256(std::vector{ + 0xd8, 0x28, 0x33, 0x86, 0xef, 0x2e, 0xf0, 0x7e, + 0xbd, 0xbb, 0x43, 0x83, 0xc1, 0x2a, 0x73, 0x9a, + 0x95, 0x3a, 0x4d, 0x6e, 0x0d, 0x6f, 0xb1, 0x13, + 0x9a, 0x40, 0x36, 0xd6, 0x93, 0xbf, 0xbb, 0x6c, + }), + uint256(std::vector{ + 0xe1, 0x10, 0xde, 0x65, 0xc9, 0x07, 0xb9, 0xde, + 0xa4, 0xae, 0x0b, 0xd8, 0x3a, 0x4b, 0x0a, 0x51, + 0xbe, 0xa1, 0x75, 0x64, 0x6a, 0x64, 0xc1, 0x2b, + 0x4c, 0x9f, 0x93, 0x1b, 0x2c, 0xb3, 0x1b, 0x49, + }), + uint256(std::vector{ + 0x91, 0x2d, 0x82, 0xb2, 0xc2, 0xbc, 0xa2, 0x31, + 0xf7, 0x1e, 0xfc, 0xf6, 0x17, 0x37, 0xfb, 0xf0, + 0xa0, 0x8b, 0xef, 0xa0, 0x41, 0x62, 0x15, 0xae, + 0xef, 0x53, 0xe8, 0xbb, 0x6d, 0x23, 0x39, 0x0a, + }), + uint256(std::vector{ + 0x8a, 0xc9, 0xcf, 0x9c, 0x39, 0x1e, 0x3f, 0xd4, + 0x28, 0x91, 0xd2, 0x72, 0x38, 0xa8, 0x1a, 0x8a, + 0x5c, 0x1d, 0x3a, 0x72, 0xb1, 0xbc, 0xbe, 0xa8, + 0xcf, 0x44, 0xa5, 0x8c, 0xe7, 0x38, 0x96, 0x13, + }), + uint256(std::vector{ + 0xd6, 0xc6, 0x39, 0xac, 0x24, 0xb4, 0x6b, 0xd1, + 0x93, 0x41, 0xc9, 0x1b, 0x13, 0xfd, 0xca, 0xb3, + 0x15, 0x81, 0xdd, 0xaf, 0x7f, 0x14, 0x11, 0x33, + 0x6a, 0x27, 0x1f, 0x3d, 0x0a, 0xa5, 0x28, 0x13, + }), + uint256(std::vector{ + 0x7b, 0x99, 0xab, 0xdc, 0x37, 0x30, 0x99, 0x1c, + 0xc9, 0x27, 0x47, 0x27, 0xd7, 0xd8, 0x2d, 0x28, + 0xcb, 0x79, 0x4e, 0xdb, 0xc7, 0x03, 0x4b, 0x4f, + 0x00, 0x53, 0xff, 0x7c, 0x4b, 0x68, 0x04, 0x44, + }), + uint256(std::vector{ + 0x43, 0xff, 0x54, 0x57, 0xf1, 0x3b, 0x92, 0x6b, + 0x61, 0xdf, 0x55, 0x2d, 0x4e, 0x40, 0x2e, 0xe6, + 0xdc, 0x14, 0x63, 0xf9, 0x9a, 0x53, 0x5f, 0x9a, + 0x71, 0x34, 0x39, 0x26, 0x4d, 0x5b, 0x61, 0x6b, + }), + uint256(std::vector{ + 0xba, 0x49, 0xb6, 0x59, 0xfb, 0xd0, 0xb7, 0x33, + 0x42, 0x11, 0xea, 0x6a, 0x9d, 0x9d, 0xf1, 0x85, + 0xc7, 0x57, 0xe7, 0x0a, 0xa8, 0x1d, 0xa5, 0x62, + 0xfb, 0x91, 0x2b, 0x84, 0xf4, 0x9b, 0xce, 0x72, + }), + uint256(std::vector{ + 0x47, 0x77, 0xc8, 0x77, 0x6a, 0x3b, 0x1e, 0x69, + 0xb7, 0x3a, 0x62, 0xfa, 0x70, 0x1f, 0xa4, 0xf7, + 0xa6, 0x28, 0x2d, 0x9a, 0xee, 0x2c, 0x7a, 0x6b, + 0x82, 0xe7, 0x93, 0x7d, 0x70, 0x81, 0xc2, 0x3c, + }), + uint256(std::vector{ + 0xec, 0x67, 0x71, 0x14, 0xc2, 0x72, 0x06, 0xf5, + 0xde, 0xbc, 0x1c, 0x1e, 0xd6, 0x6f, 0x95, 0xe2, + 0xb1, 0x88, 0x5d, 0xa5, 0xb7, 0xbe, 0x3d, 0x73, + 0x6b, 0x1d, 0xe9, 0x85, 0x79, 0x47, 0x30, 0x48, + }), + uint256(std::vector{ + 0x1b, 0x77, 0xda, 0xc4, 0xd2, 0x4f, 0xb7, 0x25, + 0x8c, 0x3c, 0x52, 0x87, 0x04, 0xc5, 0x94, 0x30, + 0xb6, 0x30, 0x71, 0x8b, 0xec, 0x48, 0x64, 0x21, + 0x83, 0x70, 0x21, 0xcf, 0x75, 0xda, 0xb6, 0x51, + }), + uint256(std::vector{ + 0xbd, 0x74, 0xb2, 0x5a, 0xac, 0xb9, 0x23, 0x78, + 0xa8, 0x71, 0xbf, 0x27, 0xd2, 0x25, 0xcf, 0xc2, + 0x6b, 0xac, 0xa3, 0x44, 0xa1, 0xea, 0x35, 0xfd, + 0xd9, 0x45, 0x10, 0xf3, 0xd1, 0x57, 0x08, 0x2c, + }), + uint256(std::vector{ + 0xd6, 0xac, 0xde, 0xdf, 0x95, 0xf6, 0x08, 0xe0, + 0x9f, 0xa5, 0x3f, 0xb4, 0x3d, 0xcd, 0x09, 0x90, + 0x47, 0x57, 0x26, 0xc5, 0x13, 0x12, 0x10, 0xc9, + 0xe5, 0xca, 0xea, 0xb9, 0x7f, 0x0e, 0x64, 0x2f, + }), + uint256(std::vector{ + 0x1e, 0xa6, 0x67, 0x5f, 0x95, 0x51, 0xee, 0xb9, + 0xdf, 0xaa, 0xa9, 0x24, 0x7b, 0xc9, 0x85, 0x82, + 0x70, 0xd3, 0xd3, 0xa4, 0xc5, 0xaf, 0xa7, 0x17, + 0x7a, 0x98, 0x4d, 0x5e, 0xd1, 0xbe, 0x24, 0x51, + }), + uint256(std::vector{ + 0x6e, 0xdb, 0x16, 0xd0, 0x19, 0x07, 0xb7, 0x59, + 0x97, 0x7d, 0x76, 0x50, 0xda, 0xd7, 0xe3, 0xec, + 0x04, 0x9a, 0xf1, 0xa3, 0xd8, 0x75, 0x38, 0x0b, + 0x69, 0x7c, 0x86, 0x2c, 0x9e, 0xc5, 0xd5, 0x1c, + }), + uint256(std::vector{ + 0xcd, 0x1c, 0x8d, 0xbf, 0x6e, 0x3a, 0xcc, 0x7a, + 0x80, 0x43, 0x9b, 0xc4, 0x96, 0x2c, 0xf2, 0x5b, + 0x9d, 0xce, 0x7c, 0x89, 0x6f, 0x3a, 0x5b, 0xd7, + 0x08, 0x03, 0xfc, 0x5a, 0x0e, 0x33, 0xcf, 0x00, + }), + uint256(std::vector{ + 0x6a, 0xca, 0x84, 0x48, 0xd8, 0x26, 0x3e, 0x54, + 0x7d, 0x5f, 0xf2, 0x95, 0x0e, 0x2e, 0xd3, 0x83, + 0x9e, 0x99, 0x8d, 0x31, 0xcb, 0xc6, 0xac, 0x9f, + 0xd5, 0x7b, 0xc6, 0x00, 0x2b, 0x15, 0x92, 0x16, + }), + uint256(std::vector{ + 0x8d, 0x5f, 0xa4, 0x3e, 0x5a, 0x10, 0xd1, 0x16, + 0x05, 0xac, 0x74, 0x30, 0xba, 0x1f, 0x5d, 0x81, + 0xfb, 0x1b, 0x68, 0xd2, 0x9a, 0x64, 0x04, 0x05, + 0x76, 0x77, 0x49, 0xe8, 0x41, 0x52, 0x76, 0x73, + }), + uint256(std::vector{ + 0x08, 0xee, 0xab, 0x0c, 0x13, 0xab, 0xd6, 0x06, + 0x9e, 0x63, 0x10, 0x19, 0x7b, 0xf8, 0x0f, 0x9c, + 0x1e, 0xa6, 0xde, 0x78, 0xfd, 0x19, 0xcb, 0xae, + 0x24, 0xd4, 0xa5, 0x20, 0xe6, 0xcf, 0x30, 0x23, + }), + uint256(std::vector{ + 0x07, 0x69, 0x55, 0x7b, 0xc6, 0x82, 0xb1, 0xbf, + 0x30, 0x86, 0x46, 0xfd, 0x0b, 0x22, 0xe6, 0x48, + 0xe8, 0xb9, 0xe9, 0x8f, 0x57, 0xe2, 0x9f, 0x5a, + 0xf4, 0x0f, 0x6e, 0xdb, 0x83, 0x3e, 0x2c, 0x49, + }), + uint256(std::vector{ + 0x4c, 0x69, 0x37, 0xd7, 0x8f, 0x42, 0x68, 0x5f, + 0x84, 0xb4, 0x3a, 0xd3, 0xb7, 0xb0, 0x0f, 0x81, + 0x28, 0x56, 0x62, 0xf8, 0x5c, 0x6a, 0x68, 0xef, + 0x11, 0xd6, 0x2a, 0xd1, 0xa3, 0xee, 0x08, 0x50, + }), + uint256(std::vector{ + 0xfe, 0xe0, 0xe5, 0x28, 0x02, 0xcb, 0x0c, 0x46, + 0xb1, 0xeb, 0x4d, 0x37, 0x6c, 0x62, 0x69, 0x7f, + 0x47, 0x59, 0xf6, 0xc8, 0x91, 0x7f, 0xa3, 0x52, + 0x57, 0x12, 0x02, 0xfd, 0x77, 0x8f, 0xd7, 0x12, + }), + uint256(std::vector{ + 0x16, 0xd6, 0x25, 0x29, 0x68, 0x97, 0x1a, 0x83, + 0xda, 0x85, 0x21, 0xd6, 0x53, 0x82, 0xe6, 0x1f, + 0x01, 0x76, 0x64, 0x6d, 0x77, 0x1c, 0x91, 0x52, + 0x8e, 0x32, 0x76, 0xee, 0x45, 0x38, 0x3e, 0x4a, + }), + uint256(std::vector{ + 0xd2, 0xe1, 0x64, 0x2c, 0x9a, 0x46, 0x22, 0x29, + 0x28, 0x9e, 0x5b, 0x0e, 0x3b, 0x7f, 0x90, 0x08, + 0xe0, 0x30, 0x1c, 0xbb, 0x93, 0x38, 0x5e, 0xe0, + 0xe2, 0x1d, 0xa2, 0x54, 0x50, 0x73, 0xcb, 0x58, + }), + uint256(std::vector{ + 0xa5, 0x12, 0x2c, 0x08, 0xff, 0x9c, 0x16, 0x1d, + 0x9c, 0xa6, 0xfc, 0x46, 0x20, 0x73, 0x39, 0x6c, + 0x7d, 0x7d, 0x38, 0xe8, 0xee, 0x48, 0xcd, 0xb3, + 0xbe, 0xa7, 0xe2, 0x23, 0x01, 0x34, 0xed, 0x6a, + }), + uint256(std::vector{ + 0x28, 0xe7, 0xb8, 0x41, 0xdc, 0xbc, 0x47, 0xcc, + 0xeb, 0x69, 0xd7, 0xcb, 0x8d, 0x94, 0x24, 0x5f, + 0xb7, 0xcb, 0x2b, 0xa3, 0xa7, 0xa6, 0xbc, 0x18, + 0xf1, 0x3f, 0x94, 0x5f, 0x7d, 0xbd, 0x6e, 0x2a, + }), + uint256(std::vector{ + 0xe1, 0xf3, 0x4b, 0x03, 0x4d, 0x4a, 0x3c, 0xd2, + 0x85, 0x57, 0xe2, 0x90, 0x7e, 0xbf, 0x99, 0x0c, + 0x91, 0x8f, 0x64, 0xec, 0xb5, 0x0a, 0x94, 0xf0, + 0x1d, 0x6f, 0xda, 0x5c, 0xa5, 0xc7, 0xef, 0x72, + }), + uint256(std::vector{ + 0x12, 0x93, 0x5f, 0x14, 0xb6, 0x76, 0x50, 0x9b, + 0x81, 0xeb, 0x49, 0xef, 0x25, 0xf3, 0x92, 0x69, + 0xed, 0x72, 0x30, 0x92, 0x38, 0xb4, 0xc1, 0x45, + 0x80, 0x35, 0x44, 0xb6, 0x46, 0xdc, 0xa6, 0x2d, + }), + uint256(std::vector{ + 0xb2, 0xee, 0xd0, 0x31, 0xd4, 0xd6, 0xa4, 0xf0, + 0x2a, 0x09, 0x7f, 0x80, 0xb5, 0x4c, 0xc1, 0x54, + 0x1d, 0x41, 0x63, 0xc6, 0xb6, 0xf5, 0x97, 0x1f, + 0x88, 0xb6, 0xe4, 0x1d, 0x35, 0xc5, 0x38, 0x14, + }), + uint256(std::vector{ + 0xfb, 0xc2, 0xf4, 0x30, 0x0c, 0x01, 0xf0, 0xb7, + 0x82, 0x0d, 0x00, 0xe3, 0x34, 0x7c, 0x8d, 0xa4, + 0xee, 0x61, 0x46, 0x74, 0x37, 0x6c, 0xbc, 0x45, + 0x35, 0x9d, 0xaa, 0x54, 0xf9, 0xb5, 0x49, 0x3e, + }), + uint256(std::vector{ + 0x25, 0x2e, 0x67, 0x98, 0x64, 0x5f, 0x5b, 0xf1, + 0x14, 0xe4, 0xb4, 0xe9, 0x0e, 0x96, 0x18, 0x28, + 0x61, 0x48, 0x98, 0x40, 0xd9, 0xb4, 0xcc, 0xc4, + 0xc1, 0xfb, 0x5a, 0x46, 0x99, 0x7c, 0xee, 0x14, + }), + uint256(std::vector{ + 0x98, 0xb1, 0x90, 0x42, 0xf1, 0xf7, 0xc7, 0xdd, + 0x11, 0xec, 0x25, 0xea, 0x66, 0xb6, 0xff, 0x74, + 0xe0, 0x8c, 0xe1, 0x1d, 0x44, 0x7e, 0xd6, 0xf1, + 0xbf, 0xe8, 0x7e, 0x11, 0x0e, 0x33, 0x1e, 0x11, + }), + uint256(std::vector{ + 0xd4, 0x51, 0x30, 0x47, 0x99, 0x57, 0x2b, 0xa9, + 0xf4, 0x2c, 0x4d, 0xab, 0x6b, 0x07, 0xc7, 0x03, + 0xbd, 0x2c, 0x12, 0x3a, 0xb9, 0xd6, 0x0f, 0x2a, + 0x60, 0xf9, 0x95, 0x58, 0x54, 0x91, 0x0b, 0x6a, + }), + uint256(std::vector{ + 0x3e, 0xcd, 0x5f, 0x27, 0xac, 0xf0, 0x1b, 0xd3, + 0x7a, 0x33, 0xe4, 0x51, 0x78, 0x67, 0xef, 0x76, + 0x47, 0x4c, 0xd8, 0x3f, 0xb3, 0x1c, 0x92, 0x08, + 0xdc, 0xef, 0x2e, 0xed, 0xce, 0xf3, 0x6c, 0x72, + }), + uint256(std::vector{ + 0x26, 0xc3, 0x7d, 0xa6, 0x78, 0x94, 0xa1, 0x3d, + 0xf8, 0xaa, 0x48, 0x78, 0xd2, 0x51, 0x4a, 0x42, + 0x12, 0x57, 0x3b, 0x73, 0xec, 0xca, 0xab, 0x16, + 0xfe, 0x4f, 0xa6, 0x60, 0xe8, 0xfe, 0x27, 0x07, + }), + uint256(std::vector{ + 0xb5, 0x45, 0xef, 0x34, 0x48, 0x5e, 0xed, 0x30, + 0xd4, 0x2b, 0x2c, 0x29, 0x5a, 0x4a, 0x5b, 0x68, + 0x0d, 0xe8, 0xa9, 0xd5, 0xe3, 0x83, 0x45, 0x78, + 0x24, 0x62, 0xc0, 0x4f, 0x09, 0xdc, 0x68, 0x51, + }), + uint256(std::vector{ + 0x77, 0xfd, 0x20, 0xb3, 0x00, 0x94, 0x67, 0x65, + 0xa8, 0x7f, 0x24, 0xbd, 0x04, 0x50, 0x73, 0x72, + 0x9c, 0xbd, 0x7b, 0x66, 0xeb, 0x8f, 0xa1, 0x40, + 0xb5, 0x83, 0xfa, 0xa9, 0xd1, 0x42, 0x58, 0x01, + }), + uint256(std::vector{ + 0xcb, 0xaa, 0x57, 0x6b, 0x17, 0x99, 0xb5, 0x8f, + 0xf3, 0xa6, 0xde, 0xcb, 0xba, 0x91, 0x9b, 0x0b, + 0x68, 0xd7, 0xc8, 0x93, 0xe4, 0x6f, 0xde, 0x99, + 0x87, 0x68, 0xe8, 0x7e, 0x35, 0x0a, 0x07, 0x25, + }), + uint256(std::vector{ + 0x45, 0xfe, 0x81, 0xb1, 0x8c, 0xa3, 0x00, 0x74, + 0xd0, 0x12, 0x0d, 0x2b, 0x1a, 0x0d, 0x10, 0xb3, + 0xa0, 0x50, 0x93, 0x35, 0x12, 0xdb, 0x8e, 0xe3, + 0x4e, 0x52, 0x47, 0x3d, 0x4f, 0x08, 0xa2, 0x67, + }), + uint256(std::vector{ + 0x0e, 0x60, 0xa1, 0xf0, 0x12, 0x1f, 0x59, 0x1e, + 0x55, 0x1d, 0x3e, 0xd1, 0x86, 0x5b, 0x50, 0xa7, + 0x5d, 0x7c, 0xcf, 0xf1, 0x28, 0x9d, 0xf7, 0xc4, + 0x4d, 0xd4, 0x65, 0xa5, 0x43, 0x17, 0xf5, 0x6a, + }), + uint256(std::vector{ + 0xce, 0xdf, 0xb1, 0x84, 0xdd, 0x92, 0xa0, 0xcb, + 0xfc, 0x11, 0xe8, 0xbe, 0x69, 0x7b, 0x47, 0x69, + 0x88, 0xed, 0x5f, 0x39, 0x36, 0x9a, 0xbd, 0xd9, + 0x0c, 0x61, 0x54, 0x49, 0x88, 0x60, 0x1c, 0x0d, + }), + uint256(std::vector{ + 0xf3, 0x62, 0x68, 0x66, 0x12, 0x64, 0x9a, 0x31, + 0x3b, 0xa4, 0x64, 0x43, 0x7a, 0x0c, 0xad, 0x0e, + 0x7e, 0x3d, 0x7e, 0x1b, 0x4b, 0x37, 0x43, 0xf9, + 0x0e, 0x05, 0xa2, 0x10, 0x0a, 0x49, 0x5f, 0x42, + }), + uint256(std::vector{ + 0x7d, 0xea, 0xe5, 0xf3, 0xbb, 0xde, 0xff, 0xd3, + 0xf8, 0x52, 0x71, 0xa0, 0x8b, 0x5e, 0xc3, 0x1f, + 0x16, 0xf9, 0x37, 0x96, 0x4a, 0xe7, 0x08, 0xfd, + 0xff, 0x7c, 0x13, 0xe5, 0xa4, 0xf3, 0xdf, 0x6b, + }), + uint256(std::vector{ + 0x40, 0xcc, 0xf0, 0xfc, 0x1e, 0xab, 0x6d, 0x85, + 0x02, 0xbd, 0x93, 0xdc, 0x31, 0x34, 0x2d, 0xfd, + 0x57, 0xdf, 0x5b, 0xbb, 0x5d, 0x70, 0xa1, 0xbf, + 0x6b, 0x92, 0xef, 0xc6, 0x1e, 0xc9, 0xa2, 0x58, + }), + uint256(std::vector{ + 0xd7, 0x80, 0x25, 0x49, 0x1f, 0x1b, 0xca, 0x85, + 0x07, 0xf6, 0x4f, 0x25, 0x87, 0x2d, 0xd0, 0x23, + 0x88, 0x47, 0x9a, 0x1a, 0x22, 0x51, 0x26, 0xe4, + 0x0d, 0x2f, 0xe4, 0x18, 0xb9, 0x8e, 0x0e, 0x2c, + }), + uint256(std::vector{ + 0x0d, 0xb7, 0x29, 0x46, 0x85, 0xc8, 0xa0, 0x72, + 0x5f, 0x15, 0x84, 0x6e, 0xa5, 0x89, 0x9e, 0xa0, + 0xe9, 0x86, 0xc2, 0x70, 0x7b, 0xd7, 0xb4, 0x12, + 0x95, 0x44, 0x12, 0xf2, 0x6a, 0xbf, 0x55, 0x0a, + }), + uint256(std::vector{ + 0xb7, 0xe2, 0x90, 0xbe, 0x95, 0x55, 0xcf, 0x75, + 0x54, 0x86, 0x50, 0xda, 0x6d, 0x47, 0xc8, 0x93, + 0xae, 0xf7, 0xf8, 0xc6, 0xdd, 0x27, 0x35, 0x49, + 0x94, 0x95, 0xf6, 0x36, 0x59, 0x0d, 0xae, 0x0a, + }), + uint256(std::vector{ + 0x2d, 0xd2, 0x53, 0x2a, 0x85, 0x8c, 0x30, 0x01, + 0x45, 0xa6, 0x5e, 0x35, 0x1f, 0x91, 0xbe, 0x6a, + 0xfe, 0xab, 0x59, 0x7c, 0x41, 0xef, 0x07, 0x3f, + 0x50, 0xb6, 0x22, 0xd5, 0x86, 0xff, 0x59, 0x27, + }), + uint256(std::vector{ + 0x97, 0x2f, 0x0c, 0x5c, 0x6f, 0x9a, 0xeb, 0x0e, + 0x38, 0xbf, 0x83, 0x19, 0xf3, 0xa5, 0xfc, 0xdc, + 0x8f, 0xd8, 0x78, 0x2e, 0x41, 0x88, 0x73, 0x0c, + 0xd0, 0x82, 0xd9, 0xba, 0xbc, 0x58, 0x98, 0x51, + }), + uint256(std::vector{ + 0x00, 0x1e, 0x57, 0x7b, 0x0f, 0x43, 0x90, 0x18, + 0x2b, 0x4a, 0xe4, 0x3d, 0x32, 0x9b, 0x3a, 0xa8, + 0x83, 0x5d, 0xae, 0x1b, 0xb7, 0x9e, 0x60, 0x4b, + 0x7d, 0x2d, 0xa0, 0xe9, 0x0d, 0x06, 0x09, 0x29, + }), + uint256(std::vector{ + 0xaa, 0x6e, 0x70, 0xa9, 0x1e, 0xbc, 0x54, 0xee, + 0xfc, 0xe5, 0xff, 0xd5, 0xb6, 0x75, 0xda, 0xf3, + 0xf1, 0xd9, 0x40, 0xa8, 0x45, 0x1f, 0xcb, 0x01, + 0x08, 0x1f, 0xa9, 0xd4, 0xf2, 0x62, 0x43, 0x6f, + }), + uint256(std::vector{ + 0xd7, 0x70, 0x38, 0xbf, 0x67, 0xe6, 0x31, 0x75, + 0x29, 0x40, 0x23, 0x12, 0x51, 0xd7, 0xfe, 0x85, + 0xaf, 0x52, 0xdb, 0xdd, 0x6a, 0xab, 0x37, 0xc7, + 0xa5, 0xec, 0x32, 0xb6, 0x5f, 0xe6, 0xde, 0x03, + }), + uint256(std::vector{ + 0xd2, 0x27, 0xa1, 0x7a, 0x7e, 0x0c, 0xf9, 0x6d, + 0xce, 0xdd, 0x9f, 0xc7, 0xbc, 0xe4, 0x3c, 0x6c, + 0x1d, 0x66, 0xba, 0xdd, 0x75, 0x43, 0xa8, 0x87, + 0xc8, 0x65, 0x6c, 0x54, 0x7e, 0xcf, 0xb2, 0x4f, + }), + uint256(std::vector{ + 0x70, 0xe8, 0xa5, 0x21, 0x95, 0x15, 0x83, 0xe5, + 0x3f, 0xc0, 0x58, 0x5c, 0x70, 0x7e, 0xce, 0xda, + 0x89, 0xb7, 0xa7, 0xd1, 0xaf, 0x41, 0xd1, 0xa0, + 0x15, 0xd7, 0x97, 0xfa, 0x76, 0xc0, 0xf5, 0x69, + }), + uint256(std::vector{ + 0xe4, 0x85, 0xa9, 0x68, 0x55, 0xe8, 0x72, 0xfc, + 0x50, 0x90, 0x15, 0x0e, 0x2c, 0xd2, 0x4e, 0x10, + 0x59, 0x1d, 0x35, 0x16, 0x6e, 0xb0, 0xeb, 0x30, + 0xfc, 0xdf, 0xac, 0x93, 0xb0, 0x1d, 0x28, 0x1c, + }), + uint256(std::vector{ + 0xe4, 0xa1, 0x9f, 0xeb, 0xdf, 0x2a, 0x86, 0x89, + 0x6e, 0x41, 0xf2, 0xce, 0xdc, 0xf2, 0xae, 0x58, + 0x46, 0x71, 0x80, 0x2e, 0x6a, 0x46, 0x7e, 0x84, + 0x39, 0xca, 0xb5, 0xd6, 0x18, 0x43, 0x41, 0x6b, + }), + uint256(std::vector{ + 0xe9, 0x27, 0x83, 0x88, 0x47, 0x80, 0x6a, 0x43, + 0xbd, 0x6c, 0x60, 0x88, 0xe3, 0x9f, 0x65, 0xb8, + 0xb3, 0xe5, 0x8b, 0x2d, 0xb5, 0xf7, 0xad, 0x56, + 0x43, 0xd9, 0x1e, 0x06, 0x59, 0xa2, 0x8a, 0x2a, + }), + uint256(std::vector{ + 0x0b, 0xd3, 0xa8, 0x18, 0xe8, 0x3f, 0x9c, 0xd2, + 0xff, 0x4f, 0x62, 0x01, 0x1a, 0x51, 0x01, 0x76, + 0xac, 0x32, 0xf5, 0x44, 0x8e, 0x6e, 0x15, 0x45, + 0x15, 0x04, 0x3c, 0x59, 0x26, 0xd5, 0x1c, 0x6f, + }), + uint256(std::vector{ + 0xce, 0x41, 0x34, 0x45, 0xe0, 0x37, 0x90, 0x49, + 0x8f, 0xe7, 0x2d, 0x8e, 0x01, 0x91, 0x5e, 0x7f, + 0xf1, 0x20, 0xae, 0x35, 0xb3, 0xb5, 0x90, 0xd2, + 0x1b, 0x7f, 0x74, 0xde, 0xe1, 0x83, 0x0f, 0x0d, + }), + uint256(std::vector{ + 0x60, 0x0e, 0x6f, 0x93, 0xe7, 0x3d, 0x7a, 0xbd, + 0x4e, 0xe0, 0xa6, 0x5c, 0xb1, 0xb1, 0x9a, 0xa3, + 0xec, 0xc5, 0x25, 0x68, 0x9d, 0xbf, 0x17, 0x77, + 0x96, 0x58, 0x74, 0x1b, 0x95, 0xc1, 0x5a, 0x55, + }), +}; + +PedersenHash PedersenHash::EmptyRoot(size_t depth) { + return pedersen_empty_roots.at(depth); +} + SHA256Compress SHA256Compress::combine( const SHA256Compress& a, const SHA256Compress& b, @@ -51,6 +436,409 @@ SHA256Compress SHA256Compress::combine( return res; } +static const std::array sha256_empty_roots = { + uint256(std::vector{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }), + uint256(std::vector{ + 0xda, 0x56, 0x98, 0xbe, 0x17, 0xb9, 0xb4, 0x69, + 0x62, 0x33, 0x57, 0x99, 0x77, 0x9f, 0xbe, 0xca, + 0x8c, 0xe5, 0xd4, 0x91, 0xc0, 0xd2, 0x62, 0x43, + 0xba, 0xfe, 0xf9, 0xea, 0x18, 0x37, 0xa9, 0xd8, + }), + uint256(std::vector{ + 0xdc, 0x76, 0x6f, 0xab, 0x49, 0x2c, 0xcf, 0x3d, + 0x1e, 0x49, 0xd4, 0xf3, 0x74, 0xb5, 0x23, 0x5f, + 0xa5, 0x65, 0x06, 0xaa, 0xc2, 0x22, 0x4d, 0x39, + 0xf9, 0x43, 0xfc, 0xd4, 0x92, 0x02, 0x97, 0x4c, + }), + uint256(std::vector{ + 0x3f, 0x0a, 0x40, 0x61, 0x81, 0x10, 0x59, 0x68, + 0xfd, 0xae, 0xe3, 0x06, 0x79, 0xe3, 0x27, 0x3c, + 0x66, 0xb7, 0x2b, 0xf9, 0xa7, 0xf5, 0xde, 0xbb, + 0xf3, 0xb5, 0xa0, 0xa2, 0x6e, 0x35, 0x9f, 0x92, + }), + uint256(std::vector{ + 0x26, 0xb0, 0x05, 0x26, 0x94, 0xfc, 0x42, 0xfd, + 0xff, 0x93, 0xe6, 0xfb, 0x5a, 0x71, 0xd3, 0x8c, + 0x3d, 0xd7, 0xdc, 0x5b, 0x6a, 0xd7, 0x10, 0xeb, + 0x04, 0x8c, 0x66, 0x02, 0x33, 0x13, 0x7f, 0xab, + }), + uint256(std::vector{ + 0x01, 0x09, 0xec, 0xc0, 0x72, 0x26, 0x59, 0xff, + 0x83, 0x45, 0x0b, 0x8f, 0x7b, 0x88, 0x46, 0xe6, + 0x7b, 0x28, 0x59, 0xf3, 0x3c, 0x30, 0xd9, 0xb7, + 0xac, 0xd5, 0xbf, 0x39, 0xca, 0xe5, 0x4e, 0x31, + }), + uint256(std::vector{ + 0x3f, 0x90, 0x9b, 0x8c, 0xe3, 0xd7, 0xff, 0xd8, + 0xa5, 0xb3, 0x09, 0x08, 0xf6, 0x05, 0xa0, 0x3b, + 0x0d, 0xb8, 0x51, 0x69, 0x55, 0x8d, 0xdc, 0x1d, + 0xa7, 0xbb, 0xbc, 0xc9, 0xb0, 0x9f, 0xd3, 0x25, + }), + uint256(std::vector{ + 0x40, 0x46, 0x0f, 0xa6, 0xbc, 0x69, 0x2a, 0x06, + 0xf4, 0x75, 0x21, 0xa6, 0x72, 0x5a, 0x54, 0x7c, + 0x02, 0x8a, 0x6a, 0x24, 0x0d, 0x84, 0x09, 0xf1, + 0x65, 0xe6, 0x3c, 0xb5, 0x4d, 0xa2, 0xd2, 0x3f, + }), + uint256(std::vector{ + 0x8c, 0x08, 0x56, 0x74, 0x24, 0x9b, 0x43, 0xda, + 0x1b, 0x9a, 0x31, 0xa0, 0xe8, 0x20, 0xe8, 0x1e, + 0x75, 0xf3, 0x42, 0x80, 0x7b, 0x03, 0xb6, 0xb9, + 0xe6, 0x49, 0x83, 0x21, 0x7b, 0xc2, 0xb3, 0x8e, + }), + uint256(std::vector{ + 0xa0, 0x83, 0x45, 0x0c, 0x1b, 0xa2, 0xa3, 0xa7, + 0xbe, 0x76, 0xfa, 0xd9, 0xd1, 0x3b, 0xc3, 0x7b, + 0xe4, 0xbf, 0x83, 0xbd, 0x3e, 0x59, 0xfc, 0x37, + 0x5a, 0x36, 0xba, 0x62, 0xdc, 0x62, 0x02, 0x98, + }), + uint256(std::vector{ + 0x1d, 0xdd, 0xda, 0xbc, 0x2c, 0xaa, 0x2d, 0xe9, + 0xef, 0xf9, 0xe1, 0x8c, 0x8c, 0x5a, 0x39, 0x40, + 0x6d, 0x79, 0x36, 0xe8, 0x89, 0xbc, 0x16, 0xcf, + 0xab, 0xb1, 0x44, 0xf5, 0xc0, 0x02, 0x26, 0x82, + }), + uint256(std::vector{ + 0xc2, 0x2d, 0x8f, 0x0b, 0x5e, 0x40, 0x56, 0xe5, + 0xf3, 0x18, 0xba, 0x22, 0x09, 0x1c, 0xc0, 0x7d, + 0xb5, 0x69, 0x4f, 0xbe, 0xb5, 0xe8, 0x7e, 0xf0, + 0xd7, 0xe2, 0xc5, 0x7c, 0xa3, 0x52, 0x35, 0x9e, + }), + uint256(std::vector{ + 0x89, 0xa4, 0x34, 0xae, 0x1f, 0xeb, 0xd7, 0x68, + 0x7e, 0xce, 0xea, 0x21, 0xd0, 0x7f, 0x20, 0xa2, + 0x51, 0x24, 0x49, 0xd0, 0x8c, 0xe2, 0xee, 0xe5, + 0x58, 0x71, 0xcd, 0xb9, 0xd4, 0x6c, 0x12, 0x33, + }), + uint256(std::vector{ + 0x73, 0x33, 0xdb, 0xff, 0xbd, 0x11, 0xf0, 0x92, + 0x47, 0xa2, 0xb3, 0x3a, 0x01, 0x3e, 0xc4, 0xc4, + 0x34, 0x20, 0x29, 0xd8, 0x51, 0xe2, 0x2b, 0xa4, + 0x85, 0xd4, 0x46, 0x18, 0x51, 0x37, 0x0c, 0x15, + }), + uint256(std::vector{ + 0x5d, 0xad, 0x84, 0x4a, 0xb9, 0x46, 0x6b, 0x70, + 0xf7, 0x45, 0x13, 0x71, 0x95, 0xca, 0x22, 0x1b, + 0x48, 0xf3, 0x46, 0xab, 0xd1, 0x45, 0xfb, 0x5e, + 0xfc, 0x23, 0xa8, 0xb4, 0xba, 0x50, 0x80, 0x22, + }), + uint256(std::vector{ + 0x50, 0x7e, 0x0d, 0xae, 0x81, 0xcb, 0xfb, 0xe4, + 0x57, 0xfd, 0x37, 0x0e, 0xf1, 0xca, 0x42, 0x01, + 0xc2, 0xb6, 0x40, 0x10, 0x83, 0xdd, 0xab, 0x44, + 0x0e, 0x4a, 0x03, 0x8d, 0xc1, 0xe3, 0x58, 0xc4, + }), + uint256(std::vector{ + 0xbd, 0xcd, 0xb3, 0x29, 0x31, 0x88, 0xc9, 0x80, + 0x7d, 0x80, 0x82, 0x67, 0x01, 0x86, 0x84, 0xcf, + 0xec, 0xe0, 0x7a, 0xc3, 0x5a, 0x42, 0xc0, 0x0f, + 0x2c, 0x79, 0xb4, 0x00, 0x38, 0x25, 0x30, 0x5d, + }), + uint256(std::vector{ + 0xba, 0xb5, 0x80, 0x09, 0x72, 0xa1, 0x6c, 0x2c, + 0x22, 0x53, 0x0c, 0x66, 0x06, 0x6d, 0x0a, 0x58, + 0x67, 0xe9, 0x87, 0xbe, 0xd2, 0x1a, 0x6d, 0x5a, + 0x45, 0x0b, 0x68, 0x3c, 0xf1, 0xcf, 0xd7, 0x09, + }), + uint256(std::vector{ + 0x11, 0xaa, 0x0b, 0x4a, 0xd2, 0x9b, 0x13, 0xb0, + 0x57, 0xa3, 0x16, 0x19, 0xd6, 0x50, 0x0d, 0x63, + 0x6c, 0xd7, 0x35, 0xcd, 0xd0, 0x7d, 0x81, 0x1e, + 0xa2, 0x65, 0xec, 0x4b, 0xcb, 0xbb, 0xd0, 0x58, + }), + uint256(std::vector{ + 0x51, 0x45, 0xb1, 0xb0, 0x55, 0xc2, 0xdf, 0x02, + 0xb9, 0x56, 0x75, 0xe3, 0x79, 0x7b, 0x91, 0xde, + 0x1b, 0x84, 0x6d, 0x25, 0x00, 0x3c, 0x0a, 0x80, + 0x3d, 0x08, 0x90, 0x07, 0x28, 0xf2, 0xcd, 0x6a, + }), + uint256(std::vector{ + 0x03, 0x23, 0xf2, 0x85, 0x0b, 0xf3, 0x44, 0x4f, + 0x4b, 0x4c, 0x5c, 0x09, 0xa6, 0x05, 0x7e, 0xc7, + 0x16, 0x91, 0x90, 0xf4, 0x5a, 0xcb, 0x9e, 0x46, + 0x98, 0x4a, 0xb3, 0xdf, 0xce, 0xc4, 0xf0, 0x6a, + }), + uint256(std::vector{ + 0x67, 0x15, 0x46, 0xe2, 0x6b, 0x1d, 0xa1, 0xaf, + 0x75, 0x45, 0x31, 0xe2, 0x6d, 0x8a, 0x6a, 0x51, + 0x07, 0x3a, 0x57, 0xdd, 0xd7, 0x2d, 0xc4, 0x72, + 0xef, 0xb4, 0x3f, 0xcb, 0x25, 0x7c, 0xff, 0xff, + }), + uint256(std::vector{ + 0xbb, 0x23, 0xa9, 0xbb, 0xa5, 0x6d, 0xe5, 0x7c, + 0xb2, 0x84, 0xb0, 0xd2, 0xb0, 0x1c, 0x64, 0x2c, + 0xf7, 0x9c, 0x9a, 0x55, 0x63, 0xf0, 0x06, 0x7a, + 0x21, 0x29, 0x24, 0x12, 0x14, 0x5b, 0xd7, 0x8a, + }), + uint256(std::vector{ + 0xf3, 0x0c, 0xc8, 0x36, 0xb9, 0xf7, 0x1b, 0x4e, + 0x7e, 0xe3, 0xc7, 0x2b, 0x1f, 0xd2, 0x53, 0x26, + 0x8a, 0xf9, 0xa2, 0x7e, 0x9d, 0x72, 0x91, 0xa2, + 0x3d, 0x02, 0x82, 0x1b, 0x21, 0xdd, 0xfd, 0x16, + }), + uint256(std::vector{ + 0x58, 0xa2, 0x75, 0x3d, 0xad, 0xe1, 0x03, 0xce, + 0xcb, 0xcd, 0xa5, 0x0b, 0x5e, 0xbf, 0xce, 0x31, + 0xe1, 0x2d, 0x41, 0xd5, 0x84, 0x1d, 0xcc, 0x95, + 0x62, 0x0f, 0x7b, 0x3d, 0x50, 0xa1, 0xb9, 0xa1, + }), + uint256(std::vector{ + 0x92, 0x5e, 0x6d, 0x47, 0x4a, 0x5d, 0x8d, 0x30, + 0x04, 0xf2, 0x9d, 0xa0, 0xdd, 0x78, 0xd3, 0x0a, + 0xe3, 0x82, 0x4c, 0xe7, 0x9d, 0xfe, 0x49, 0x34, + 0xbb, 0x29, 0xec, 0x3a, 0xfa, 0xf3, 0xd5, 0x21, + }), + uint256(std::vector{ + 0x08, 0xf2, 0x79, 0x61, 0x86, 0x16, 0xbc, 0xdd, + 0x4e, 0xad, 0xc9, 0xc7, 0xa9, 0x06, 0x26, 0x91, + 0xa5, 0x9b, 0x43, 0xb0, 0x7e, 0x2c, 0x1e, 0x23, + 0x7f, 0x17, 0xbd, 0x18, 0x9c, 0xd6, 0xa8, 0xfe, + }), + uint256(std::vector{ + 0xc9, 0x2b, 0x32, 0xdb, 0x42, 0xf4, 0x2e, 0x2b, + 0xf0, 0xa5, 0x9d, 0xf9, 0x05, 0x5b, 0xe5, 0xc6, + 0x69, 0xd3, 0x24, 0x2d, 0xf4, 0x53, 0x57, 0x65, + 0x9b, 0x75, 0xae, 0x2c, 0x27, 0xa7, 0x6f, 0x50, + }), + uint256(std::vector{ + 0xc0, 0xdb, 0x2a, 0x74, 0x99, 0x8c, 0x50, 0xeb, + 0x7b, 0xa6, 0x53, 0x4f, 0x6d, 0x41, 0x0e, 0xfc, + 0x27, 0xc4, 0xbb, 0x88, 0xac, 0xb0, 0x22, 0x2c, + 0x79, 0x06, 0xea, 0x28, 0xa3, 0x27, 0xb5, 0x11, + }), + uint256(std::vector{ + 0xd7, 0xc6, 0x12, 0xc8, 0x17, 0x79, 0x31, 0x91, + 0xa1, 0xe6, 0x86, 0x52, 0x12, 0x18, 0x76, 0xd6, + 0xb3, 0xbd, 0xe4, 0x0f, 0x4f, 0xa5, 0x2b, 0xc3, + 0x14, 0x14, 0x5c, 0xe6, 0xe5, 0xcd, 0xd2, 0x59, + }), + uint256(std::vector{ + 0xb2, 0x23, 0x70, 0x10, 0x6c, 0x67, 0xa1, 0x72, + 0x09, 0xf6, 0x13, 0x0b, 0xc0, 0x9f, 0x73, 0x5d, + 0x83, 0xaa, 0x2c, 0x04, 0xfc, 0x4f, 0xe7, 0x2e, + 0xa5, 0xd8, 0x0b, 0x21, 0x67, 0x23, 0xe7, 0xce, + }), + uint256(std::vector{ + 0x9f, 0x67, 0xd5, 0xf6, 0x64, 0x66, 0x4c, 0x90, + 0x19, 0x40, 0xee, 0xe3, 0xd0, 0x2d, 0xd5, 0xb3, + 0xe4, 0xb9, 0x2e, 0x7b, 0x42, 0x82, 0x0c, 0x42, + 0xfc, 0x51, 0x59, 0xe9, 0x1b, 0x41, 0x17, 0x2a, + }), + uint256(std::vector{ + 0xac, 0x58, 0xcd, 0x13, 0x88, 0xfe, 0xc2, 0x90, + 0xd3, 0x98, 0xf1, 0x94, 0x4b, 0x56, 0x44, 0x49, + 0xa6, 0x3c, 0x81, 0x58, 0x80, 0x56, 0x6b, 0xd1, + 0xd1, 0x89, 0xf7, 0x83, 0x9e, 0x3b, 0x0c, 0x8c, + }), + uint256(std::vector{ + 0x56, 0x98, 0xea, 0xe7, 0xc8, 0x51, 0x5e, 0xd0, + 0x5a, 0x70, 0x33, 0x9b, 0xdf, 0x7c, 0x10, 0x28, + 0xe7, 0xac, 0xca, 0x13, 0xa4, 0xfa, 0x97, 0xd9, + 0x53, 0x8f, 0x01, 0xac, 0x8d, 0x88, 0x9a, 0xe3, + }), + uint256(std::vector{ + 0x2d, 0x49, 0x95, 0x77, 0x0a, 0x76, 0xfb, 0x93, + 0x31, 0x4c, 0xa7, 0x4b, 0x35, 0x24, 0xea, 0x1d, + 0xb5, 0x68, 0x8a, 0xd0, 0xa7, 0x61, 0x83, 0xea, + 0x17, 0x20, 0x4a, 0x8f, 0x02, 0x4a, 0x9f, 0x3b, + }), + uint256(std::vector{ + 0x5e, 0x89, 0x92, 0xc1, 0xb0, 0x72, 0xc1, 0x6e, + 0x9e, 0x28, 0xa8, 0x53, 0x58, 0xfb, 0x5f, 0xb6, + 0x90, 0x1a, 0x81, 0x58, 0x77, 0x66, 0xda, 0xdb, + 0x7a, 0xa0, 0xb9, 0x73, 0xde, 0xd2, 0xf2, 0x64, + }), + uint256(std::vector{ + 0xe9, 0x5d, 0xb7, 0x1e, 0x1f, 0x72, 0x91, 0xba, + 0x54, 0x99, 0x46, 0x1b, 0xc7, 0x15, 0x20, 0x3e, + 0x29, 0xb8, 0x4b, 0xfa, 0x42, 0x83, 0xe3, 0xbb, + 0x7f, 0x47, 0x0a, 0x15, 0xd0, 0xe1, 0x58, 0x4e, + }), + uint256(std::vector{ + 0x41, 0xf0, 0x78, 0xbd, 0x18, 0x24, 0xc8, 0xa4, + 0xb7, 0x19, 0x64, 0xf3, 0x94, 0xaa, 0x59, 0x50, + 0x84, 0xd8, 0xeb, 0x17, 0xb9, 0x7a, 0x36, 0x30, + 0x43, 0x3a, 0xf7, 0x0d, 0x10, 0xe0, 0xef, 0xf6, + }), + uint256(std::vector{ + 0xa1, 0x91, 0x3f, 0xe6, 0xb2, 0x01, 0x32, 0x31, + 0x2f, 0x8c, 0x1f, 0x00, 0xdd, 0xd6, 0x3c, 0xec, + 0x7a, 0x03, 0xf5, 0xf1, 0xd7, 0xd8, 0x34, 0x92, + 0xfa, 0x28, 0x4c, 0x0b, 0x5d, 0x63, 0x20, 0xb0, + }), + uint256(std::vector{ + 0xba, 0x94, 0x40, 0xc4, 0xdb, 0xfc, 0xf5, 0x5c, + 0xeb, 0x60, 0x5a, 0x5b, 0x89, 0x90, 0xfc, 0x11, + 0xf8, 0xef, 0x22, 0x87, 0x0d, 0x8d, 0x12, 0xe1, + 0x30, 0xf9, 0x86, 0x49, 0x1e, 0xae, 0x84, 0xb3, + }), + uint256(std::vector{ + 0x49, 0xdb, 0x2d, 0x5e, 0x22, 0xb8, 0x01, 0x5c, + 0xae, 0x48, 0x10, 0xd7, 0x5e, 0x54, 0x01, 0x4c, + 0x54, 0x69, 0x86, 0x27, 0x38, 0xe1, 0x61, 0xec, + 0x96, 0xec, 0x20, 0x21, 0x87, 0x18, 0x82, 0x8a, + }), + uint256(std::vector{ + 0xd4, 0x85, 0x1f, 0xb8, 0x43, 0x1e, 0xdf, 0xbb, + 0x8b, 0x1e, 0x85, 0xad, 0xa6, 0x89, 0x59, 0x67, + 0xc2, 0xda, 0xc8, 0x7d, 0xf3, 0x44, 0x99, 0x2a, + 0x05, 0xfa, 0xf1, 0xec, 0xf8, 0x36, 0xee, 0xc9, + }), + uint256(std::vector{ + 0xe4, 0xab, 0x9f, 0x44, 0x70, 0xf0, 0x0c, 0xd1, + 0x96, 0xd4, 0x7c, 0x75, 0xc8, 0x2e, 0x7a, 0xda, + 0xf0, 0x6f, 0xe1, 0x7e, 0x04, 0x2e, 0x39, 0x53, + 0xd9, 0x3b, 0xb5, 0xd5, 0x6d, 0x8c, 0xd8, 0xfb, + }), + uint256(std::vector{ + 0x7e, 0x43, 0x20, 0x43, 0x48, 0x49, 0xec, 0xb3, + 0x57, 0xf1, 0xaf, 0xaa, 0xba, 0x21, 0xa5, 0x44, + 0x00, 0xef, 0x2d, 0x11, 0xcf, 0xf8, 0x3b, 0x93, + 0x7d, 0x87, 0xfd, 0xaf, 0xa4, 0x9f, 0x81, 0x99, + }), + uint256(std::vector{ + 0x02, 0x0a, 0xdc, 0x98, 0xd9, 0x6c, 0xfb, 0xbc, + 0xca, 0x15, 0xfc, 0x3a, 0xa0, 0x37, 0x60, 0xed, + 0x28, 0x66, 0x86, 0xc3, 0x5b, 0x5d, 0x92, 0xc7, + 0xcb, 0x64, 0xa9, 0x99, 0xb3, 0x94, 0xa8, 0x54, + }), + uint256(std::vector{ + 0x3a, 0x26, 0xb2, 0x9f, 0xe1, 0xac, 0xfd, 0xd6, + 0xc6, 0xa1, 0x51, 0xbc, 0xc3, 0xdb, 0xcb, 0x95, + 0xa1, 0x0e, 0xbe, 0x2f, 0x05, 0x53, 0xf8, 0x07, + 0x79, 0x56, 0x9b, 0x67, 0xb7, 0x24, 0x4e, 0x77, + }), + uint256(std::vector{ + 0xec, 0x2d, 0x09, 0x86, 0xe6, 0xa0, 0xdd, 0xf4, + 0x38, 0x97, 0xb2, 0xd4, 0xf2, 0x3b, 0xb0, 0x34, + 0xf5, 0x38, 0xff, 0xe0, 0x08, 0x27, 0xf3, 0x10, + 0xdc, 0x49, 0x63, 0xf3, 0x26, 0x7f, 0x0b, 0xfb, + }), + uint256(std::vector{ + 0xd4, 0x80, 0x73, 0xf8, 0x81, 0x9f, 0x81, 0xf0, + 0x35, 0x8e, 0x3f, 0xc3, 0x5a, 0x04, 0x7c, 0xc7, + 0x40, 0x82, 0xae, 0x1c, 0xb7, 0xee, 0x22, 0xfb, + 0x60, 0x9c, 0x01, 0x64, 0x93, 0x42, 0xd0, 0xe6, + }), + uint256(std::vector{ + 0xad, 0x80, 0x37, 0x60, 0x17, 0x93, 0xf1, 0x72, + 0x44, 0x1e, 0xcb, 0x00, 0xdc, 0x13, 0x8d, 0x9f, + 0xc5, 0x95, 0x71, 0x25, 0xec, 0xc3, 0x82, 0xec, + 0x65, 0xe3, 0x6f, 0x81, 0x7d, 0xc7, 0x99, 0xfb, + }), + uint256(std::vector{ + 0xca, 0x50, 0x0a, 0x54, 0x41, 0xf3, 0x6f, 0x4d, + 0xf6, 0x73, 0xd6, 0xb8, 0xed, 0x07, 0x5d, 0x36, + 0xda, 0xe2, 0xc7, 0xe6, 0x48, 0x14, 0x28, 0xc7, + 0x0a, 0x5a, 0x76, 0xb7, 0xa9, 0xbe, 0xbc, 0xe8, + }), + uint256(std::vector{ + 0x42, 0x2b, 0x6d, 0xdd, 0x47, 0x32, 0x31, 0xdc, + 0x4d, 0x56, 0xfe, 0x91, 0x34, 0x44, 0xcc, 0xd5, + 0x6f, 0x7c, 0x61, 0xf7, 0x47, 0xba, 0x57, 0xca, + 0x94, 0x6d, 0x5f, 0xef, 0x72, 0xd8, 0x40, 0xa0, + }), + uint256(std::vector{ + 0xab, 0x41, 0xf4, 0xec, 0xb7, 0xd7, 0x08, 0x96, + 0x15, 0x80, 0x0e, 0x19, 0xfc, 0xc5, 0x3b, 0x83, + 0x79, 0xed, 0x05, 0xee, 0x35, 0xc8, 0x25, 0x67, + 0x09, 0x55, 0x83, 0xfd, 0x90, 0xff, 0x30, 0x35, + }), + uint256(std::vector{ + 0xbb, 0xf7, 0x61, 0x82, 0x48, 0x35, 0x4c, 0xeb, + 0x1b, 0xc1, 0xfc, 0x9d, 0xbc, 0x42, 0xc4, 0x26, + 0xa4, 0xe2, 0xc1, 0xe0, 0xd4, 0x43, 0xc5, 0x68, + 0x3a, 0x92, 0x56, 0xc6, 0x2e, 0xcd, 0xc2, 0x6f, + }), + uint256(std::vector{ + 0xe5, 0x0a, 0xe7, 0x14, 0x79, 0xfc, 0x8e, 0xc5, + 0x69, 0x19, 0x2a, 0x13, 0x07, 0x2e, 0x01, 0x1a, + 0xfc, 0x24, 0x9f, 0x47, 0x1a, 0xf0, 0x95, 0x00, + 0xea, 0x39, 0xf7, 0x5d, 0x0a, 0xf8, 0x56, 0xbf, + }), + uint256(std::vector{ + 0xe7, 0x4c, 0x0b, 0x92, 0x20, 0x14, 0x7d, 0xb2, + 0xd5, 0x0a, 0x3b, 0x58, 0xd4, 0x13, 0x77, 0x5d, + 0x16, 0xc9, 0x84, 0x69, 0x0b, 0xe7, 0xd9, 0x0f, + 0x0b, 0xc4, 0x3d, 0x99, 0xdb, 0xa1, 0xb6, 0x89, + }), + uint256(std::vector{ + 0x29, 0x32, 0x4a, 0x0a, 0x48, 0xd1, 0x16, 0x57, + 0xa5, 0x1b, 0xa0, 0x8b, 0x00, 0x48, 0x79, 0xbf, + 0xcf, 0xc6, 0x6a, 0x1a, 0xcb, 0x7c, 0xe3, 0x6d, + 0xfe, 0x47, 0x8d, 0x26, 0x55, 0x48, 0x4b, 0x48, + }), + uint256(std::vector{ + 0x88, 0x95, 0x2e, 0x3d, 0x0a, 0xc0, 0x6c, 0xb1, + 0x6b, 0x66, 0x52, 0x01, 0x12, 0x22, 0x49, 0x65, + 0x9a, 0x22, 0x32, 0x5e, 0x01, 0xc8, 0x70, 0xf4, + 0x9e, 0x29, 0xda, 0x6b, 0x17, 0x57, 0xe0, 0x82, + }), + uint256(std::vector{ + 0xcd, 0xf8, 0x79, 0xf2, 0x43, 0x5b, 0x95, 0xaf, + 0x04, 0x2a, 0x3b, 0xf7, 0xb8, 0x50, 0xf7, 0x81, + 0x92, 0x46, 0xc8, 0x05, 0x28, 0x58, 0x03, 0xd6, + 0x7f, 0xfb, 0xf4, 0xf2, 0x95, 0xbe, 0xd0, 0x04, + }), + uint256(std::vector{ + 0xe0, 0x05, 0xe3, 0x24, 0x20, 0x0b, 0x4f, 0x42, + 0x8c, 0x62, 0xbc, 0x33, 0x31, 0xe6, 0x95, 0xc3, + 0x73, 0x60, 0x7c, 0xd0, 0xfa, 0xa9, 0x79, 0x03, + 0x41, 0xfa, 0x3b, 0xa1, 0xed, 0x22, 0x8b, 0xc5, + }), + uint256(std::vector{ + 0x35, 0x44, 0x47, 0x72, 0x7a, 0xa9, 0xa5, 0x3d, + 0xd8, 0x34, 0x5b, 0x6b, 0x6c, 0x69, 0x34, 0x43, + 0xe5, 0x6e, 0xf4, 0xae, 0xba, 0x13, 0xc4, 0x10, + 0x17, 0x9f, 0xc8, 0x58, 0x9e, 0x77, 0x33, 0xd5, + }), + uint256(std::vector{ + 0xda, 0x52, 0xdd, 0xa9, 0x1f, 0x28, 0x29, 0xc1, + 0x5c, 0x0e, 0x58, 0xd2, 0x9a, 0x95, 0x36, 0x0b, + 0x86, 0xab, 0x30, 0xcf, 0x0c, 0xac, 0x81, 0x01, + 0x83, 0x2a, 0x29, 0xf3, 0x8c, 0x31, 0x85, 0xf1, + }), + uint256(std::vector{ + 0xc7, 0xda, 0x78, 0x14, 0xe2, 0x28, 0xe1, 0x14, + 0x44, 0x11, 0xd7, 0x8b, 0x53, 0x60, 0x92, 0xfe, + 0x92, 0x0b, 0xcd, 0xfc, 0xc3, 0x6c, 0xf1, 0x9d, + 0x12, 0x59, 0x04, 0x7b, 0x26, 0x7d, 0x58, 0xb5, + }), + uint256(std::vector{ + 0xab, 0xa1, 0xf6, 0x8b, 0x6c, 0x2b, 0x4d, 0xb6, + 0xcc, 0x06, 0xa7, 0x34, 0x0e, 0x12, 0x31, 0x3c, + 0x4b, 0x4a, 0x4e, 0xa6, 0xde, 0xb1, 0x7d, 0xeb, + 0x3e, 0x1e, 0x66, 0xcd, 0x8e, 0xac, 0xf3, 0x2b, + }), + uint256(std::vector{ + 0xc1, 0x60, 0xae, 0x4f, 0x64, 0xab, 0x76, 0x4d, + 0x86, 0x4a, 0x52, 0xad, 0x5e, 0x33, 0x12, 0x6c, + 0x4b, 0x5c, 0xe1, 0x05, 0xa4, 0x7d, 0xee, 0xdd, + 0x75, 0xbc, 0x70, 0x19, 0x9a, 0x52, 0x47, 0xef, + }), + uint256(std::vector{ + 0xea, 0xdf, 0x23, 0xfc, 0x99, 0xd5, 0x14, 0xdd, + 0x8e, 0xa2, 0x04, 0xd2, 0x23, 0xe9, 0x8d, 0xa9, + 0x88, 0x83, 0x1f, 0x9b, 0x5d, 0x19, 0x40, 0x27, + 0x4c, 0xa5, 0x20, 0xb7, 0xfb, 0x17, 0x3d, 0x8a, + }), + uint256(std::vector{ + 0x5b, 0x8e, 0x14, 0xfa, 0xca, 0xc8, 0xa7, 0xc7, + 0xa3, 0xbf, 0xee, 0x8b, 0xae, 0x71, 0xf2, 0xf7, + 0x79, 0x3d, 0x3a, 0xd5, 0xfe, 0x33, 0x83, 0xf9, + 0x3a, 0xb6, 0x06, 0x1f, 0x2a, 0x11, 0xbb, 0x02 + }), +}; + +SHA256Compress SHA256Compress::EmptyRoot(size_t depth) { + return sha256_empty_roots.at(depth); +} + template class PathFiller { private: diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 79a90bc5b..1ebb2b499 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -57,14 +57,9 @@ public: template class EmptyMerkleRoots { public: - EmptyMerkleRoots() { - empty_roots.at(0) = Hash::uncommitted(); - for (size_t d = 1; d <= Depth; d++) { - empty_roots.at(d) = Hash::combine(empty_roots.at(d-1), empty_roots.at(d-1), d-1); - } - } - Hash empty_root(size_t depth) { - return empty_roots.at(depth); + EmptyMerkleRoots() { } + Hash empty_root(size_t depth) const { + return Hash::EmptyRoot(depth); } template friend bool operator==(const EmptyMerkleRoots& a, @@ -227,6 +222,7 @@ public: static SHA256Compress uncommitted() { return SHA256Compress(); } + static SHA256Compress EmptyRoot(size_t); }; class PedersenHash : public uint256 { @@ -241,6 +237,7 @@ public: ); static PedersenHash uncommitted(); + static PedersenHash EmptyRoot(size_t); }; template diff --git a/src/zcash/Proof.cpp b/src/zcash/Proof.cpp index af87d1b81..7ab1298a8 100644 --- a/src/zcash/Proof.cpp +++ b/src/zcash/Proof.cpp @@ -3,249 +3,16 @@ #include "crypto/common.h" #include -#include -#include #include -using namespace libsnark; - -typedef alt_bn128_pp curve_pp; -typedef alt_bn128_pp::G1_type curve_G1; -typedef alt_bn128_pp::G2_type curve_G2; -typedef alt_bn128_pp::GT_type curve_GT; -typedef alt_bn128_pp::Fp_type curve_Fr; -typedef alt_bn128_pp::Fq_type curve_Fq; -typedef alt_bn128_pp::Fqe_type curve_Fq2; - -BOOST_STATIC_ASSERT(sizeof(mp_limb_t) == 8); - namespace libzcash { -// FE2IP as defined in the protocol spec and IEEE Std 1363a-2004. -bigint<8> fq2_to_bigint(const curve_Fq2 &e) -{ - auto modq = curve_Fq::field_char(); - auto c0 = e.c0.as_bigint(); - auto c1 = e.c1.as_bigint(); - - bigint<8> temp = c1 * modq; - temp += c0; - return temp; -} - -// Writes a bigint in big endian -template -void write_bigint(base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob, const bigint &val) -{ - auto ptr = blob.begin(); - for (ssize_t i = LIMBS-1; i >= 0; i--, ptr += 8) { - WriteBE64(ptr, val.data[i]); - } -} - -// Reads a bigint from big endian -template -bigint read_bigint(const base_blob<8 * LIMBS * sizeof(mp_limb_t)> &blob) -{ - bigint ret; - - auto ptr = blob.begin(); - - for (ssize_t i = LIMBS-1; i >= 0; i--, ptr += 8) { - ret.data[i] = ReadBE64(ptr); - } - - return ret; -} - -template<> -Fq::Fq(curve_Fq element) : data() -{ - write_bigint<4>(data, element.as_bigint()); -} - -template<> -curve_Fq Fq::to_libsnark_fq() const -{ - auto element_bigint = read_bigint<4>(data); - - // Check that the integer is smaller than the modulus - auto modq = curve_Fq::field_char(); - element_bigint.limit(modq, "element is not in Fq"); - - return curve_Fq(element_bigint); -} - -template<> -Fq2::Fq2(curve_Fq2 element) : data() -{ - write_bigint<8>(data, fq2_to_bigint(element)); -} - -template<> -curve_Fq2 Fq2::to_libsnark_fq2() const -{ - bigint<4> modq = curve_Fq::field_char(); - bigint<8> combined = read_bigint<8>(data); - bigint<5> res; - bigint<4> c0; - bigint<8>::div_qr(res, c0, combined, modq); - bigint<4> c1 = res.shorten(modq, "element is not in Fq2"); - - return curve_Fq2(curve_Fq(c0), curve_Fq(c1)); -} - -template<> -CompressedG1::CompressedG1(curve_G1 point) -{ - if (point.is_zero()) { - throw std::domain_error("curve point is zero"); - } - - point.to_affine_coordinates(); - - x = Fq(point.X); - y_lsb = point.Y.as_bigint().data[0] & 1; -} - -template<> -curve_G1 CompressedG1::to_libsnark_g1() const -{ - curve_Fq x_coordinate = x.to_libsnark_fq(); - - // y = +/- sqrt(x^3 + b) - auto y_coordinate = ((x_coordinate.squared() * x_coordinate) + alt_bn128_coeff_b).sqrt(); - - if ((y_coordinate.as_bigint().data[0] & 1) != y_lsb) { - y_coordinate = -y_coordinate; - } - - curve_G1 r = curve_G1::one(); - r.X = x_coordinate; - r.Y = y_coordinate; - r.Z = curve_Fq::one(); - - assert(r.is_well_formed()); - - return r; -} - -template<> -CompressedG2::CompressedG2(curve_G2 point) -{ - if (point.is_zero()) { - throw std::domain_error("curve point is zero"); - } - - point.to_affine_coordinates(); - - x = Fq2(point.X); - y_gt = fq2_to_bigint(point.Y) > fq2_to_bigint(-(point.Y)); -} - -template<> -curve_G2 CompressedG2::to_libsnark_g2() const -{ - auto x_coordinate = x.to_libsnark_fq2(); - - // y = +/- sqrt(x^3 + b) - auto y_coordinate = ((x_coordinate.squared() * x_coordinate) + alt_bn128_twist_coeff_b).sqrt(); - auto y_coordinate_neg = -y_coordinate; - - if ((fq2_to_bigint(y_coordinate) > fq2_to_bigint(y_coordinate_neg)) != y_gt) { - y_coordinate = y_coordinate_neg; - } - - curve_G2 r = curve_G2::one(); - r.X = x_coordinate; - r.Y = y_coordinate; - r.Z = curve_Fq2::one(); - - assert(r.is_well_formed()); - - if (alt_bn128_modulus_r * r != curve_G2::zero()) { - throw std::runtime_error("point is not in G2"); - } - - return r; -} - -template<> -PHGRProof::PHGRProof(const r1cs_ppzksnark_proof &proof) -{ - g_A = CompressedG1(proof.g_A.g); - g_A_prime = CompressedG1(proof.g_A.h); - g_B = CompressedG2(proof.g_B.g); - g_B_prime = CompressedG1(proof.g_B.h); - g_C = CompressedG1(proof.g_C.g); - g_C_prime = CompressedG1(proof.g_C.h); - g_K = CompressedG1(proof.g_K); - g_H = CompressedG1(proof.g_H); -} - -template<> -r1cs_ppzksnark_proof PHGRProof::to_libsnark_proof() const -{ - r1cs_ppzksnark_proof proof; - - proof.g_A.g = g_A.to_libsnark_g1(); - proof.g_A.h = g_A_prime.to_libsnark_g1(); - proof.g_B.g = g_B.to_libsnark_g2(); - proof.g_B.h = g_B_prime.to_libsnark_g1(); - proof.g_C.g = g_C.to_libsnark_g1(); - proof.g_C.h = g_C_prime.to_libsnark_g1(); - proof.g_K = g_K.to_libsnark_g1(); - proof.g_H = g_H.to_libsnark_g1(); - - return proof; -} - -PHGRProof PHGRProof::random_invalid() -{ - PHGRProof p; - p.g_A = curve_G1::random_element(); - p.g_A_prime = curve_G1::random_element(); - p.g_B = curve_G2::random_element(); - p.g_B_prime = curve_G1::random_element(); - p.g_C = curve_G1::random_element(); - p.g_C_prime = curve_G1::random_element(); - - p.g_K = curve_G1::random_element(); - p.g_H = curve_G1::random_element(); - - return p; -} - -static std::once_flag init_public_params_once_flag; - -void initialize_curve_params() -{ - std::call_once (init_public_params_once_flag, curve_pp::init_public_params); -} - ProofVerifier ProofVerifier::Strict() { - initialize_curve_params(); return ProofVerifier(true); } ProofVerifier ProofVerifier::Disabled() { - initialize_curve_params(); return ProofVerifier(false); } -template<> -bool ProofVerifier::check( - const r1cs_ppzksnark_verification_key& vk, - const r1cs_ppzksnark_processed_verification_key& pvk, - const r1cs_primary_input& primary_input, - const r1cs_ppzksnark_proof& proof -) -{ - if (perform_verification) { - return r1cs_ppzksnark_online_verifier_strong_IC(pvk, primary_input, proof); - } else { - return true; - } -} - } diff --git a/src/zcash/Proof.hpp b/src/zcash/Proof.hpp index e06095d57..7c9b7f7f5 100644 --- a/src/zcash/Proof.hpp +++ b/src/zcash/Proof.hpp @@ -16,12 +16,6 @@ private: public: Fq() : data() { } - template - Fq(libsnark_Fq element); - - template - libsnark_Fq to_libsnark_fq() const; - ADD_SERIALIZE_METHODS; template @@ -49,12 +43,6 @@ private: public: Fq2() : data() { } - template - Fq2(libsnark_Fq2 element); - - template - libsnark_Fq2 to_libsnark_fq2() const; - ADD_SERIALIZE_METHODS; template @@ -84,12 +72,6 @@ private: public: CompressedG1() : y_lsb(false), x() { } - template - CompressedG1(libsnark_G1 point); - - template - libsnark_G1 to_libsnark_g1() const; - ADD_SERIALIZE_METHODS; template @@ -134,12 +116,6 @@ private: public: CompressedG2() : y_gt(false), x() { } - template - CompressedG2(libsnark_G2 point); - - template - libsnark_G2 to_libsnark_g2() const; - ADD_SERIALIZE_METHODS; template @@ -190,17 +166,6 @@ private: public: PHGRProof() : g_A(), g_A_prime(), g_B(), g_B_prime(), g_C(), g_C_prime(), g_K(), g_H() { } - // Produces a compressed proof using a libsnark zkSNARK proof - template - PHGRProof(const libsnark_proof& proof); - - // Produces a libsnark zkSNARK proof out of this proof, - // or throws an exception if it is invalid. - template - libsnark_proof to_libsnark_proof() const; - - static PHGRProof random_invalid(); - ADD_SERIALIZE_METHODS; template diff --git a/src/zcash/circuit/commitment.tcc b/src/zcash/circuit/commitment.tcc deleted file mode 100644 index d1b0b10fa..000000000 --- a/src/zcash/circuit/commitment.tcc +++ /dev/null @@ -1,100 +0,0 @@ -template -class note_commitment_gadget : gadget { -private: - std::shared_ptr> block1; - std::shared_ptr> block2; - std::shared_ptr> hasher1; - std::shared_ptr> intermediate_hash; - std::shared_ptr> hasher2; - -public: - note_commitment_gadget( - protoboard &pb, - pb_variable& ZERO, - pb_variable_array& a_pk, - pb_variable_array& v, - pb_variable_array& rho, - pb_variable_array& r, - std::shared_ptr> result - ) : gadget(pb) { - pb_variable_array leading_byte = - from_bits({1, 0, 1, 1, 0, 0, 0, 0}, ZERO); - - pb_variable_array first_of_rho(rho.begin(), rho.begin()+184); - pb_variable_array last_of_rho(rho.begin()+184, rho.end()); - - intermediate_hash.reset(new digest_variable(pb, 256, "")); - - // final padding - pb_variable_array length_padding = - from_bits({ - // padding - 1,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - - // length of message (840 bits) - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,1,1, - 0,1,0,0,1,0,0,0 - }, ZERO); - - block1.reset(new block_variable(pb, { - leading_byte, - a_pk, - v, - first_of_rho - }, "")); - - block2.reset(new block_variable(pb, { - last_of_rho, - r, - length_padding - }, "")); - - pb_linear_combination_array IV = SHA256_default_IV(pb); - - hasher1.reset(new sha256_compression_function_gadget( - pb, - IV, - block1->bits, - *intermediate_hash, - "")); - - pb_linear_combination_array IV2(intermediate_hash->bits); - - hasher2.reset(new sha256_compression_function_gadget( - pb, - IV2, - block2->bits, - *result, - "")); - } - - void generate_r1cs_constraints() { - hasher1->generate_r1cs_constraints(); - hasher2->generate_r1cs_constraints(); - } - - void generate_r1cs_witness() { - hasher1->generate_r1cs_witness(); - hasher2->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/gadget.tcc b/src/zcash/circuit/gadget.tcc deleted file mode 100644 index 0a2ec7719..000000000 --- a/src/zcash/circuit/gadget.tcc +++ /dev/null @@ -1,349 +0,0 @@ -#include "zcash/circuit/utils.tcc" -#include "zcash/circuit/prfs.tcc" -#include "zcash/circuit/commitment.tcc" -#include "zcash/circuit/merkle.tcc" -#include "zcash/circuit/note.tcc" - -template -class joinsplit_gadget : gadget { -private: - // Verifier inputs - pb_variable_array zk_packed_inputs; - pb_variable_array zk_unpacked_inputs; - std::shared_ptr> unpacker; - - std::shared_ptr> zk_merkle_root; - std::shared_ptr> zk_h_sig; - std::array>, NumInputs> zk_input_nullifiers; - std::array>, NumInputs> zk_input_macs; - std::array>, NumOutputs> zk_output_commitments; - pb_variable_array zk_vpub_old; - pb_variable_array zk_vpub_new; - - // Aux inputs - pb_variable ZERO; - std::shared_ptr> zk_phi; - pb_variable_array zk_total_uint64; - - // Input note gadgets - std::array>, NumInputs> zk_input_notes; - std::array>, NumInputs> zk_mac_authentication; - - // Output note gadgets - std::array>, NumOutputs> zk_output_notes; - -public: - // PRF_pk only has a 1-bit domain separation "nonce" - // for different macs. - BOOST_STATIC_ASSERT(NumInputs <= 2); - - // PRF_rho only has a 1-bit domain separation "nonce" - // for different output `rho`. - BOOST_STATIC_ASSERT(NumOutputs <= 2); - - joinsplit_gadget(protoboard &pb) : gadget(pb) { - // Verification - { - // The verification inputs are all bit-strings of various - // lengths (256-bit digests and 64-bit integers) and so we - // pack them into as few field elements as possible. (The - // more verification inputs you have, the more expensive - // verification is.) - zk_packed_inputs.allocate(pb, verifying_field_element_size()); - pb.set_input_sizes(verifying_field_element_size()); - - alloc_uint256(zk_unpacked_inputs, zk_merkle_root); - alloc_uint256(zk_unpacked_inputs, zk_h_sig); - - for (size_t i = 0; i < NumInputs; i++) { - alloc_uint256(zk_unpacked_inputs, zk_input_nullifiers[i]); - alloc_uint256(zk_unpacked_inputs, zk_input_macs[i]); - } - - for (size_t i = 0; i < NumOutputs; i++) { - alloc_uint256(zk_unpacked_inputs, zk_output_commitments[i]); - } - - alloc_uint64(zk_unpacked_inputs, zk_vpub_old); - alloc_uint64(zk_unpacked_inputs, zk_vpub_new); - - assert(zk_unpacked_inputs.size() == verifying_input_bit_size()); - - // This gadget will ensure that all of the inputs we provide are - // boolean constrained. - unpacker.reset(new multipacking_gadget( - pb, - zk_unpacked_inputs, - zk_packed_inputs, - FieldT::capacity(), - "unpacker" - )); - } - - // We need a constant "zero" variable in some contexts. In theory - // it should never be necessary, but libsnark does not synthesize - // optimal circuits. - // - // The first variable of our constraint system is constrained - // to be one automatically for us, and is known as `ONE`. - ZERO.allocate(pb); - - zk_phi.reset(new digest_variable(pb, 252, "")); - - zk_total_uint64.allocate(pb, 64); - - for (size_t i = 0; i < NumInputs; i++) { - // Input note gadget for commitments, macs, nullifiers, - // and spend authority. - zk_input_notes[i].reset(new input_note_gadget( - pb, - ZERO, - zk_input_nullifiers[i], - *zk_merkle_root - )); - - // The input keys authenticate h_sig to prevent - // malleability. - zk_mac_authentication[i].reset(new PRF_pk_gadget( - pb, - ZERO, - zk_input_notes[i]->a_sk->bits, - zk_h_sig->bits, - i ? true : false, - zk_input_macs[i] - )); - } - - for (size_t i = 0; i < NumOutputs; i++) { - zk_output_notes[i].reset(new output_note_gadget( - pb, - ZERO, - zk_phi->bits, - zk_h_sig->bits, - i ? true : false, - zk_output_commitments[i] - )); - } - } - - void generate_r1cs_constraints() { - // The true passed here ensures all the inputs - // are boolean constrained. - unpacker->generate_r1cs_constraints(true); - - // Constrain `ZERO` - generate_r1cs_equals_const_constraint(this->pb, ZERO, FieldT::zero(), "ZERO"); - - // Constrain bitness of phi - zk_phi->generate_r1cs_constraints(); - - for (size_t i = 0; i < NumInputs; i++) { - // Constrain the JoinSplit input constraints. - zk_input_notes[i]->generate_r1cs_constraints(); - - // Authenticate h_sig with a_sk - zk_mac_authentication[i]->generate_r1cs_constraints(); - } - - for (size_t i = 0; i < NumOutputs; i++) { - // Constrain the JoinSplit output constraints. - zk_output_notes[i]->generate_r1cs_constraints(); - } - - // Value balance - { - linear_combination left_side = packed_addition(zk_vpub_old); - for (size_t i = 0; i < NumInputs; i++) { - left_side = left_side + packed_addition(zk_input_notes[i]->value); - } - - linear_combination right_side = packed_addition(zk_vpub_new); - for (size_t i = 0; i < NumOutputs; i++) { - right_side = right_side + packed_addition(zk_output_notes[i]->value); - } - - // Ensure that both sides are equal - this->pb.add_r1cs_constraint(r1cs_constraint( - 1, - left_side, - right_side - )); - - // #854: Ensure that left_side is a 64-bit integer. - for (size_t i = 0; i < 64; i++) { - generate_boolean_r1cs_constraint( - this->pb, - zk_total_uint64[i], - "" - ); - } - - this->pb.add_r1cs_constraint(r1cs_constraint( - 1, - left_side, - packed_addition(zk_total_uint64) - )); - } - } - - void generate_r1cs_witness( - const uint252& phi, - const uint256& rt, - const uint256& h_sig, - const std::array& inputs, - const std::array& outputs, - uint64_t vpub_old, - uint64_t vpub_new - ) { - // Witness `zero` - this->pb.val(ZERO) = FieldT::zero(); - - // Witness rt. This is not a sanity check. - // - // This ensures the read gadget constrains - // the intended root in the event that - // both inputs are zero-valued. - zk_merkle_root->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(rt) - ); - - // Witness public balance values - zk_vpub_old.fill_with_bits( - this->pb, - uint64_to_bool_vector(vpub_old) - ); - zk_vpub_new.fill_with_bits( - this->pb, - uint64_to_bool_vector(vpub_new) - ); - - { - // Witness total_uint64 bits - uint64_t left_side_acc = vpub_old; - for (size_t i = 0; i < NumInputs; i++) { - left_side_acc += inputs[i].note.value(); - } - - zk_total_uint64.fill_with_bits( - this->pb, - uint64_to_bool_vector(left_side_acc) - ); - } - - // Witness phi - zk_phi->bits.fill_with_bits( - this->pb, - uint252_to_bool_vector(phi) - ); - - // Witness h_sig - zk_h_sig->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(h_sig) - ); - - for (size_t i = 0; i < NumInputs; i++) { - // Witness the input information. - auto merkle_path = inputs[i].witness.path(); - zk_input_notes[i]->generate_r1cs_witness( - merkle_path, - inputs[i].key, - inputs[i].note - ); - - // Witness macs - zk_mac_authentication[i]->generate_r1cs_witness(); - } - - for (size_t i = 0; i < NumOutputs; i++) { - // Witness the output information. - zk_output_notes[i]->generate_r1cs_witness(outputs[i]); - } - - // [SANITY CHECK] Ensure that the intended root - // was witnessed by the inputs, even if the read - // gadget overwrote it. This allows the prover to - // fail instead of the verifier, in the event that - // the roots of the inputs do not match the - // treestate provided to the proving API. - zk_merkle_root->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(rt) - ); - - // This happens last, because only by now are all the - // verifier inputs resolved. - unpacker->generate_r1cs_witness_from_bits(); - } - - static r1cs_primary_input witness_map( - const uint256& rt, - const uint256& h_sig, - const std::array& macs, - const std::array& nullifiers, - const std::array& commitments, - uint64_t vpub_old, - uint64_t vpub_new - ) { - std::vector verify_inputs; - - insert_uint256(verify_inputs, rt); - insert_uint256(verify_inputs, h_sig); - - for (size_t i = 0; i < NumInputs; i++) { - insert_uint256(verify_inputs, nullifiers[i]); - insert_uint256(verify_inputs, macs[i]); - } - - for (size_t i = 0; i < NumOutputs; i++) { - insert_uint256(verify_inputs, commitments[i]); - } - - insert_uint64(verify_inputs, vpub_old); - insert_uint64(verify_inputs, vpub_new); - - assert(verify_inputs.size() == verifying_input_bit_size()); - auto verify_field_elements = pack_bit_vector_into_field_element_vector(verify_inputs); - assert(verify_field_elements.size() == verifying_field_element_size()); - return verify_field_elements; - } - - static size_t verifying_input_bit_size() { - size_t acc = 0; - - acc += 256; // the merkle root (anchor) - acc += 256; // h_sig - for (size_t i = 0; i < NumInputs; i++) { - acc += 256; // nullifier - acc += 256; // mac - } - for (size_t i = 0; i < NumOutputs; i++) { - acc += 256; // new commitment - } - acc += 64; // vpub_old - acc += 64; // vpub_new - - return acc; - } - - static size_t verifying_field_element_size() { - return div_ceil(verifying_input_bit_size(), FieldT::capacity()); - } - - void alloc_uint256( - pb_variable_array& packed_into, - std::shared_ptr>& var - ) { - var.reset(new digest_variable(this->pb, 256, "")); - packed_into.insert(packed_into.end(), var->bits.begin(), var->bits.end()); - } - - void alloc_uint64( - pb_variable_array& packed_into, - pb_variable_array& integer - ) { - integer.allocate(this->pb, 64, ""); - packed_into.insert(packed_into.end(), integer.begin(), integer.end()); - } -}; diff --git a/src/zcash/circuit/merkle.tcc b/src/zcash/circuit/merkle.tcc deleted file mode 100644 index 09f02ae9f..000000000 --- a/src/zcash/circuit/merkle.tcc +++ /dev/null @@ -1,60 +0,0 @@ -template -class merkle_tree_gadget : gadget { -private: - typedef sha256_two_to_one_hash_gadget sha256_gadget; - - pb_variable_array positions; - std::shared_ptr> authvars; - std::shared_ptr> auth; - -public: - merkle_tree_gadget( - protoboard& pb, - digest_variable leaf, - digest_variable root, - pb_variable& enforce - ) : gadget(pb) { - positions.allocate(pb, INCREMENTAL_MERKLE_TREE_DEPTH); - authvars.reset(new merkle_authentication_path_variable( - pb, INCREMENTAL_MERKLE_TREE_DEPTH, "auth" - )); - auth.reset(new merkle_tree_check_read_gadget( - pb, - INCREMENTAL_MERKLE_TREE_DEPTH, - positions, - leaf, - root, - *authvars, - enforce, - "" - )); - } - - void generate_r1cs_constraints() { - for (size_t i = 0; i < INCREMENTAL_MERKLE_TREE_DEPTH; i++) { - // TODO: This might not be necessary, and doesn't - // appear to be done in libsnark's tests, but there - // is no documentation, so let's do it anyway to - // be safe. - generate_boolean_r1cs_constraint( - this->pb, - positions[i], - "boolean_positions" - ); - } - - authvars->generate_r1cs_constraints(); - auth->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const MerklePath& path) { - // TODO: Change libsnark so that it doesn't require this goofy - // number thing in its API. - size_t path_index = convertVectorToInt(path.index); - - positions.fill_with_bits_of_uint64(this->pb, path_index); - - authvars->generate_r1cs_witness(path_index, path.authentication_path); - auth->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/note.tcc b/src/zcash/circuit/note.tcc deleted file mode 100644 index c598c62ee..000000000 --- a/src/zcash/circuit/note.tcc +++ /dev/null @@ -1,244 +0,0 @@ -template -class note_gadget : public gadget { -public: - pb_variable_array value; - std::shared_ptr> r; - - note_gadget(protoboard &pb) : gadget(pb) { - value.allocate(pb, 64); - r.reset(new digest_variable(pb, 256, "")); - } - - void generate_r1cs_constraints() { - for (size_t i = 0; i < 64; i++) { - generate_boolean_r1cs_constraint( - this->pb, - value[i], - "boolean_value" - ); - } - - r->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const SproutNote& note) { - r->bits.fill_with_bits(this->pb, uint256_to_bool_vector(note.r)); - value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value())); - } -}; - -template -class input_note_gadget : public note_gadget { -private: - std::shared_ptr> a_pk; - std::shared_ptr> rho; - - std::shared_ptr> commitment; - std::shared_ptr> commit_to_inputs; - - pb_variable value_enforce; - std::shared_ptr> witness_input; - - std::shared_ptr> spend_authority; - std::shared_ptr> expose_nullifiers; -public: - std::shared_ptr> a_sk; - - input_note_gadget( - protoboard& pb, - pb_variable& ZERO, - std::shared_ptr> nullifier, - digest_variable rt - ) : note_gadget(pb) { - a_sk.reset(new digest_variable(pb, 252, "")); - a_pk.reset(new digest_variable(pb, 256, "")); - rho.reset(new digest_variable(pb, 256, "")); - commitment.reset(new digest_variable(pb, 256, "")); - - spend_authority.reset(new PRF_addr_a_pk_gadget( - pb, - ZERO, - a_sk->bits, - a_pk - )); - - expose_nullifiers.reset(new PRF_nf_gadget( - pb, - ZERO, - a_sk->bits, - rho->bits, - nullifier - )); - - commit_to_inputs.reset(new note_commitment_gadget( - pb, - ZERO, - a_pk->bits, - this->value, - rho->bits, - this->r->bits, - commitment - )); - - value_enforce.allocate(pb); - - witness_input.reset(new merkle_tree_gadget( - pb, - *commitment, - rt, - value_enforce - )); - } - - void generate_r1cs_constraints() { - note_gadget::generate_r1cs_constraints(); - - a_sk->generate_r1cs_constraints(); - rho->generate_r1cs_constraints(); - - spend_authority->generate_r1cs_constraints(); - expose_nullifiers->generate_r1cs_constraints(); - - commit_to_inputs->generate_r1cs_constraints(); - - // value * (1 - enforce) = 0 - // Given `enforce` is boolean constrained: - // If `value` is zero, `enforce` _can_ be zero. - // If `value` is nonzero, `enforce` _must_ be one. - generate_boolean_r1cs_constraint(this->pb, value_enforce,""); - - this->pb.add_r1cs_constraint(r1cs_constraint( - packed_addition(this->value), - (1 - value_enforce), - 0 - ), ""); - - witness_input->generate_r1cs_constraints(); - } - - void generate_r1cs_witness( - const MerklePath& path, - const SproutSpendingKey& key, - const SproutNote& note - ) { - note_gadget::generate_r1cs_witness(note); - - // Witness a_sk for the input - a_sk->bits.fill_with_bits( - this->pb, - uint252_to_bool_vector(key) - ); - - // Witness a_pk for a_sk with PRF_addr - spend_authority->generate_r1cs_witness(); - - // [SANITY CHECK] Witness a_pk with note information - a_pk->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.a_pk) - ); - - // Witness rho for the input note - rho->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.rho) - ); - - // Witness the nullifier for the input note - expose_nullifiers->generate_r1cs_witness(); - - // Witness the commitment of the input note - commit_to_inputs->generate_r1cs_witness(); - - // [SANITY CHECK] Ensure the commitment is - // valid. - commitment->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.cm()) - ); - - // Set enforce flag for nonzero input value - this->pb.val(value_enforce) = (note.value() != 0) ? FieldT::one() : FieldT::zero(); - - // Witness merkle tree authentication path - witness_input->generate_r1cs_witness(path); - } -}; - -template -class output_note_gadget : public note_gadget { -private: - std::shared_ptr> rho; - std::shared_ptr> a_pk; - - std::shared_ptr> prevent_faerie_gold; - std::shared_ptr> commit_to_outputs; - -public: - output_note_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& phi, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> commitment - ) : note_gadget(pb) { - rho.reset(new digest_variable(pb, 256, "")); - a_pk.reset(new digest_variable(pb, 256, "")); - - // Do not allow the caller to choose the same "rho" - // for any two valid notes in a given view of the - // blockchain. See protocol specification for more - // details. - prevent_faerie_gold.reset(new PRF_rho_gadget( - pb, - ZERO, - phi, - h_sig, - nonce, - rho - )); - - // Commit to the output notes publicly without - // disclosing them. - commit_to_outputs.reset(new note_commitment_gadget( - pb, - ZERO, - a_pk->bits, - this->value, - rho->bits, - this->r->bits, - commitment - )); - } - - void generate_r1cs_constraints() { - note_gadget::generate_r1cs_constraints(); - - a_pk->generate_r1cs_constraints(); - - prevent_faerie_gold->generate_r1cs_constraints(); - - commit_to_outputs->generate_r1cs_constraints(); - } - - void generate_r1cs_witness(const SproutNote& note) { - note_gadget::generate_r1cs_witness(note); - - prevent_faerie_gold->generate_r1cs_witness(); - - // [SANITY CHECK] Witness rho ourselves with the - // note information. - rho->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.rho) - ); - - a_pk->bits.fill_with_bits( - this->pb, - uint256_to_bool_vector(note.a_pk) - ); - - commit_to_outputs->generate_r1cs_witness(); - } -}; diff --git a/src/zcash/circuit/prfs.tcc b/src/zcash/circuit/prfs.tcc deleted file mode 100644 index 3f50ac9e5..000000000 --- a/src/zcash/circuit/prfs.tcc +++ /dev/null @@ -1,109 +0,0 @@ -template -class PRF_gadget : gadget { -private: - std::shared_ptr> block; - std::shared_ptr> hasher; - std::shared_ptr> result; - -public: - PRF_gadget( - protoboard& pb, - pb_variable& ZERO, - bool a, - bool b, - bool c, - bool d, - pb_variable_array x, - pb_variable_array y, - std::shared_ptr> result - ) : gadget(pb), result(result) { - - pb_linear_combination_array IV = SHA256_default_IV(pb); - - pb_variable_array discriminants; - discriminants.emplace_back(a ? ONE : ZERO); - discriminants.emplace_back(b ? ONE : ZERO); - discriminants.emplace_back(c ? ONE : ZERO); - discriminants.emplace_back(d ? ONE : ZERO); - - block.reset(new block_variable(pb, { - discriminants, - x, - y - }, "PRF_block")); - - hasher.reset(new sha256_compression_function_gadget( - pb, - IV, - block->bits, - *result, - "PRF_hasher")); - } - - void generate_r1cs_constraints() { - hasher->generate_r1cs_constraints(); - } - - void generate_r1cs_witness() { - hasher->generate_r1cs_witness(); - } -}; - -template -pb_variable_array gen256zeroes(pb_variable& ZERO) { - pb_variable_array ret; - while (ret.size() < 256) { - ret.emplace_back(ZERO); - } - - return ret; -} - -template -class PRF_addr_a_pk_gadget : public PRF_gadget { -public: - PRF_addr_a_pk_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 1, 1, 0, 0, a_sk, gen256zeroes(ZERO), result) {} -}; - -template -class PRF_nf_gadget : public PRF_gadget { -public: - PRF_nf_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - pb_variable_array& rho, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 1, 1, 1, 0, a_sk, rho, result) {} -}; - -template -class PRF_pk_gadget : public PRF_gadget { -public: - PRF_pk_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& a_sk, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 0, nonce, 0, 0, a_sk, h_sig, result) {} -}; - -template -class PRF_rho_gadget : public PRF_gadget { -public: - PRF_rho_gadget( - protoboard& pb, - pb_variable& ZERO, - pb_variable_array& phi, - pb_variable_array& h_sig, - bool nonce, - std::shared_ptr> result - ) : PRF_gadget(pb, ZERO, 0, nonce, 1, 0, phi, h_sig, result) {} -}; diff --git a/src/zcash/circuit/utils.tcc b/src/zcash/circuit/utils.tcc deleted file mode 100644 index fa7ae324a..000000000 --- a/src/zcash/circuit/utils.tcc +++ /dev/null @@ -1,75 +0,0 @@ -#include "uint252.h" - -template -pb_variable_array from_bits(std::vector bits, pb_variable& ZERO) { - pb_variable_array acc; - - BOOST_FOREACH(bool bit, bits) { - acc.emplace_back(bit ? ONE : ZERO); - } - - return acc; -} - -std::vector trailing252(std::vector input) { - if (input.size() != 256) { - throw std::length_error("trailing252 input invalid length"); - } - - return std::vector(input.begin() + 4, input.end()); -} - -template -std::vector to_bool_vector(T input) { - std::vector input_v(input.begin(), input.end()); - - return convertBytesVectorToVector(input_v); -} - -std::vector uint256_to_bool_vector(uint256 input) { - return to_bool_vector(input); -} - -std::vector uint252_to_bool_vector(uint252 input) { - return trailing252(to_bool_vector(input)); -} - -std::vector uint64_to_bool_vector(uint64_t input) { - auto num_bv = convertIntToVectorLE(input); - - return convertBytesVectorToVector(num_bv); -} - -void insert_uint256(std::vector& into, uint256 from) { - std::vector blob = uint256_to_bool_vector(from); - into.insert(into.end(), blob.begin(), blob.end()); -} - -void insert_uint64(std::vector& into, uint64_t from) { - std::vector num = uint64_to_bool_vector(from); - into.insert(into.end(), num.begin(), num.end()); -} - -template -T swap_endianness_u64(T v) { - if (v.size() != 64) { - throw std::length_error("invalid bit length for 64-bit unsigned integer"); - } - - for (size_t i = 0; i < 4; i++) { - for (size_t j = 0; j < 8; j++) { - std::swap(v[i*8 + j], v[((7-i)*8)+j]); - } - } - - return v; -} - -template -linear_combination packed_addition(pb_variable_array input) { - auto input_swapped = swap_endianness_u64(input); - - return pb_packing_sum(pb_variable_array( - input_swapped.rbegin(), input_swapped.rend() - )); -} diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 209b820b8..c3783e97a 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include #include #include @@ -91,24 +93,6 @@ double benchmark_sleep() return timer_stop(tv_start); } -double benchmark_parameter_loading() -{ - // FIXME: this is duplicated with the actual loading code - boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; - boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; - - struct timeval tv_start; - timer_start(tv_start); - - auto newParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); - - double ret = timer_stop(tv_start); - - delete newParams; - - return ret; -} - double benchmark_create_joinsplit() { uint256 joinSplitPubKey; @@ -118,8 +102,7 @@ double benchmark_create_joinsplit() struct timeval tv_start; timer_start(tv_start); - JSDescription jsdesc(true, - *pzcashParams, + JSDescription jsdesc(*pzcashParams, joinSplitPubKey, anchor, {JSInput(), JSInput()}, diff --git a/src/zcbenchmarks.h b/src/zcbenchmarks.h index 363823838..49cf4b749 100644 --- a/src/zcbenchmarks.h +++ b/src/zcbenchmarks.h @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers #ifndef BENCHMARKS_H #define BENCHMARKS_H @@ -5,7 +6,6 @@ #include extern double benchmark_sleep(); -extern double benchmark_parameter_loading(); extern double benchmark_create_joinsplit(); extern std::vector benchmark_create_joinsplit_threaded(int nThreads); extern double benchmark_solve_equihash(); diff --git a/zcutil/build-win.sh b/zcutil/build-win.sh index e8c0465d9..ccf6657e8 100755 --- a/zcutil/build-win.sh +++ b/zcutil/build-win.sh @@ -18,7 +18,7 @@ echo $PWD cd $WD ./autogen.sh -CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site CXXFLAGS="-DPTW32_STATIC_LIB -DCURL_STATICLIB -DCURVE_ALT_BN128 -fopenmp -pthread" ./configure --prefix="${PREFIX}" --host=x86_64-w64-mingw32 --enable-static --disable-shared +CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site CXXFLAGS="-DPTW32_STATIC_LIB -DCURL_STATICLIB -fopenmp -pthread" ./configure --prefix="${PREFIX}" --host=x86_64-w64-mingw32 --enable-static --disable-shared sed -i 's/-lboost_system-mt /-lboost_system-mt-s /' configure cd src/ CC="${CC} -g " CXX="${CXX} -g " make V=1 komodod.exe komodo-cli.exe komodo-tx.exe From aeb30dd8fa37fe823fce2e3b188ec05017ba3874 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 07:09:47 -0500 Subject: [PATCH 006/220] We do not use any of these CCs, and we want to remove gmp as dependency, so convert them to use mini-gmp.h for now --- src/cc/CCPayments.h | 2 +- src/cc/CCrewards.h | 2 +- src/cc/pegs.cpp | 2 +- src/cc/prices.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index ac5f22c47..30c61bb0c 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -18,7 +18,7 @@ #define CC_PAYMENTS_H #include "CCinclude.h" -#include +#include "mini-gmp.h" #include #define PAYMENTS_TXFEE 10000 diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h index d9f9edf6e..f9b8672a0 100644 --- a/src/cc/CCrewards.h +++ b/src/cc/CCrewards.h @@ -18,7 +18,7 @@ #define CC_REWARDS_H #include "CCinclude.h" -#include +#include "mini-gmp.h" #define EVAL_REWARDS 0xe5 #define REWARDSCC_MAXAPR (COIN * 25) diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp index 6ef33a884..88ef1eb00 100644 --- a/src/cc/pegs.cpp +++ b/src/cc/pegs.cpp @@ -16,7 +16,7 @@ #include "CCPegs.h" #include "../importcoin.h" #include "key_io.h" -#include +#include "mini-gmp.h" /* diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 0fcc2e512..4b5aebd65 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -73,7 +73,7 @@ GetKomodoEarlytxidScriptPub is on line #2080 of komodo_bitcoind.h #include "CCPrices.h" #include -#include +#include "mini-gmp.h" #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) From 1f1e2ebf0468dbbee3654f2de3df17bbd4d2ef93 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 07:20:06 -0500 Subject: [PATCH 007/220] Raw transaction updates --- src/primitives/transaction.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 2bc7b48c6..b4441758c 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -45,8 +45,9 @@ #include "zcash/JoinSplit.hpp" #include "zcash/Proof.hpp" -extern uint32_t ASSETCHAINS_MAGIC; -extern std::string ASSETCHAINS_SELFIMPORT; +#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION) // Overwinter transaction version static const int32_t OVERWINTER_TX_VERSION = 3; @@ -252,7 +253,6 @@ public: JSDescription(): vpub_old(0), vpub_new(0) { } JSDescription( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, @@ -265,7 +265,6 @@ public: ); static JSDescription Randomized( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, @@ -579,7 +578,7 @@ public: const CAmount valueBalance; const std::vector vShieldedSpend; const std::vector vShieldedOutput; - const std::vector vjoinsplit; + const std::vector vJoinSplit; const uint256 joinSplitPubKey; const joinsplit_sig_t joinSplitSig = {{0}}; const binding_sig_t bindingSig = {{0}}; @@ -636,8 +635,8 @@ public: } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, *const_cast*>(&vjoinsplit), ser_action); - if (vjoinsplit.size() > 0) { + ::SerReadWrite(os, *const_cast*>(&vJoinSplit), ser_action); + if (vJoinSplit.size() > 0) { READWRITE(*const_cast(&joinSplitPubKey)); READWRITE(*const_cast(&joinSplitSig)); } @@ -744,7 +743,7 @@ struct CMutableTransaction CAmount valueBalance; std::vector vShieldedSpend; std::vector vShieldedOutput; - std::vector vjoinsplit; + std::vector vJoinSplit; uint256 joinSplitPubKey; CTransaction::joinsplit_sig_t joinSplitSig = {{0}}; CTransaction::binding_sig_t bindingSig = {{0}}; @@ -800,8 +799,8 @@ struct CMutableTransaction } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, vjoinsplit, ser_action); - if (vjoinsplit.size() > 0) { + ::SerReadWrite(os, vJoinSplit, ser_action); + if (vJoinSplit.size() > 0) { READWRITE(joinSplitPubKey); READWRITE(joinSplitSig); } From c6de8f850cefa9111ded6c883c175136e2993cda Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 07:29:49 -0500 Subject: [PATCH 008/220] Revert "Raw transaction updates" This reverts commit 1f1e2ebf0468dbbee3654f2de3df17bbd4d2ef93. --- src/primitives/transaction.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index b4441758c..2bc7b48c6 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -45,9 +45,8 @@ #include "zcash/JoinSplit.hpp" #include "zcash/Proof.hpp" -#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION) -#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION) -#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION) +extern uint32_t ASSETCHAINS_MAGIC; +extern std::string ASSETCHAINS_SELFIMPORT; // Overwinter transaction version static const int32_t OVERWINTER_TX_VERSION = 3; @@ -253,6 +252,7 @@ public: JSDescription(): vpub_old(0), vpub_new(0) { } JSDescription( + bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, @@ -265,6 +265,7 @@ public: ); static JSDescription Randomized( + bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, @@ -578,7 +579,7 @@ public: const CAmount valueBalance; const std::vector vShieldedSpend; const std::vector vShieldedOutput; - const std::vector vJoinSplit; + const std::vector vjoinsplit; const uint256 joinSplitPubKey; const joinsplit_sig_t joinSplitSig = {{0}}; const binding_sig_t bindingSig = {{0}}; @@ -635,8 +636,8 @@ public: } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, *const_cast*>(&vJoinSplit), ser_action); - if (vJoinSplit.size() > 0) { + ::SerReadWrite(os, *const_cast*>(&vjoinsplit), ser_action); + if (vjoinsplit.size() > 0) { READWRITE(*const_cast(&joinSplitPubKey)); READWRITE(*const_cast(&joinSplitSig)); } @@ -743,7 +744,7 @@ struct CMutableTransaction CAmount valueBalance; std::vector vShieldedSpend; std::vector vShieldedOutput; - std::vector vJoinSplit; + std::vector vjoinsplit; uint256 joinSplitPubKey; CTransaction::joinsplit_sig_t joinSplitSig = {{0}}; CTransaction::binding_sig_t bindingSig = {{0}}; @@ -799,8 +800,8 @@ struct CMutableTransaction } if (nVersion >= 2) { auto os = WithVersion(&s, static_cast(header)); - ::SerReadWrite(os, vJoinSplit, ser_action); - if (vJoinSplit.size() > 0) { + ::SerReadWrite(os, vjoinsplit, ser_action); + if (vjoinsplit.size() > 0) { READWRITE(joinSplitPubKey); READWRITE(joinSplitSig); } From 89bbd48eaecac1c123b49aee0e8185c7bfb276c6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 12:30:58 -0500 Subject: [PATCH 009/220] More libsnark removal changes to various internals --- src/primitives/transaction.cpp | 58 +------------------ src/primitives/transaction.h | 7 ++- src/utiltest.cpp | 5 +- .../asyncrpcoperation_mergetoaddress.cpp | 4 +- src/wallet/asyncrpcoperation_sendmany.cpp | 1 - .../asyncrpcoperation_shieldcoinbase.cpp | 1 - src/wallet/rpcwallet.cpp | 8 +-- 7 files changed, 13 insertions(+), 71 deletions(-) diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index ea24f9d23..2cde04f2c 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -27,7 +27,6 @@ #include "librustzcash.h" JSDescription::JSDescription( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& anchor, @@ -42,7 +41,6 @@ JSDescription::JSDescription( std::array notes; proof = params.prove( - makeGrothProof, inputs, outputs, notes, @@ -62,7 +60,6 @@ JSDescription::JSDescription( } JSDescription JSDescription::Randomized( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& anchor, @@ -87,71 +84,18 @@ JSDescription JSDescription::Randomized( MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); return JSDescription( - makeGrothProof, params, joinSplitPubKey, anchor, inputs, outputs, vpub_old, vpub_new, computeProof, esk // payment disclosure ); } -class SproutProofVerifier : public boost::static_visitor -{ - ZCJoinSplit& params; - libzcash::ProofVerifier& verifier; - const uint256& joinSplitPubKey; - const JSDescription& jsdesc; - -public: - SproutProofVerifier( - ZCJoinSplit& params, - libzcash::ProofVerifier& verifier, - const uint256& joinSplitPubKey, - const JSDescription& jsdesc - ) : params(params), jsdesc(jsdesc), verifier(verifier), joinSplitPubKey(joinSplitPubKey) {} - - bool operator()(const libzcash::PHGRProof& proof) const - { - return params.verify( - proof, - verifier, - joinSplitPubKey, - jsdesc.randomSeed, - jsdesc.macs, - jsdesc.nullifiers, - jsdesc.commitments, - jsdesc.vpub_old, - jsdesc.vpub_new, - jsdesc.anchor - ); - } - - bool operator()(const libzcash::GrothProof& proof) const - { - uint256 h_sig = params.h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey); - - return librustzcash_sprout_verify( - proof.begin(), - jsdesc.anchor.begin(), - h_sig.begin(), - jsdesc.macs[0].begin(), - jsdesc.macs[1].begin(), - jsdesc.nullifiers[0].begin(), - jsdesc.nullifiers[1].begin(), - jsdesc.commitments[0].begin(), - jsdesc.commitments[1].begin(), - jsdesc.vpub_old, - jsdesc.vpub_new - ); - } -}; - bool JSDescription::Verify( ZCJoinSplit& params, libzcash::ProofVerifier& verifier, const uint256& joinSplitPubKey ) const { - auto pv = SproutProofVerifier(params, verifier, joinSplitPubKey, *this); - return boost::apply_visitor(pv, proof); + return false; } uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 2bc7b48c6..2ece7b255 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -48,6 +48,11 @@ extern uint32_t ASSETCHAINS_MAGIC; extern std::string ASSETCHAINS_SELFIMPORT; +#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION) + + // Overwinter transaction version static const int32_t OVERWINTER_TX_VERSION = 3; static_assert(OVERWINTER_TX_VERSION >= OVERWINTER_MIN_TX_VERSION, @@ -252,7 +257,6 @@ public: JSDescription(): vpub_old(0), vpub_new(0) { } JSDescription( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, @@ -265,7 +269,6 @@ public: ); static JSDescription Randomized( - bool makeGrothProof, ZCJoinSplit& params, const uint256& joinSplitPubKey, const uint256& rt, diff --git a/src/utiltest.cpp b/src/utiltest.cpp index 898f2c4c9..ead7fe6a0 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2016 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -43,7 +44,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, // Prepare JoinSplits uint256 rt; - JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt, + JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, inputs, outputs, 2*value, 0, false}; mtx.vjoinsplit.push_back(jsdesc); @@ -132,7 +133,7 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, // Prepare JoinSplits uint256 rt = tree.root(); - JSDescription jsdesc {false, params, mtx.joinSplitPubKey, rt, + JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, inputs, outputs, 0, value, false}; mtx.vjoinsplit.push_back(jsdesc); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index afac9c6eb..2e77195f3 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -927,7 +928,6 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( uint256 esk; // payment disclosure - secret JSDescription jsdesc = JSDescription::Randomized( - mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), *pzcashParams, joinSplitPubKey_, anchor, diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 82a7c9212..db7f7bd66 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -1258,7 +1258,6 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( uint256 esk; // payment disclosure - secret JSDescription jsdesc = JSDescription::Randomized( - mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), *pzcashParams, joinSplitPubKey_, anchor, diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 6db4eb6c0..55feb2cbf 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -455,7 +455,6 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf uint256 esk; // payment disclosure - secret JSDescription jsdesc = JSDescription::Randomized( - mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), *pzcashParams, joinSplitPubKey_, anchor, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 866e01d58..88cfbe504 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3245,8 +3245,7 @@ UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& uint256 joinSplitPubKey; uint256 anchor = SproutMerkleTree().root(); - JSDescription samplejoinsplit(true, - *pzcashParams, + JSDescription samplejoinsplit(*pzcashParams, joinSplitPubKey, anchor, {JSInput(), JSInput()}, @@ -3306,8 +3305,6 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk) for (int i = 0; i < samplecount; i++) { if (benchmarktype == "sleep") { sample_times.push_back(benchmark_sleep()); - } else if (benchmarktype == "parameterloading") { - sample_times.push_back(benchmark_parameter_loading()); } else if (benchmarktype == "createjoinsplit") { if (params.size() < 3) { sample_times.push_back(benchmark_create_joinsplit()); @@ -3605,8 +3602,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& myp mtx.nVersion = 2; mtx.joinSplitPubKey = joinSplitPubKey; - JSDescription jsdesc(false, - *pzcashParams, + JSDescription jsdesc(*pzcashParams, joinSplitPubKey, anchor, {vjsin[0], vjsin[1]}, From f3affab178db5348193047e21963c2e856abeee4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 24 Jan 2020 18:33:06 -0500 Subject: [PATCH 010/220] Revert "We do not use any of these CCs, and we want to remove gmp as dependency, so convert them to use mini-gmp.h for now" This reverts commit aeb30dd8fa37fe823fce2e3b188ec05017ba3874. --- src/cc/CCPayments.h | 2 +- src/cc/CCrewards.h | 2 +- src/cc/pegs.cpp | 2 +- src/cc/prices.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index 30c61bb0c..ac5f22c47 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -18,7 +18,7 @@ #define CC_PAYMENTS_H #include "CCinclude.h" -#include "mini-gmp.h" +#include #include #define PAYMENTS_TXFEE 10000 diff --git a/src/cc/CCrewards.h b/src/cc/CCrewards.h index f9b8672a0..d9f9edf6e 100644 --- a/src/cc/CCrewards.h +++ b/src/cc/CCrewards.h @@ -18,7 +18,7 @@ #define CC_REWARDS_H #include "CCinclude.h" -#include "mini-gmp.h" +#include #define EVAL_REWARDS 0xe5 #define REWARDSCC_MAXAPR (COIN * 25) diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp index 88ef1eb00..6ef33a884 100644 --- a/src/cc/pegs.cpp +++ b/src/cc/pegs.cpp @@ -16,7 +16,7 @@ #include "CCPegs.h" #include "../importcoin.h" #include "key_io.h" -#include "mini-gmp.h" +#include /* diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 4b5aebd65..0fcc2e512 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -73,7 +73,7 @@ GetKomodoEarlytxidScriptPub is on line #2080 of komodo_bitcoind.h #include "CCPrices.h" #include -#include "mini-gmp.h" +#include #define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos) From 4c0aebd6750559d23e8b1aa0c5a128f3c55fbc0c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 25 Jan 2020 08:18:40 -0500 Subject: [PATCH 011/220] Add libgmp back --- depends/packages/libgmp.mk | 44 ++++++++++++++++++++++++++++++++++++ depends/packages/packages.mk | 4 ++-- 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 depends/packages/libgmp.mk diff --git a/depends/packages/libgmp.mk b/depends/packages/libgmp.mk new file mode 100644 index 000000000..acd5d4c0e --- /dev/null +++ b/depends/packages/libgmp.mk @@ -0,0 +1,44 @@ +package=libgmp + +ifeq ($(host_os),mingw32) +$(package)_download_path=https://github.com/joshuayabut/$(package)/archive +$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz +$(package)_download_file=$($(package)_git_commit).tar.gz +$(package)_sha256_hash=193836c1acc9dc00fe2521205d7bbe1ba13263f6cbef6f02584bf6f8b34b108f +$(package)_git_commit=053c03b1cab347671d936f43ef66b48ab5e380ee +$(package)_dependencies= +$(package)_config_opts=--enable-cxx --disable-shared +else ifeq ($(build_os),darwin) +$(package)_download_path=https://github.com/ca333/$(package)/archive +$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz +$(package)_download_file=$($(package)_git_commit).tar.gz +$(package)_sha256_hash=59b2c2b5d58fdf5943bfde1fa709e9eb53e7e072c9699d28dc1c2cbb3c8cc32c +$(package)_git_commit=aece03c7b6967f91f3efdac8c673f55adff53ab1 +$(package)_dependencies= +$(package)_config_opts=--enable-cxx --disable-shared +else +$(package)_version=6.1.1 +$(package)_download_path=https://github.com/MyHush/libgmp/releases/download/v6.1.1 +$(package)_file_name=gmp-$($(package)_version).tar.bz2 +$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6 +$(package)_dependencies= +$(package)_config_opts=--enable-cxx --disable-shared +endif + +define $(package)_config_cmds + $($(package)_autoconf) --host=$(host) --build=$(build) +endef + +ifeq ($(build_os),darwin) +define $(package)_build_cmds + $(MAKE) +endef +else +define $(package)_build_cmds + $(MAKE) CPPFLAGS='-fPIC' +endef +endif + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install ; echo '=== staging find for $(package):' ; find $($(package)_staging_dir) +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 5aee77182..8abb7c708 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,10 +1,10 @@ rust_packages := rust librustzcash ifeq ($(build_os),darwin) - zcash_packages := libsnark libsodium utfcpp + zcash_packages := libgmp libsodium utfcpp else proton_packages := proton - zcash_packages := libsodium utfcpp + zcash_packages := libgmp libsodium utfcpp endif rust_crates := \ From 499720c42b439a559afb0b648748358ce91d22a8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 25 Jan 2020 08:28:38 -0500 Subject: [PATCH 012/220] Do not anger the libgmp Elder Gods --- configure.ac | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9b5c0335b..0f83b1e8f 100644 --- a/configure.ac +++ b/configure.ac @@ -700,7 +700,7 @@ if test x$use_pkgconfig = xyes; then ) else # BUG: Fix this: - echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++' + echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, gmp' AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -716,6 +716,22 @@ else fi fi +# These packages don't provide pkgconfig config files across all +# platforms, so we use older autoconf detection mechanisms: +if test x$TARGET_OS = xdarwin; then +AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) +AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) + +AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) +AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) +fi + +#AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) +#AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) + +#AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) +#AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) + if test "x$use_zmq" = "xyes"; then AC_CHECK_HEADER([zmq.h], [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], @@ -754,7 +770,7 @@ AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) -LIBZCASH_LIBS="$BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" +LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" AC_MSG_CHECKING([whether to build komodod]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) From 6c48397cf37b4fae0a0809737406d315eb834b34 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 15 Feb 2020 14:14:39 +0100 Subject: [PATCH 013/220] Hush witness rework, many thanks to @CryptoForge for this awesome code https://github.com/Cryptoforge-alt/pirate/tree/pirate_witness_rework --- src/Makefile.am | 2 + src/init.cpp | 46 +- ...asyncrpcoperation_saplingconsolidation.cpp | 221 ++++ .../asyncrpcoperation_saplingconsolidation.h | 37 + src/wallet/db.cpp | 51 +- src/wallet/db.h | 1 + src/wallet/gtest/test_wallet.cpp | 44 +- src/wallet/wallet.cpp | 1046 +++++++++++++---- src/wallet/wallet.h | 59 +- src/wallet/walletdb.cpp | 6 + src/wallet/walletdb.h | 1 + 11 files changed, 1233 insertions(+), 281 deletions(-) create mode 100644 src/wallet/asyncrpcoperation_saplingconsolidation.cpp create mode 100644 src/wallet/asyncrpcoperation_saplingconsolidation.h diff --git a/src/Makefile.am b/src/Makefile.am index 2a304c5a5..d2fb7b174 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -248,6 +248,7 @@ BITCOIN_CORE_H = \ validationinterface.h \ version.h \ wallet/asyncrpcoperation_mergetoaddress.h \ + wallet/asyncrpcoperation_saplingconsolidation.h \ wallet/asyncrpcoperation_sendmany.h \ wallet/asyncrpcoperation_shieldcoinbase.h \ wallet/crypter.h \ @@ -368,6 +369,7 @@ libbitcoin_wallet_a_SOURCES = \ zcbenchmarks.cpp \ zcbenchmarks.h \ wallet/asyncrpcoperation_mergetoaddress.cpp \ + wallet/asyncrpcoperation_saplingconsolidation.cpp \ wallet/asyncrpcoperation_sendmany.cpp \ wallet/asyncrpcoperation_shieldcoinbase.cpp \ wallet/crypter.cpp \ diff --git a/src/init.cpp b/src/init.cpp index 36ed5e0cb..6428bf8dc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -57,6 +57,7 @@ #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" +#include "wallet/asyncrpcoperation_saplingconsolidation.h" #endif #include @@ -449,6 +450,13 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); + strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation")); + strUsage += HelpMessageOpt("-consolidatesaplingaddress=", _("Specify Sapling Address to Consolidate. (default: all)")); + strUsage += HelpMessageOpt("-consolidationtxfee", strprintf(_("Fee amount in Puposhis used send consolidation transactions. (default %i)"), DEFAULT_CONSOLIDATION_FEE)); + strUsage += HelpMessageOpt("-deletetx", _("Enable Old Transaction Deletion")); + strUsage += HelpMessageOpt("-deleteinterval", strprintf(_("Delete transaction every blocks during inital block download (default: %i)"), DEFAULT_TX_DELETE_INTERVAL)); + strUsage += HelpMessageOpt("-keeptxnum", strprintf(_("Keep the last transactions (default: %i)"), DEFAULT_TX_RETENTION_LASTTX)); + strUsage += HelpMessageOpt("-keeptxfornblocks", strprintf(_("Keep transactions for at least blocks (default: %i)"), DEFAULT_TX_RETENTION_BLOCKS)); if (showDebug) strUsage += HelpMessageOpt("-mintxfee=", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); @@ -500,7 +508,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)"); } - string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, " + string debugCategories = "addrman, alert, bench, coindb, db, deletetx, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, " "rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied or if = 1, output all debugging information.") + " " + _(" can be:") + " " + debugCategories + "."); @@ -1953,6 +1961,42 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pwalletMain->GenerateNewSeed(); } + //Set Sapling Consolidation + pwalletMain->fSaplingConsolidationEnabled = GetBoolArg("-consolidation", false); + fConsolidationTxFee = GetArg("-consolidationtxfee", DEFAULT_CONSOLIDATION_FEE); + fConsolidationMapUsed = !mapMultiArgs["-consolidatesaplingaddress"].empty(); + + //Validate Sapling Addresses + vector& vaddresses = mapMultiArgs["-consolidatesaplingaddress"]; + for (int i = 0; i < vaddresses.size(); i++) { + LogPrintf("Consolidating Sapling Address: %s\n", vaddresses[i]); + auto zAddress = DecodePaymentAddress(vaddresses[i]); + if (!IsValidPaymentAddress(zAddress)) { + return InitError("Invalid consolidation address"); + } + } + + //Set Transaction Deletion Options + fTxDeleteEnabled = GetBoolArg("-deletetx", false); + fTxConflictDeleteEnabled = GetBoolArg("-deleteconflicttx", true); + + fDeleteInterval = GetArg("-deleteinterval", DEFAULT_TX_DELETE_INTERVAL); + if (fDeleteInterval < 1) + return InitError("deleteinterval must be greater than 0"); + + fKeepLastNTransactions = GetArg("-keeptxnum", DEFAULT_TX_RETENTION_LASTTX); + if (fKeepLastNTransactions < 1) + return InitError("keeptxnum must be greater than 0"); + + fDeleteTransactionsAfterNBlocks = GetArg("-keeptxfornblocks", DEFAULT_TX_RETENTION_BLOCKS); + if (fDeleteTransactionsAfterNBlocks < 1) + return InitError("keeptxfornblocks must be greater than 0"); + + if (fDeleteTransactionsAfterNBlocks < MAX_REORG_LENGTH + 1 ) { + LogPrintf("keeptxfornblock is less the MAX_REORG_LENGTH, Setting to %i\n", MAX_REORG_LENGTH + 1); + fDeleteTransactionsAfterNBlocks = MAX_REORG_LENGTH + 1; + } + if (fFirstRun) { // Create new keyUser and set as default key diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp new file mode 100644 index 000000000..9152f0d8c --- /dev/null +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -0,0 +1,221 @@ +#include "assert.h" +#include "boost/variant/static_visitor.hpp" +#include "asyncrpcoperation_saplingconsolidation.h" +#include "init.h" +#include "key_io.h" +#include "rpc/protocol.h" +#include "random.h" +#include "sync.h" +#include "tinyformat.h" +#include "transaction_builder.h" +#include "util.h" +#include "utilmoneystr.h" +#include "wallet.h" + +CAmount fConsolidationTxFee = DEFAULT_CONSOLIDATION_FEE; +bool fConsolidationMapUsed = false; +const int CONSOLIDATION_EXPIRY_DELTA = 15; + + +AsyncRPCOperation_saplingconsolidation::AsyncRPCOperation_saplingconsolidation(int targetHeight) : targetHeight_(targetHeight) {} + +AsyncRPCOperation_saplingconsolidation::~AsyncRPCOperation_saplingconsolidation() {} + +void AsyncRPCOperation_saplingconsolidation::main() { + if (isCancelled()) + return; + + set_state(OperationStatus::EXECUTING); + start_execution_clock(); + + bool success = false; + + try { + success = main_impl(); + } catch (const UniValue& objError) { + int code = find_value(objError, "code").get_int(); + std::string message = find_value(objError, "message").get_str(); + set_error_code(code); + set_error_message(message); + } catch (const runtime_error& e) { + set_error_code(-1); + set_error_message("runtime error: " + string(e.what())); + } catch (const logic_error& e) { + set_error_code(-1); + set_error_message("logic error: " + string(e.what())); + } catch (const exception& e) { + set_error_code(-1); + set_error_message("general exception: " + string(e.what())); + } catch (...) { + set_error_code(-2); + set_error_message("unknown error"); + } + + stop_execution_clock(); + + if (success) { + set_state(OperationStatus::SUCCESS); + } else { + set_state(OperationStatus::FAILED); + } + + std::string s = strprintf("%s: Sapling Consolidation transaction created. (status=%s", getId(), getStateAsString()); + if (success) { + s += strprintf(", success)\n"); + } else { + s += strprintf(", error=%s)\n", getErrorMessage()); + } + + LogPrintf("%s", s); +} + +bool AsyncRPCOperation_saplingconsolidation::main_impl() { + LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingconsolidation.\n", getId()); + auto consensusParams = Params().GetConsensus(); + auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams); + if (nextActivationHeight && targetHeight_ + CONSOLIDATION_EXPIRY_DELTA >= nextActivationHeight.get()) { + LogPrint("zrpcunsafe", "%s: Consolidation txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); + setConsolidationResult(0, 0, std::vector()); + return true; + } + + std::vector sproutEntries; + std::vector saplingEntries; + std::set addresses; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + // We set minDepth to 11 to avoid unconfirmed notes and in anticipation of specifying + // an anchor at height N-10 for each Sprout JoinSplit description + // Consider, should notes be sorted? + pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, "", 11); + if (fConsolidationMapUsed) { + const vector& v = mapMultiArgs["-consolidatesaplingaddress"]; + for(int i = 0; i < v.size(); i++) { + auto zAddress = DecodePaymentAddress(v[i]); + if (boost::get(&zAddress) != nullptr) { + libzcash::SaplingPaymentAddress saplingAddress = boost::get(zAddress); + addresses.insert(saplingAddress ); + } + } + } else { + pwalletMain->GetSaplingPaymentAddresses(addresses); + } + } + + int numTxCreated = 0; + std::vector consolidationTxIds; + CAmount amountConsolidated = 0; + CCoinsViewCache coinsView(pcoinsTip); + + for (auto addr : addresses) { + libzcash::SaplingExtendedSpendingKey extsk; + if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + + std::vector fromNotes; + CAmount amountToSend = 0; + int maxQuantity = rand() % 35 + 10; + for (const SaplingNoteEntry& saplingEntry : saplingEntries) { + + libzcash::SaplingIncomingViewingKey ivk; + pwalletMain->GetSaplingIncomingViewingKey(boost::get(saplingEntry.address), ivk); + + //Select Notes from that same address we will be sending to. + if (ivk == extsk.expsk.full_viewing_key().in_viewing_key()) { + amountToSend += CAmount(saplingEntry.note.value()); + fromNotes.push_back(saplingEntry); + } + + //Only use a randomly determined number of notes between 10 and 45 + if (fromNotes.size() >= maxQuantity) + break; + + } + + //random minimum 2 - 12 required + int minQuantity = rand() % 10 + 2; + if (fromNotes.size() < minQuantity) + continue; + + amountConsolidated += amountToSend; + auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain); + //builder.SetExpiryHeight(targetHeight_ + CONSOLIDATION_EXPIRY_DELTA); + LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - fConsolidationTxFee)); + + // Select Sapling notes + std::vector ops; + std::vector notes; + for (auto fromNote : fromNotes) { + ops.push_back(fromNote.op); + notes.push_back(fromNote.note); + } + + // Fetch Sapling anchor and witnesses + uint256 anchor; + std::vector> witnesses; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor); + } + + // Add Sapling spends + for (size_t i = 0; i < notes.size(); i++) { + if (!witnesses[i]) { + LogPrint("zrpcunsafe", "%s: Missing Witnesses. Stopping.\n", getId()); + break; + } + builder.AddSaplingSpend(extsk.expsk, notes[i], anchor, witnesses[i].get()); + } + + builder.SetFee(fConsolidationTxFee); + builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); + //CTransaction tx = builder.Build(); + + auto maybe_tx = builder.Build(); + if (!maybe_tx) { + LogPrint("zrpcunsafe", "%s: Failed to build transaction.", getId()); + break; + } + CTransaction tx = maybe_tx.get(); + + if (isCancelled()) { + LogPrint("zrpcunsafe", "%s: Canceled. Stopping.\n", getId()); + break; + } + + pwalletMain->CommitConsolidationTx(tx); + LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); + amountConsolidated += amountToSend - fConsolidationTxFee; + consolidationTxIds.push_back(tx.GetHash().ToString()); + + } + } + + LogPrint("zrpcunsafe", "%s: Created %d transactions with total Sapling output amount=%s\n", getId(), numTxCreated, FormatMoney(amountConsolidated)); + setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); + return true; + +} + +void AsyncRPCOperation_saplingconsolidation::setConsolidationResult(int numTxCreated, const CAmount& amountConsolidated, const std::vector& consolidationTxIds) { + UniValue res(UniValue::VOBJ); + res.push_back(Pair("num_tx_created", numTxCreated)); + res.push_back(Pair("amount_consolidated", FormatMoney(amountConsolidated))); + UniValue txIds(UniValue::VARR); + for (const std::string& txId : consolidationTxIds) { + txIds.push_back(txId); + } + res.push_back(Pair("consolidation_txids", txIds)); + set_result(res); +} + +void AsyncRPCOperation_saplingconsolidation::cancel() { + set_state(OperationStatus::CANCELLED); +} + +UniValue AsyncRPCOperation_saplingconsolidation::getStatus() const { + UniValue v = AsyncRPCOperation::getStatus(); + UniValue obj = v.get_obj(); + obj.push_back(Pair("method", "saplingconsolidation")); + obj.push_back(Pair("target_height", targetHeight_)); + return obj; +} diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.h b/src/wallet/asyncrpcoperation_saplingconsolidation.h new file mode 100644 index 000000000..8e38204c7 --- /dev/null +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.h @@ -0,0 +1,37 @@ +#include "amount.h" +#include "asyncrpcoperation.h" +#include "univalue.h" +#include "zcash/Address.hpp" +#include "zcash/zip32.h" + +//Default fee used for consolidation transactions +static const CAmount DEFAULT_CONSOLIDATION_FEE = 0; +extern CAmount fConsolidationTxFee; +extern bool fConsolidationMapUsed; + +class AsyncRPCOperation_saplingconsolidation : public AsyncRPCOperation +{ +public: + AsyncRPCOperation_saplingconsolidation(int targetHeight); + virtual ~AsyncRPCOperation_saplingconsolidation(); + + // We don't want to be copied or moved around + AsyncRPCOperation_saplingconsolidation(AsyncRPCOperation_saplingconsolidation const&) = delete; // Copy construct + AsyncRPCOperation_saplingconsolidation(AsyncRPCOperation_saplingconsolidation&&) = delete; // Move construct + AsyncRPCOperation_saplingconsolidation& operator=(AsyncRPCOperation_saplingconsolidation const&) = delete; // Copy assign + AsyncRPCOperation_saplingconsolidation& operator=(AsyncRPCOperation_saplingconsolidation&&) = delete; // Move assign + + virtual void main(); + + virtual void cancel(); + + virtual UniValue getStatus() const; + +private: + int targetHeight_; + + bool main_impl(); + + void setConsolidationResult(int numTxCreated, const CAmount& amountConsolidated, const std::vector& consolidationTxIds); + +}; \ No newline at end of file diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index dd0880b75..1814e9209 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -105,7 +105,7 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn) nEnvFlags |= DB_PRIVATE; dbenv->set_lg_dir(pathLogDir.string().c_str()); - dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet + dbenv->set_cachesize(1, 0x100000, 1); // 1 MiB should be enough for just the wallet, Increased by 1 GB dbenv->set_lg_bsize(0x10000); dbenv->set_lg_max(1048576); dbenv->set_lk_max_locks(40000); @@ -181,6 +181,55 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu return (fRecovered ? RECOVER_OK : RECOVER_FAIL); } +bool CDBEnv::Compact(const std::string& strFile) +{ + LOCK(cs_db); + + DB_COMPACT dbcompact; + dbcompact.compact_fillpercent = 80; + dbcompact.compact_pages = DB_MAX_PAGES; + dbcompact.compact_timeout = 0; + + DB_COMPACT *pdbcompact; + pdbcompact = &dbcompact; + + int result = 1; + if (mapDb[strFile] != NULL) { + Db* pdb = mapDb[strFile]; + result = pdb->compact(NULL, NULL, NULL, pdbcompact, DB_FREE_SPACE, NULL); + delete pdb; + mapDb[strFile] = NULL; + + switch (result) + { + case DB_LOCK_DEADLOCK: + LogPrint("db","Deadlock %i\n", result); + break; + case DB_LOCK_NOTGRANTED: + LogPrint("db","Lock Not Granted %i\n", result); + break; + case DB_REP_HANDLE_DEAD: + LogPrint("db","Handle Dead %i\n", result); + break; + case DB_REP_LOCKOUT: + LogPrint("db","Rep Lockout %i\n", result); + break; + case EACCES: + LogPrint("db","Eacces %i\n", result); + break; + case EINVAL: + LogPrint("db","Error Invalid %i\n", result); + break; + case 0: + LogPrint("db","Wallet Compact Sucessful\n"); + break; + default: + LogPrint("db","Compact result int %i\n", result); + } + } + return (result == 0); +} + bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector& vResult) { LOCK(cs_db); diff --git a/src/wallet/db.h b/src/wallet/db.h index 8ad246de4..31ba88f11 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -88,6 +88,7 @@ public: * NOTE: reads the entire database into memory, so cannot be used * for huge databases. */ + bool Compact(const std::string& strFile); typedef std::pair, std::vector > KeyValPair; bool Salvage(const std::string& strFile, bool fAggressive, std::vector& vResult); diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 676239d0b..dcc7fdfdd 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -53,12 +53,10 @@ public: return CCryptoKeyStore::Unlock(vMasterKeyIn); } - void IncrementNoteWitnesses(const CBlockIndex* pindex, - const CBlock* pblock, - SproutMerkleTree& sproutTree, - SaplingMerkleTree& saplingTree) { - CWallet::IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree); + void BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) { + CWallet::BuildWitnessCache(pindex, witnessOnly); } + void DecrementNoteWitnesses(const CBlockIndex* pindex) { CWallet::DecrementNoteWitnesses(pindex); } @@ -116,7 +114,7 @@ std::pair CreateValidBlock(TestWallet& wallet, wallet.AddToWallet(wtx, true, NULL); block.vtx.push_back(wtx); - wallet.IncrementNoteWitnesses(&index, &block, sproutTree, saplingTree); + wallet.BuildWitnessCache(&index, false); return std::make_pair(jsoutpt, saplingNotes[0]); } @@ -724,8 +722,8 @@ TEST(WalletTests, GetConflictedSaplingNotes) { wallet.AddToWallet(wtx, true, NULL); // Simulate receiving new block and ChainTip signal - wallet.IncrementNoteWitnesses(&fakeIndex, &block, sproutTree, saplingTree); - wallet.UpdateSaplingNullifierNoteMapForBlock(&block); + wallet.BuildWitnessCache(&fakeIndex, false); + wallet.UpdateNullifierNoteMapForBlock(&block); // Retrieve the updated wtx from wallet uint256 hash = wtx.GetHash(); @@ -1008,8 +1006,8 @@ TEST(WalletTests, NavigateFromSaplingNullifierToNote) { } // Simulate receiving new block and ChainTip signal - wallet.IncrementNoteWitnesses(&fakeIndex, &block, sproutTree, saplingTree); - wallet.UpdateSaplingNullifierNoteMapForBlock(&block); + wallet.BuildWitnessCache(&fakeIndex, false); + wallet.UpdateNullifierNoteMapForBlock(&block); // Retrieve the updated wtx from wallet uint256 hash = wtx.GetHash(); @@ -1126,8 +1124,8 @@ TEST(WalletTests, SpentSaplingNoteIsFromMe) { // Simulate receiving new block and ChainTip signal. // This triggers calculation of nullifiers for notes belonging to this wallet // in the output descriptions of wtx. - wallet.IncrementNoteWitnesses(&fakeIndex, &block, sproutTree, saplingTree); - wallet.UpdateSaplingNullifierNoteMapForBlock(&block); + wallet.BuildWitnessCache(&fakeIndex, false); + wallet.UpdateNullifierNoteMapForBlock(&block); // Retrieve the updated wtx from wallet wtx = wallet.mapWallet[wtx.GetHash()]; @@ -1263,7 +1261,7 @@ TEST(WalletTests, CachedWitnessesEmptyChain) { CBlockIndex index(block); SproutMerkleTree sproutTree; SaplingMerkleTree saplingTree; - wallet.IncrementNoteWitnesses(&index, &block, sproutTree, saplingTree); + wallet.BuildWitnessCache(&index, false); ::GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); @@ -1354,7 +1352,7 @@ TEST(WalletTests, CachedWitnessesChainTip) { EXPECT_NE(anchors1.second, anchors3.second); // Re-incrementing with the same block should give the same result - wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree); + wallet.BuildWitnessCache(&index2, false); auto anchors4 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); EXPECT_NE(anchors4.first, anchors4.second); @@ -1364,7 +1362,7 @@ TEST(WalletTests, CachedWitnessesChainTip) { EXPECT_EQ(anchors2.second, anchors4.second); // Incrementing with the same block again should not change the cache - wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree); + wallet.BuildWitnessCache(&index2, false); std::vector> sproutWitnesses5; std::vector> saplingWitnesses5; @@ -1447,7 +1445,7 @@ TEST(WalletTests, CachedWitnessesDecrementFirst) { EXPECT_NE(anchors2.second, anchors4.second); // Re-incrementing with the same block should give the same result - wallet.IncrementNoteWitnesses(&index2, &block2, sproutTree, saplingTree); + wallet.BuildWitnessCache(&index2, false); auto anchors5 = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); @@ -1504,7 +1502,7 @@ TEST(WalletTests, CachedWitnessesCleanIndex) { for (size_t i = 0; i < numBlocks; i++) { SproutMerkleTree sproutRiPrevTree {sproutRiTree}; SaplingMerkleTree saplingRiPrevTree {saplingRiTree}; - wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), sproutRiTree, saplingRiTree); + wallet.BuildWitnessCache(&indices[i], false); auto anchors = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); for (size_t j = 0; j < numBlocks; j++) { @@ -1531,7 +1529,7 @@ TEST(WalletTests, CachedWitnessesCleanIndex) { } { - wallet.IncrementNoteWitnesses(&(indices[i]), &(blocks[i]), sproutRiPrevTree, saplingRiPrevTree); + wallet.BuildWitnessCache(&indices[i], false); auto anchors = GetWitnessesAndAnchors(wallet, sproutNotes, saplingNotes, sproutWitnesses, saplingWitnesses); for (size_t j = 0; j < numBlocks; j++) { EXPECT_TRUE((bool) sproutWitnesses[j]); @@ -1886,8 +1884,8 @@ TEST(WalletTests, UpdatedSaplingNoteData) { wallet.AddToWallet(wtx, true, NULL); // Simulate receiving new block and ChainTip signal - wallet.IncrementNoteWitnesses(&fakeIndex, &block, sproutTree, saplingTree); - wallet.UpdateSaplingNullifierNoteMapForBlock(&block); + wallet.BuildWitnessCache(&fakeIndex, false); + wallet.UpdateNullifierNoteMapForBlock(&block); // Retrieve the updated wtx from wallet uint256 hash = wtx.GetHash(); @@ -1915,7 +1913,7 @@ TEST(WalletTests, UpdatedSaplingNoteData) { EXPECT_EQ(2, wtx2.mapSaplingNoteData.size()); EXPECT_EQ(1, wtx2.mapSaplingNoteData[sop0].witnesses.size()); // wtx2 has fake witness for payment output - EXPECT_EQ(0, wtx2.mapSaplingNoteData[sop1].witnesses.size()); // wtx2 never had incrementnotewitness called + EXPECT_EQ(0, wtx2.mapSaplingNoteData[sop1].witnesses.size()); // wtx2 never had BuildWitnessCache called // After updating, they should be the same EXPECT_TRUE(wallet.UpdatedNoteData(wtx2, wtx)); @@ -2040,8 +2038,8 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { wallet.AddToWallet(wtx, true, NULL); // Simulate receiving new block and ChainTip signal - wallet.IncrementNoteWitnesses(&fakeIndex, &block, sproutTree, saplingTree); - wallet.UpdateSaplingNullifierNoteMapForBlock(&block); + wallet.BuildWitnessCache(&fakeIndex, false); + wallet.UpdateNullifierNoteMapForBlock(&block); // Retrieve the updated wtx from wallet uint256 hash = wtx.GetHash(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b52ccdb9f..6e73f2a1a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -20,6 +20,7 @@ ******************************************************************************/ #include "wallet/wallet.h" +#include "asyncrpcqueue.h" #include "checkpoints.h" #include "coincontrol.h" @@ -38,6 +39,7 @@ #include "zcash/Note.hpp" #include "crypter.h" #include "coins.h" +#include "wallet/asyncrpcoperation_saplingconsolidation.h" #include "zcash/zip32.h" #include "cc/CCinclude.h" @@ -65,6 +67,11 @@ CBlockIndex *komodo_chainactive(int32_t height); extern std::string DONATION_PUBKEY; int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int tx_height( const uint256 &hash ); +bool fTxDeleteEnabled = false; +bool fTxConflictDeleteEnabled = false; +int fDeleteInterval = DEFAULT_TX_DELETE_INTERVAL; +unsigned int fDeleteTransactionsAfterNBlocks = DEFAULT_TX_RETENTION_BLOCKS; +unsigned int fKeepLastNTransactions = DEFAULT_TX_RETENTION_LASTTX; /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) @@ -584,11 +591,56 @@ void CWallet::ChainTip(const CBlockIndex *pindex, bool added) { if (added) { - IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree); + // Prevent witness cache building && consolidation transactions + // from being created when node is syncing after launch, + // and also when node wakes up from suspension/hibernation and incoming blocks are old. + bool initialDownloadCheck = IsInitialBlockDownload(); + if (!initialDownloadCheck && + pblock->GetBlockTime() > GetAdjustedTime() - 8640) //Last 144 blocks 2.4 * 60 * 60 + { + BuildWitnessCache(pindex, false); + RunSaplingConsolidation(pindex->GetHeight()); + DeleteWalletTransactions(pindex); + } else { + //Build intial witnesses on every block + BuildWitnessCache(pindex, true); + if (initialDownloadCheck && pindex->GetHeight() % fDeleteInterval == 0) { + DeleteWalletTransactions(pindex); + } + } } else { DecrementNoteWitnesses(pindex); + UpdateNullifierNoteMapForBlock(pblock); } - UpdateSaplingNullifierNoteMapForBlock(pblock); +} + +void CWallet::RunSaplingConsolidation(int blockHeight) { + if (!NetworkUpgradeActive(blockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + return; + } + LOCK(cs_wallet); + if (!fSaplingConsolidationEnabled) { + return; + } + + int consolidateInterval = rand() % 5 + 5; + if (blockHeight % consolidateInterval == 0) { + std::shared_ptr q = getAsyncRPCQueue(); + std::shared_ptr lastOperation = q->getOperationForId(saplingConsolidationOperationId); + if (lastOperation != nullptr) { + lastOperation->cancel(); + } + pendingSaplingConsolidationTxs.clear(); + std::shared_ptr operation(new AsyncRPCOperation_saplingconsolidation(blockHeight + 5)); + saplingConsolidationOperationId = operation->getId(); + q->addOperation(operation); + } +} + +void CWallet::CommitConsolidationTx(const CTransaction& tx) { + CWalletTx wtx(this, tx); + CReserveKey reservekey(pwalletMain); + CommitTransaction(wtx, reservekey); } void CWallet::SetBestChain(const CBlockLocator& loc) @@ -872,6 +924,22 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const return false; } +unsigned int CWallet::GetSpendDepth(const uint256& hash, unsigned int n) const +{ + const COutPoint outpoint(hash, n); + pair range; + range = mapTxSpends.equal_range(outpoint); + + for (TxSpends::const_iterator it = range.first; it != range.second; ++it) + { + const uint256& wtxid = it->second; + std::map::const_iterator mit = mapWallet.find(wtxid); + if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) + return mit->second.GetDepthInMainChain(); // Spent + } + return 0; +} + /** * Note is spent if any non-conflicted transaction * spends it: @@ -890,6 +958,20 @@ bool CWallet::IsSproutSpent(const uint256& nullifier) const { return false; } +unsigned int CWallet::GetSproutSpendDepth(const uint256& nullifier) const { + pair range; + range = mapTxSproutNullifiers.equal_range(nullifier); + + for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) { + const uint256& wtxid = it->second; + std::map::const_iterator mit = mapWallet.find(wtxid); + if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) { + return mit->second.GetDepthInMainChain(); // Spent + } + } + return 0; +} + bool CWallet::IsSaplingSpent(const uint256& nullifier) const { pair range; range = mapTxSaplingNullifiers.equal_range(nullifier); @@ -904,6 +986,20 @@ bool CWallet::IsSaplingSpent(const uint256& nullifier) const { return false; } +unsigned int CWallet::GetSaplingSpendDepth(const uint256& nullifier) const { + pair range; + range = mapTxSaplingNullifiers.equal_range(nullifier); + + for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) { + const uint256& wtxid = it->second; + std::map::const_iterator mit = mapWallet.find(wtxid); + if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) { + return mit->second.GetDepthInMainChain(); // Spent + } + } + return 0; +} + void CWallet::AddToTransparentSpends(const COutPoint& outpoint, const uint256& wtxid) { mapTxSpends.insert(make_pair(outpoint, wtxid)); @@ -992,241 +1088,369 @@ void CWallet::ClearNoteWitnessCache() item.second.witnessHeight = -1; } } - nWitnessCacheSize = 0; - //fprintf(stderr,"Clear witness cache\n"); } -template -void CopyPreviousWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize) -{ - for (auto& item : noteDataMap) { - auto* nd = &(item.second); - // Only increment witnesses that are behind the current height - if (nd->witnessHeight < indexHeight) { - // Check the validity of the cache - // The only time a note witnessed above the current height - // would be invalid here is during a reindex when blocks - // have been decremented, and we are incrementing the blocks - // immediately after. - assert(nWitnessCacheSize >= nd->witnesses.size()); - // Witnesses being incremented should always be either -1 - // (never incremented or decremented) or one below indexHeight - assert((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight - 1)); - // Copy the witness for the previous block if we have one - if (nd->witnesses.size() > 0) { - nd->witnesses.push_front(nd->witnesses.front()); - } - if (nd->witnesses.size() > WITNESS_CACHE_SIZE) { - nd->witnesses.pop_back(); - } - } - } -} - -template -void AppendNoteCommitment(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const uint256& note_commitment) -{ - for (auto& item : noteDataMap) { - auto* nd = &(item.second); - if (nd->witnessHeight < indexHeight && nd->witnesses.size() > 0) { - // Check the validity of the cache - // See comment in CopyPreviousWitnesses about validity. - assert(nWitnessCacheSize >= nd->witnesses.size()); - nd->witnesses.front().append(note_commitment); - } - } -} - -template -void WitnessNoteIfMine(std::map& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const OutPoint& key, const Witness& witness) -{ - if (noteDataMap.count(key) && noteDataMap[key].witnessHeight < indexHeight) { - auto* nd = &(noteDataMap[key]); - if (nd->witnesses.size() > 0) { - // We think this can happen because we write out the - // witness cache state after every block increment or - // decrement, but the block index itself is written in - // batches. So if the node crashes in between these two - // operations, it is possible for IncrementNoteWitnesses - // to be called again on previously-cached blocks. This - // doesn't affect existing cached notes because of the - // NoteData::witnessHeight checks. See #1378 for details. - LogPrintf("Inconsistent witness cache state found for %s\n- Cache size: %d\n- Top (height %d): %s\n- New (height %d): %s\n", - key.ToString(), nd->witnesses.size(), - nd->witnessHeight, - nd->witnesses.front().root().GetHex(), - indexHeight, - witness.root().GetHex()); - nd->witnesses.clear(); - } - nd->witnesses.push_front(witness); - // Set height to one less than pindex so it gets incremented - nd->witnessHeight = indexHeight - 1; - // Check the validity of the cache - assert(nWitnessCacheSize >= nd->witnesses.size()); - } -} - - -template -void UpdateWitnessHeights(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize) -{ - for (auto& item : noteDataMap) { - auto* nd = &(item.second); - if (nd->witnessHeight < indexHeight) { - nd->witnessHeight = indexHeight; - // Check the validity of the cache - // See comment in CopyPreviousWitnesses about validity. - assert(nWitnessCacheSize >= nd->witnesses.size()); - } - } -} - -void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, - const CBlock* pblockIn, - SproutMerkleTree& sproutTree, - SaplingMerkleTree& saplingTree) -{ - LOCK(cs_wallet); - for (std::pair& wtxItem : mapWallet) { - ::CopyPreviousWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize); - ::CopyPreviousWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize); - } - - if (nWitnessCacheSize < WITNESS_CACHE_SIZE) { - nWitnessCacheSize += 1; - } - - const CBlock* pblock {pblockIn}; - CBlock block; - if (!pblock) { - ReadBlockFromDisk(block, pindex, false); - pblock = █ - } - - for (const CTransaction& tx : pblock->vtx) { - auto hash = tx.GetHash(); - bool txIsOurs = mapWallet.count(hash); - // Sprout - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; - for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { - const uint256& note_commitment = jsdesc.commitments[j]; - sproutTree.append(note_commitment); - - // Increment existing witnesses - for (std::pair& wtxItem : mapWallet) { - ::AppendNoteCommitment(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment); - } - - // If this is our note, witness it - if (txIsOurs) { - JSOutPoint jsoutpt {hash, i, j}; - ::WitnessNoteIfMine(mapWallet[hash].mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, jsoutpt, sproutTree.witness()); - } - } - } - // Sapling - for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) { - const uint256& note_commitment = tx.vShieldedOutput[i].cm; - saplingTree.append(note_commitment); - - // Increment existing witnesses - for (std::pair& wtxItem : mapWallet) { - ::AppendNoteCommitment(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment); - } - - // If this is our note, witness it - if (txIsOurs) { - SaplingOutPoint outPoint {hash, i}; - ::WitnessNoteIfMine(mapWallet[hash].mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, outPoint, saplingTree.witness()); - } - } - } - - // Update witness heights - for (std::pair& wtxItem : mapWallet) { - ::UpdateWitnessHeights(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize); - ::UpdateWitnessHeights(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize); - } - - // For performance reasons, we write out the witness cache in - // CWallet::SetBestChain() (which also ensures that overall consistency - // of the wallet.dat is maintained). -} - -template -bool DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize) -{ - extern int32_t KOMODO_REWIND; - - for (auto& item : noteDataMap) { - auto* nd = &(item.second); - // Only decrement witnesses that are not above the current height - if (nd->witnessHeight <= indexHeight) { - // Check the validity of the cache - // See comment below (this would be invalid if there were a - // prior decrement). - assert(nWitnessCacheSize >= nd->witnesses.size()); - // Witnesses being decremented should always be either -1 - // (never incremented or decremented) or equal to the height - // of the block being removed (indexHeight) - if (!((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight))) - { - printf("at height %d\n", indexHeight); - return false; - } - if (nd->witnesses.size() > 0) { - nd->witnesses.pop_front(); - } - // indexHeight is the height of the block being removed, so - // the new witness cache height is one below it. - nd->witnessHeight = indexHeight - 1; - } - // Check the validity of the cache - // Technically if there are notes witnessed above the current - // height, their cache will now be invalid (relative to the new - // value of nWitnessCacheSize). However, this would only occur - // during a reindex, and by the time the reindex reaches the tip - // of the chain again, the existing witness caches will be valid - // again. - // We don't set nWitnessCacheSize to zero at the start of the - // reindex because the on-disk blocks had already resulted in a - // chain that didn't trigger the assertion below. - if (nd->witnessHeight < indexHeight) { - // Subtract 1 to compare to what nWitnessCacheSize will be after - // decrementing. - assert((nWitnessCacheSize - 1) >= nd->witnesses.size()); - } - } - assert(KOMODO_REWIND != 0 || nWitnessCacheSize > 0 || WITNESS_CACHE_SIZE != _COINBASE_MATURITY+10); - return true; -} - - void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex) { LOCK(cs_wallet); + + extern int32_t KOMODO_REWIND; + for (std::pair& wtxItem : mapWallet) { - if (!::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize)) - needsRescan = true; - if (!::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize)) - needsRescan = true; + //Sprout + for (auto& item : wtxItem.second.mapSproutNoteData) { + auto* nd = &(item.second); + if (nd->nullifier && pwalletMain->GetSproutSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { + // Only decrement witnesses that are not above the current height + if (nd->witnessHeight <= pindex->GetHeight()) { + if (nd->witnesses.size() > 1) { + // indexHeight is the height of the block being removed, so + // the new witness cache height is one below it. + nd->witnesses.pop_front(); + nd->witnessHeight = pindex->GetHeight() - 1; + } + } + } + } + //Sapling + for (auto& item : wtxItem.second.mapSaplingNoteData) { + auto* nd = &(item.second); + if (nd->nullifier && pwalletMain->GetSaplingSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { + // Only decrement witnesses that are not above the current height + if (nd->witnessHeight <= pindex->GetHeight()) { + if (nd->witnesses.size() > 1) { + // indexHeight is the height of the block being removed, so + // the new witness cache height is one below it. + nd->witnesses.pop_front(); + nd->witnessHeight = pindex->GetHeight() - 1; + } + } + } + } } - if ( WITNESS_CACHE_SIZE == _COINBASE_MATURITY+10 ) - { - nWitnessCacheSize -= 1; - // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302) - assert(nWitnessCacheSize > 0); + assert(KOMODO_REWIND != 0 || WITNESS_CACHE_SIZE != _COINBASE_MATURITY+10); +} + +template +void ClearSingleNoteWitnessCache(NoteData* nd) +{ + nd->witnesses.clear(); + nd->witnessHeight = -1; + nd->witnessRootValidated = false; +} + +int CWallet::SproutWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight) +{ + if (GetSproutSpendDepth(nullifier) <= WITNESS_CACHE_SIZE) { + nMinimumHeight = min(nWitnessHeight, nMinimumHeight); } - else - { - if ( nWitnessCacheSize > 0 ) - nWitnessCacheSize--; + return nMinimumHeight; +} + +int CWallet::SaplingWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight) +{ + if (GetSaplingSpendDepth(nullifier) <= WITNESS_CACHE_SIZE) { + nMinimumHeight = min(nWitnessHeight, nMinimumHeight); } - // For performance reasons, we write out the witness cache in - // CWallet::SetBestChain() (which also ensures that overall consistency - // of the wallet.dat is maintained). + return nMinimumHeight; +} + +int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessOnly) +{ + LOCK2(cs_main, cs_wallet); + + int nWitnessTxIncrement = 0; + int nWitnessTotalTxCount = mapWallet.size(); + int nMinimumHeight = pindex->GetHeight(); + + for (std::pair& wtxItem : mapWallet) { + nWitnessTxIncrement += 1; + + if (wtxItem.second.mapSproutNoteData.empty() && wtxItem.second.mapSaplingNoteData.empty()) + continue; + + if (wtxItem.second.GetDepthInMainChain() > 0) { + auto wtxHash = wtxItem.second.GetHash(); + int wtxHeight = mapBlockIndex[wtxItem.second.hashBlock]->GetHeight(); + + for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { + + auto op = item.first; + auto* nd = &(item.second); + CBlockIndex* pblockindex; + uint256 blockRoot; + uint256 witnessRoot; + + if (!nd->nullifier) + ::ClearSingleNoteWitnessCache(nd); + + if (!nd->witnesses.empty() && nd->witnessHeight > 0) { + + //Skip all functions for validated witness while witness only = true + if (nd->witnessRootValidated && witnessOnly) + continue; + + //Skip Validation when witness root has been validated + if (nd->witnessRootValidated) { + nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + + //Skip Validation when witness height is greater that block height + if (nd->witnessHeight > pindex->GetHeight() - 1) { + nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + + //Validate the witness at the witness height + witnessRoot = nd->witnesses.front().root(); + pblockindex = chainActive[nd->witnessHeight]; + blockRoot = pblockindex->hashFinalSproutRoot; + if (witnessRoot == blockRoot) { + nd->witnessRootValidated = true; + nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + } + + //Clear witness Cache for all other scenarios + pblockindex = chainActive[wtxHeight]; + ::ClearSingleNoteWitnessCache(nd); + + LogPrintf("Setting Inital Sprout Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); + + SproutMerkleTree sproutTree; + blockRoot = pblockindex->pprev->hashFinalSproutRoot; + pcoinsTip->GetSproutAnchorAt(blockRoot, sproutTree); + + //Cycle through blocks and transactions building sprout tree until the commitment needed is reached + const CBlock* pblock; + CBlock block; + ReadBlockFromDisk(block, pblockindex, 1); + pblock = █ + + for (const CTransaction& tx : block.vtx) { + auto hash = tx.GetHash(); + + for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { + const JSDescription& jsdesc = tx.vjoinsplit[i]; + for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { + const uint256& note_commitment = jsdesc.commitments[j]; + + // Increment existing witness until the end of the block + if (!nd->witnesses.empty()) { + nd->witnesses.front().append(note_commitment); + } + + //Only needed for intial witness + if (nd->witnesses.empty()) { + sproutTree.append(note_commitment); + + // If this is our note, witness it + if (hash == wtxHash) { + JSOutPoint outPoint {hash, i, j}; + if (op == outPoint) { + nd->witnesses.push_front(sproutTree.witness()); + } + } + } + } + } + } + + nd->witnessHeight = pblockindex->GetHeight(); + UpdateSproutNullifierNoteMapWithTx(wtxItem.second); + nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + } + + for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { + + auto op = item.first; + auto* nd = &(item.second); + CBlockIndex* pblockindex; + uint256 blockRoot; + uint256 witnessRoot; + + if (!nd->nullifier) + ::ClearSingleNoteWitnessCache(nd); + + if (!nd->witnesses.empty() && nd->witnessHeight > 0) { + + //Skip all functions for validated witness while witness only = true + if (nd->witnessRootValidated && witnessOnly) + continue; + + //Skip Validation when witness root has been validated + if (nd->witnessRootValidated) { + nMinimumHeight = SaplingWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + + //Skip Validation when witness height is greater that block height + if (nd->witnessHeight > pindex->GetHeight() - 1) { + nMinimumHeight = SaplingWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + + //Validate the witness at the witness height + witnessRoot = nd->witnesses.front().root(); + pblockindex = chainActive[nd->witnessHeight]; + blockRoot = pblockindex->hashFinalSaplingRoot; + if (witnessRoot == blockRoot) { + nd->witnessRootValidated = true; + nMinimumHeight = SaplingWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + continue; + } + } + + //Clear witness Cache for all other scenarios + pblockindex = chainActive[wtxHeight]; + ::ClearSingleNoteWitnessCache(nd); + + LogPrintf("Setting Inital Sapling Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); + + SaplingMerkleTree saplingTree; + blockRoot = pblockindex->pprev->hashFinalSaplingRoot; + pcoinsTip->GetSaplingAnchorAt(blockRoot, saplingTree); + + //Cycle through blocks and transactions building sapling tree until the commitment needed is reached + const CBlock* pblock; + CBlock block; + ReadBlockFromDisk(block, pblockindex, 1); + pblock = █ + + for (const CTransaction& tx : block.vtx) { + auto hash = tx.GetHash(); + + // Sapling + for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) { + const uint256& note_commitment = tx.vShieldedOutput[i].cm; + + // Increment existing witness until the end of the block + if (!nd->witnesses.empty()) { + nd->witnesses.front().append(note_commitment); + } + + //Only needed for intial witness + if (nd->witnesses.empty()) { + saplingTree.append(note_commitment); + + // If this is our note, witness it + if (hash == wtxHash) { + SaplingOutPoint outPoint {hash, i}; + if (op == outPoint) { + nd->witnesses.push_front(saplingTree.witness()); + } + } + } + } + } + nd->witnessHeight = pblockindex->GetHeight(); + UpdateSaplingNullifierNoteMapWithTx(wtxItem.second); + nMinimumHeight = SaplingWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); + } + } + } + + return nMinimumHeight; +} + +void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) +{ + + LOCK2(cs_main, cs_wallet); + + int startHeight = VerifyAndSetInitialWitness(pindex, witnessOnly) + 1; + + if (startHeight > pindex->GetHeight() || witnessOnly) { + return; + } + + uint256 sproutRoot; + uint256 saplingRoot; + CBlockIndex* pblockindex = chainActive[startHeight]; + int height = chainActive.Height(); + + while (pblockindex) { + + if (pblockindex->GetHeight() % 100 == 0 && pblockindex->GetHeight() < height - 5) { + LogPrintf("Building Witnesses for block %i %.4f complete\n", pblockindex->GetHeight(), pblockindex->GetHeight() / double(height)); + } + + SproutMerkleTree sproutTree; + sproutRoot = pblockindex->pprev->hashFinalSproutRoot; + pcoinsTip->GetSproutAnchorAt(sproutRoot, sproutTree); + + SaplingMerkleTree saplingTree; + saplingRoot = pblockindex->pprev->hashFinalSaplingRoot; + pcoinsTip->GetSaplingAnchorAt(saplingRoot, saplingTree); + + //Cycle through blocks and transactions building sapling tree until the commitment needed is reached + CBlock block; + ReadBlockFromDisk(block, pblockindex, 1); + + for (std::pair& wtxItem : mapWallet) { + + if (wtxItem.second.mapSproutNoteData.empty() && wtxItem.second.mapSaplingNoteData.empty()) + continue; + + if (wtxItem.second.GetDepthInMainChain() > 0) { + + //Sprout + for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { + auto* nd = &(item.second); + if (nd->nullifier && nd->witnessHeight == pblockindex->GetHeight() - 1 + && GetSproutSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { + + + nd->witnesses.push_front(nd->witnesses.front()); + while (nd->witnesses.size() > WITNESS_CACHE_SIZE) { + nd->witnesses.pop_back(); + } + + for (const CTransaction& tx : block.vtx) { + for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { + const JSDescription& jsdesc = tx.vjoinsplit[i]; + for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { + const uint256& note_commitment = jsdesc.commitments[j]; + nd->witnesses.front().append(note_commitment); + } + } + } + nd->witnessHeight = pblockindex->GetHeight(); + } + } + + //Sapling + for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { + auto* nd = &(item.second); + if (nd->nullifier && nd->witnessHeight == pblockindex->GetHeight() - 1 + && GetSaplingSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { + + nd->witnesses.push_front(nd->witnesses.front()); + while (nd->witnesses.size() > WITNESS_CACHE_SIZE) { + nd->witnesses.pop_back(); + } + + for (const CTransaction& tx : block.vtx) { + for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) { + const uint256& note_commitment = tx.vShieldedOutput[i].cm; + nd->witnesses.front().append(note_commitment); + } + } + nd->witnessHeight = pblockindex->GetHeight(); + } + } + } + } + + if (pblockindex == pindex) + break; + + pblockindex = chainActive.Next(pblockindex); + + } + } bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) @@ -1429,6 +1653,48 @@ void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx) } } +/** + * Update mapSproutNullifiersToNotes, computing the nullifier from a cached witness if necessary. + */ +void CWallet::UpdateSproutNullifierNoteMapWithTx(CWalletTx& wtx) { + LOCK(cs_wallet); + + ZCNoteDecryption dec; + for (mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) { + SproutNoteData nd = item.second; + + if (nd.witnesses.empty()) { + // If there are no witnesses, erase the nullifier and associated mapping. + if (nd.nullifier) { + mapSproutNullifiersToNotes.erase(nd.nullifier.get()); + } + nd.nullifier = boost::none; + } + else { + if (GetNoteDecryptor(nd.address, dec)) { + auto i = item.first.js; + auto hSig = wtx.vjoinsplit[i].h_sig( + *pzcashParams, wtx.joinSplitPubKey); + auto optNullifier = GetSproutNoteNullifier( + wtx.vjoinsplit[i], + item.second.address, + dec, + hSig, + item.first.n); + + if (!optNullifier) { + // This should not happen. If it does, maybe the position has been corrupted or miscalculated? + assert(false); + } + + uint256 nullifier = optNullifier.get(); + mapSproutNullifiersToNotes[nullifier] = item.first; + item.second.nullifier = nullifier; + } + } + } +} + /** * Update mapSaplingNullifiersToNotes, computing the nullifier from a cached witness if necessary. */ @@ -1479,13 +1745,14 @@ void CWallet::UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx) { * Iterate over transactions in a block and update the cached Sapling nullifiers * for transactions which belong to the wallet. */ -void CWallet::UpdateSaplingNullifierNoteMapForBlock(const CBlock *pblock) { +void CWallet::UpdateNullifierNoteMapForBlock(const CBlock *pblock) { LOCK(cs_wallet); for (const CTransaction& tx : pblock->vtx) { auto hash = tx.GetHash(); bool txIsOurs = mapWallet.count(hash); if (txIsOurs) { + UpdateSproutNullifierNoteMapWithTx(mapWallet[hash]); UpdateSaplingNullifierNoteMapWithTx(mapWallet[hash]); } } @@ -2725,6 +2992,298 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, } } +/** + * Reorder the transactions based on block hieght and block index. + * Transactions can get out of order when they are deleted and subsequently + * re-added during intial load rescan. + */ + +void CWallet::ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos) { + LOCK2(cs_main, cs_wallet); + + int maxSortNumber = chainActive.Tip()->GetHeight() + 1; + + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx wtx = it->second; + int confirms = wtx.GetDepthInMainChain(); + maxOrderPos = max(maxOrderPos, wtx.nOrderPos); + + if (confirms > 0) { + int wtxHeight = mapBlockIndex[wtx.hashBlock]->GetHeight(); + auto key = std::make_pair(wtxHeight, wtx.nIndex); + mapSorted.insert(make_pair(key, wtx)); + } + else { + auto key = std::make_pair(maxSortNumber, 0); + mapSorted.insert(std::make_pair(key, wtx)); + maxSortNumber++; + } + } +} + /**Update the nOrderPos with passed in ordered map. + */ + +void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder) { + LOCK2(cs_main, cs_wallet); + + int64_t previousPosition = 0; + std::map mapUpdatedTxs; + + //Check the postion of each transaction relative to the previous one. + for (map, CWalletTx>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { + CWalletTx wtx = it->second; + const uint256 wtxid = wtx.GetHash(); + + if (wtx.nOrderPos <= previousPosition || resetOrder) { + previousPosition++; + wtx.nOrderPos = previousPosition; + mapUpdatedTxs.insert(std::make_pair(wtxid, wtx)); + } + else { + previousPosition = wtx.nOrderPos; + } + } + + //Update transactions nOrderPos for transactions that changed + CWalletDB walletdb(strWalletFile, "r+", false); + for (map::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) { + CWalletTx wtx = it->second; + LogPrint("deletetx","Reorder Tx - Updating Positon to %i for Tx %s\n ", wtx.nOrderPos, wtx.GetHash().ToString()); + wtx.WriteToDisk(&walletdb); + mapWallet[wtx.GetHash()].nOrderPos = wtx.nOrderPos; + } + + //Update Next Wallet Tx Positon + nOrderPosNext = previousPosition++; + CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext); + LogPrint("deletetx","Reorder Tx - Total Transactions Reordered %i, Next Position %i\n ", mapUpdatedTxs.size(), nOrderPosNext); + +} + +/** + * Delete transactions from the Wallet + */ +void CWallet::DeleteTransactions(std::vector &removeTxs) { + LOCK(cs_wallet); + + CWalletDB walletdb(strWalletFile, "r+", false); + + for (int i = 0; i< removeTxs.size(); i++) { + if (mapWallet.erase(removeTxs[i])) { + walletdb.EraseTx(removeTxs[i]); + LogPrint("deletetx","Delete Tx - Deleting tx %s, %i.\n", removeTxs[i].ToString(),i); + } else { + LogPrint("deletetx","Delete Tx - Deleting tx %failed.\n", removeTxs[i].ToString()); + return; + } + } +} + +void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { + + LOCK2(cs_main, cs_wallet); + + int nDeleteAfter = (int)fDeleteTransactionsAfterNBlocks; + bool runCompact = false; + + if (pindex && fTxDeleteEnabled) { + + //Check for acentries - exit function if found + { + std::list acentries; + CWalletDB walletdb(strWalletFile); + walletdb.ListAccountCreditDebit("*", acentries); + if (acentries.size() > 0) { + LogPrintf("deletetx not compatible to account entries\n"); + return; + } + } + //delete transactions + + //Sort Transactions by block and block index + int64_t maxOrderPos = 0; + std::map, CWalletTx> mapSorted; + ReorderWalletTransactions(mapSorted, maxOrderPos); + if (maxOrderPos > int64_t(mapSorted.size())*10) { + //reset the postion when the max postion is 10x bigger than the + //number of transactions in the wallet + LogPrint("deletetx","Reorder Tx - maxOrderPos %i mapSorted Size %i\n", maxOrderPos, int64_t(mapSorted.size())*10); + UpdateWalletTransactionOrder(mapSorted, true); + } + else { + UpdateWalletTransactionOrder(mapSorted, false); + } + + //Process Transactions in sorted order + int txConflictCount = 0; + int txUnConfirmed = 0; + int txCount = 0; + int txSaveCount = 0; + std::vector removeTxs; + + for (auto & item : mapSorted) + { + + CWalletTx& wtx = item.second; + const uint256& wtxid = wtx.GetHash(); + bool deleteTx = true; + txCount += 1; + int wtxDepth = wtx.GetDepthInMainChain(); + + //Keep anything newer than N Blocks + if (wtxDepth == 0) + txUnConfirmed++; + + if (wtxDepth < nDeleteAfter && wtxDepth >= 0) { + LogPrint("deletetx","DeleteTx - Transaction above minimum depth, tx %s\n", wtx.GetHash().ToString()); + deleteTx = false; + txSaveCount++; + continue; + } else if (wtxDepth == -1) { + //Enabled by default + if (!fTxConflictDeleteEnabled) { + LogPrint("deletetx","DeleteTx - Conflict delete is not enabled tx %s\n", wtx.GetHash().ToString()); + deleteTx = false; + txSaveCount++; + continue; + } else { + txConflictCount++; + } + } else { + + //Check for unspent inputs or spend less than N Blocks ago. (Sapling) + for (auto & pair : wtx.mapSaplingNoteData) { + SaplingNoteData nd = pair.second; + if (!nd.nullifier || pwalletMain->GetSaplingSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { + LogPrint("deletetx","DeleteTx - Unspent sapling input tx %s\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sapling) + for (int i = 0; i < wtx.vShieldedSpend.size(); i++) { + const SpendDescription& spendDesc = wtx.vShieldedSpend[i]; + if (pwalletMain->IsSaplingNullifierFromMe(spendDesc.nullifier)) { + const uint256& parentHash = pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash; + const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); + if (parent != NULL && parentHash != wtxid) { + LogPrint("deletetx","DeleteTx - Parent of sapling tx %s found\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Check for unspent inputs or spend less than N Blocks ago. (Sprout) + for (auto & pair : wtx.mapSproutNoteData) { + SproutNoteData nd = pair.second; + if (!nd.nullifier || pwalletMain->GetSproutSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { + LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sprout) + for (int i = 0; i < wtx.vjoinsplit.size(); i++) { + const JSDescription& jsdesc = wtx.vjoinsplit[i]; + for (const uint256 &nullifier : jsdesc.nullifiers) { + // JSOutPoint op = pwalletMain->mapSproutNullifiersToNotes[nullifier]; + if (pwalletMain->IsSproutNullifierFromMe(nullifier)) { + const uint256& parentHash = pwalletMain->mapSproutNullifiersToNotes[nullifier].hash; + const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); + if (parent != NULL && parentHash != wtxid) { + LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Check for unspent inputs or spend less than N Blocks ago. (Transparent) + for (unsigned int i = 0; i < wtx.vout.size(); i++) { + CTxDestination address; + ExtractDestination(wtx.vout[i].scriptPubKey, address); + if(IsMine(wtx.vout[i])) { + if (pwalletMain->GetSpendDepth(wtx.GetHash(), i) <= fDeleteTransactionsAfterNBlocks) { + LogPrint("deletetx","DeleteTx - Unspent transparent input tx %s\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Chcek for output with that no longer have parents in the wallet. (Transparent) + for (int i = 0; i < wtx.vin.size(); i++) { + const CTxIn& txin = wtx.vin[i]; + const uint256& parentHash = txin.prevout.hash; + const CWalletTx* parent = pwalletMain->GetWalletTx(txin.prevout.hash); + if (parent != NULL && parentHash != wtxid) { + LogPrint("deletetx","DeleteTx - Parent of transparent tx %s found\n", wtx.GetHash().ToString()); + deleteTx = false; + continue; + } + } + + if (!deleteTx) { + txSaveCount++; + continue; + } + + //Keep Last N Transactions + if (mapSorted.size() - txCount < fKeepLastNTransactions + txConflictCount + txUnConfirmed) { + LogPrint("deletetx","DeleteTx - Transaction set position %i, tx %s\n", mapSorted.size() - txCount, wtxid.ToString()); + deleteTx = false; + txSaveCount++; + continue; + } + } + + //Collect everything else for deletion + if (deleteTx && int(removeTxs.size()) < MAX_DELETE_TX_SIZE) { + removeTxs.push_back(wtxid); + runCompact = true; + } + } + + //Delete Transactions from wallet + DeleteTransactions(removeTxs); + LogPrintf("Delete Tx - Total Transaction Count %i, Transactions Deleted %i\n ", txCount, int(removeTxs.size())); + + //Compress Wallet + if (runCompact) + CWalletDB::Compact(bitdb,strWalletFile); + } +} + /** * Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already @@ -2738,8 +3297,6 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) CBlockIndex* pindex = pindexStart; - std::vector myTxHashes; - { LOCK2(cs_main, cs_wallet); @@ -2761,7 +3318,6 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) { - myTxHashes.push_back(tx.GetHash()); ret++; } } @@ -2776,27 +3332,23 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree)); } } - // Increment note witness caches - ChainTip(pindex, &block, sproutTree, saplingTree, true); - pindex = chainActive.Next(pindex); + // Build inital witness caches + BuildWitnessCache(pindex, true); + + //Delete Transactions + if (pindex->GetHeight() % fDeleteInterval == 0) + DeleteWalletTransactions(pindex); + if (GetTime() >= nNow + 60) { nNow = GetTime(); LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->GetHeight(), Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex)); } + pindex = chainActive.Next(pindex); } - - // After rescanning, persist Sapling note data that might have changed, e.g. nullifiers. - // Do not flush the wallet here for performance reasons. - CWalletDB walletdb(strWalletFile, "r+", false); - for (auto hash : myTxHashes) { - CWalletTx wtx = mapWallet[hash]; - if (!wtx.mapSaplingNoteData.empty()) { - if (!wtx.WriteToDisk(&walletdb)) { - LogPrintf("Rescanning... WriteToDisk failed to update Sapling note data for: %s\n", hash.ToString()); - } - } - } + + //Update all witness caches + BuildWitnessCache(chainActive.Tip(), false); ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index eb350fb40..0946d452b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -23,6 +23,7 @@ #define BITCOIN_WALLET_WALLET_H #include "amount.h" +#include "asyncrpcoperation.h" #include "coins.h" #include "key.h" #include "keystore.h" @@ -60,6 +61,11 @@ extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; extern bool fSendFreeTransactions; extern bool fPayAtLeastCustomFee; +extern bool fTxDeleteEnabled; +extern bool fTxConflictDeleteEnabled; +extern int fDeleteInterval; +extern unsigned int fDeleteTransactionsAfterNBlocks; +extern unsigned int fKeepLastNTransactions; //! -paytxfee default @@ -82,6 +88,18 @@ extern unsigned int WITNESS_CACHE_SIZE; //! Size of HD seed in bytes static const size_t HD_WALLET_SEED_LENGTH = 32; +//Default Transaction Rentention N-BLOCKS +static const int DEFAULT_TX_DELETE_INTERVAL = 1000; + +//Default Transaction Rentention N-BLOCKS +static const unsigned int DEFAULT_TX_RETENTION_BLOCKS = 10000; + +//Default Retenion Last N-Transactions +static const unsigned int DEFAULT_TX_RETENTION_LASTTX = 200; + +//Amount of transactions to delete per run while syncing +static const int MAX_DELETE_TX_SIZE = 50000; + class CBlockIndex; class CCoinControl; class COutput; @@ -250,15 +268,18 @@ public: * -1 as a placeholder. The next time CWallet::ChainTip is called, we can * determine what height the witness cache for this note is valid for (even * if no witnesses were cached), and so can set the correct value in - * CWallet::IncrementNoteWitnesses and CWallet::DecrementNoteWitnesses. + * CWallet::BuildWitnessCache and CWallet::DecrementNoteWitnesses. */ int witnessHeight; - SproutNoteData() : address(), nullifier(), witnessHeight {-1} { } + //In Memory Only + bool witnessRootValidated; + + SproutNoteData() : address(), nullifier(), witnessHeight {-1}, witnessRootValidated {false} { } SproutNoteData(libzcash::SproutPaymentAddress a) : - address {a}, nullifier(), witnessHeight {-1} { } + address {a}, nullifier(), witnessHeight {-1}, witnessRootValidated {false} { } SproutNoteData(libzcash::SproutPaymentAddress a, uint256 n) : - address {a}, nullifier {n}, witnessHeight {-1} { } + address {a}, nullifier {n}, witnessHeight {-1}, witnessRootValidated {false} { } ADD_SERIALIZE_METHODS; @@ -300,6 +321,9 @@ public: libzcash::SaplingIncomingViewingKey ivk; boost::optional nullifier; + //In Memory Only + bool witnessRootValidated; + ADD_SERIALIZE_METHODS; template @@ -779,6 +803,9 @@ private: typedef TxSpendMap TxNullifiers; TxNullifiers mapTxSproutNullifiers; TxNullifiers mapTxSaplingNullifiers; + + std::vector pendingSaplingConsolidationTxs; + AsyncRPCOperationId saplingConsolidationOperationId; void AddToTransparentSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSproutSpends(const uint256& nullifier, const uint256& wtxid); @@ -793,6 +820,7 @@ public: */ int64_t nWitnessCacheSize; bool needsRescan = false; + bool fSaplingConsolidationEnabled = false; void ClearNoteWitnessCache(); @@ -800,13 +828,16 @@ public: std::set GetNullifiers(); protected: + + int SproutWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight); + int SaplingWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight); + /** * pindex is the new tip being connected. */ - void IncrementNoteWitnesses(const CBlockIndex* pindex, - const CBlock* pblock, - SproutMerkleTree& sproutTree, - SaplingMerkleTree& saplingTree); + int VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessOnly); + void BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly); + /** * pindex is the old tip being disconnected. */ @@ -1001,8 +1032,11 @@ public: bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; + unsigned int GetSpendDepth(const uint256& hash, unsigned int n) const; bool IsSproutSpent(const uint256& nullifier) const; + unsigned int GetSproutSpendDepth(const uint256& nullifier) const; bool IsSaplingSpent(const uint256& nullifier) const; + unsigned int GetSaplingSpendDepth(const uint256& nullifier) const; bool IsLockedCoin(uint256 hash, unsigned int n) const; void LockCoin(COutPoint& output); @@ -1137,8 +1171,9 @@ public: void MarkDirty(); bool UpdateNullifierNoteMap(); void UpdateNullifierNoteMapWithTx(const CWalletTx& wtx); + void UpdateSproutNullifierNoteMapWithTx(CWalletTx& wtx); void UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx); - void UpdateSaplingNullifierNoteMapForBlock(const CBlock* pblock); + void UpdateNullifierNoteMapForBlock(const CBlock* pblock); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void EraseFromWallet(const uint256 &hash); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); @@ -1148,6 +1183,10 @@ public: std::vector commitments, std::vector>& witnesses, uint256 &final_anchor); + void ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos); + void UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder); + void DeleteTransactions(std::vector &removeTxs); + void DeleteWalletTransactions(const CBlockIndex* pindex); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime); @@ -1215,6 +1254,8 @@ public: CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetChange(const CTransaction& tx) const; void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, SaplingMerkleTree saplingTree, bool added); + void RunSaplingConsolidation(int blockHeight); + void CommitConsolidationTx(const CTransaction& tx); /** Saves witness caches and best block locator to disk. */ void SetBestChain(const CBlockLocator& loc); std::set> GetNullifiersForAddresses(const std::set & addresses); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c29427b74..952a76735 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1208,6 +1208,12 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) return false; } +bool CWalletDB::Compact(CDBEnv& dbenv, const std::string& strFile) +{ + bool fSuccess = dbenv.Compact(strFile); + return fSuccess; +} + // // Try to (very carefully!) recover wallet.dat if there is a problem. // diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 2c57ec1e8..9069e3a08 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -189,6 +189,7 @@ public: DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); + static bool Compact(CDBEnv& dbenv, const std::string& strFile); static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, const std::string& filename); From 8556f00d379f3a7c36be40b5418df500355692e4 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Mon, 17 Feb 2020 21:36:17 +0100 Subject: [PATCH 014/220] resource friendly tx reorder port from https://github.com/CryptoForge/Zero/commit/58b05de90d06817d9bd47fe6b9adeaceccf3c95a --- src/wallet/wallet.cpp | 101 ++++++++++++++++++++++-------------------- src/wallet/wallet.h | 4 +- 2 files changed, 55 insertions(+), 50 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6e73f2a1a..953f738ef 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -49,6 +49,8 @@ #include #include +#include + using namespace std; using namespace libzcash; @@ -2998,60 +3000,61 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, * re-added during intial load rescan. */ -void CWallet::ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos) { +void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos) +{ LOCK2(cs_main, cs_wallet); int maxSortNumber = chainActive.Tip()->GetHeight() + 1; for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { - CWalletTx wtx = it->second; - int confirms = wtx.GetDepthInMainChain(); - maxOrderPos = max(maxOrderPos, wtx.nOrderPos); + CWalletTx* pwtx = &(it->second); + int confirms = pwtx->GetDepthInMainChain(); + maxOrderPos = max(maxOrderPos, pwtx->nOrderPos); if (confirms > 0) { - int wtxHeight = mapBlockIndex[wtx.hashBlock]->GetHeight(); - auto key = std::make_pair(wtxHeight, wtx.nIndex); - mapSorted.insert(make_pair(key, wtx)); + int wtxHeight = mapBlockIndex[pwtx->hashBlock]->GetHeight(); + auto key = std::make_pair(wtxHeight, pwtx->nIndex); + mapSorted.insert(make_pair(key, pwtx)); } else { - auto key = std::make_pair(maxSortNumber, 0); - mapSorted.insert(std::make_pair(key, wtx)); - maxSortNumber++; + auto key = std::make_pair(maxSortNumber, 0); + mapSorted.insert(std::make_pair(key, pwtx)); + maxSortNumber++; } } } /**Update the nOrderPos with passed in ordered map. */ -void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder) { +void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder) { LOCK2(cs_main, cs_wallet); int64_t previousPosition = 0; - std::map mapUpdatedTxs; + std::map mapUpdatedTxs; //Check the postion of each transaction relative to the previous one. - for (map, CWalletTx>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { - CWalletTx wtx = it->second; - const uint256 wtxid = wtx.GetHash(); +for (map, CWalletTx*>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) { + CWalletTx* pwtx = it->second; + const uint256 wtxid = pwtx->GetHash(); - if (wtx.nOrderPos <= previousPosition || resetOrder) { + if (pwtx->nOrderPos <= previousPosition || resetOrder) { previousPosition++; - wtx.nOrderPos = previousPosition; - mapUpdatedTxs.insert(std::make_pair(wtxid, wtx)); + pwtx->nOrderPos = previousPosition; + mapUpdatedTxs.insert(std::make_pair(wtxid, pwtx)); } else { - previousPosition = wtx.nOrderPos; + previousPosition = pwtx->nOrderPos; } } //Update transactions nOrderPos for transactions that changed CWalletDB walletdb(strWalletFile, "r+", false); - for (map::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) { - CWalletTx wtx = it->second; - LogPrint("deletetx","Reorder Tx - Updating Positon to %i for Tx %s\n ", wtx.nOrderPos, wtx.GetHash().ToString()); - wtx.WriteToDisk(&walletdb); - mapWallet[wtx.GetHash()].nOrderPos = wtx.nOrderPos; + for (map::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) { + CWalletTx* pwtx = it->second; + LogPrint("deletetx","Reorder Tx - Updating Positon to %i for Tx %s\n ", pwtx->nOrderPos, pwtx->GetHash().ToString()); + pwtx->WriteToDisk(&walletdb); + mapWallet[pwtx->GetHash()].nOrderPos = pwtx->nOrderPos; } //Update Next Wallet Tx Positon @@ -3078,6 +3081,8 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) { return; } } + // Miodrag: release memory back to the OS + malloc_trim(0); } void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { @@ -3103,7 +3108,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { //Sort Transactions by block and block index int64_t maxOrderPos = 0; - std::map, CWalletTx> mapSorted; + std::map, CWalletTx*> mapSorted; ReorderWalletTransactions(mapSorted, maxOrderPos); if (maxOrderPos > int64_t(mapSorted.size())*10) { //reset the postion when the max postion is 10x bigger than the @@ -3125,25 +3130,25 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { for (auto & item : mapSorted) { - CWalletTx& wtx = item.second; - const uint256& wtxid = wtx.GetHash(); + CWalletTx* pwtx = item.second; + const uint256& wtxid = pwtx->GetHash(); bool deleteTx = true; txCount += 1; - int wtxDepth = wtx.GetDepthInMainChain(); + int wtxDepth = pwtx->GetDepthInMainChain(); //Keep anything newer than N Blocks if (wtxDepth == 0) txUnConfirmed++; if (wtxDepth < nDeleteAfter && wtxDepth >= 0) { - LogPrint("deletetx","DeleteTx - Transaction above minimum depth, tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Transaction above minimum depth, tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; txSaveCount++; continue; } else if (wtxDepth == -1) { //Enabled by default if (!fTxConflictDeleteEnabled) { - LogPrint("deletetx","DeleteTx - Conflict delete is not enabled tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Conflict delete is not enabled tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; txSaveCount++; continue; @@ -3153,10 +3158,10 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } else { //Check for unspent inputs or spend less than N Blocks ago. (Sapling) - for (auto & pair : wtx.mapSaplingNoteData) { + for (auto & pair : pwtx->mapSaplingNoteData) { SaplingNoteData nd = pair.second; if (!nd.nullifier || pwalletMain->GetSaplingSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent sapling input tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Unspent sapling input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3168,13 +3173,13 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sapling) - for (int i = 0; i < wtx.vShieldedSpend.size(); i++) { - const SpendDescription& spendDesc = wtx.vShieldedSpend[i]; + for (int i = 0; i < pwtx->vShieldedSpend.size(); i++) { + const SpendDescription& spendDesc = pwtx->vShieldedSpend[i]; if (pwalletMain->IsSaplingNullifierFromMe(spendDesc.nullifier)) { const uint256& parentHash = pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash; const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of sapling tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of sapling tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3187,10 +3192,10 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for unspent inputs or spend less than N Blocks ago. (Sprout) - for (auto & pair : wtx.mapSproutNoteData) { + for (auto & pair : pwtx->mapSproutNoteData) { SproutNoteData nd = pair.second; if (!nd.nullifier || pwalletMain->GetSproutSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3202,15 +3207,15 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sprout) - for (int i = 0; i < wtx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = wtx.vjoinsplit[i]; + for (int i = 0; i < pwtx->vjoinsplit.size(); i++) { + const JSDescription& jsdesc = pwtx->vjoinsplit[i]; for (const uint256 &nullifier : jsdesc.nullifiers) { // JSOutPoint op = pwalletMain->mapSproutNullifiersToNotes[nullifier]; if (pwalletMain->IsSproutNullifierFromMe(nullifier)) { const uint256& parentHash = pwalletMain->mapSproutNullifiersToNotes[nullifier].hash; const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3224,12 +3229,12 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Check for unspent inputs or spend less than N Blocks ago. (Transparent) - for (unsigned int i = 0; i < wtx.vout.size(); i++) { + for (unsigned int i = 0; i < pwtx->vout.size(); i++) { CTxDestination address; - ExtractDestination(wtx.vout[i].scriptPubKey, address); - if(IsMine(wtx.vout[i])) { - if (pwalletMain->GetSpendDepth(wtx.GetHash(), i) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent transparent input tx %s\n", wtx.GetHash().ToString()); + ExtractDestination(pwtx->vout[i].scriptPubKey, address); + if(IsMine(pwtx->vout[i])) { + if (pwalletMain->GetSpendDepth(pwtx->GetHash(), i) <= fDeleteTransactionsAfterNBlocks) { + LogPrint("deletetx","DeleteTx - Unspent transparent input tx %s\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } @@ -3242,12 +3247,12 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { } //Chcek for output with that no longer have parents in the wallet. (Transparent) - for (int i = 0; i < wtx.vin.size(); i++) { - const CTxIn& txin = wtx.vin[i]; + for (int i = 0; i < pwtx->vin.size(); i++) { + const CTxIn& txin = pwtx->vin[i]; const uint256& parentHash = txin.prevout.hash; const CWalletTx* parent = pwalletMain->GetWalletTx(txin.prevout.hash); if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of transparent tx %s found\n", wtx.GetHash().ToString()); + LogPrint("deletetx","DeleteTx - Parent of transparent tx %s found\n", pwtx->GetHash().ToString()); deleteTx = false; continue; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0946d452b..79d24a86d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1183,8 +1183,8 @@ public: std::vector commitments, std::vector>& witnesses, uint256 &final_anchor); - void ReorderWalletTransactions(std::map, CWalletTx> &mapSorted, int64_t &maxOrderPos); - void UpdateWalletTransactionOrder(std::map, CWalletTx> &mapSorted, bool resetOrder); + void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); + void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); void DeleteTransactions(std::vector &removeTxs); void DeleteWalletTransactions(const CBlockIndex* pindex); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); From d3226b8a5c48d94fdf9a8786caac5877b6654083 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 18 Feb 2020 09:15:42 -0500 Subject: [PATCH 015/220] Update security-warnings.md --- doc/security-warnings.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/security-warnings.md b/doc/security-warnings.md index eba7141fc..f12b4fe12 100644 --- a/doc/security-warnings.md +++ b/doc/security-warnings.md @@ -64,7 +64,7 @@ be able to: each note ciphertext on the blockchain. You should ensure no other users have the ability to execute code (even -unprivileged) on the hardware your `zcashd` process runs on until these +unprivileged) on the hardware your `hushd` process runs on until these vulnerabilities are fully analyzed and fixed. REST Interface @@ -77,9 +77,9 @@ security review. RPC Interface --------------- -Users should choose a strong RPC password. If no RPC username and password are set, zcashd will not start and will print an error message with a suggestion for a strong random password. If the client knows the RPC password, they have at least full access to the node. In addition, certain RPC commands can be misused to overwrite files and/or take over the account that is running zcashd. (In the future we may restrict these commands, but full node access – including the ability to spend from and export keys held by the wallet – would still be possible unless wallet methods are disabled.) +Users should choose a strong RPC password. If no RPC username and password are set, hush will not start and will print an error message with a suggestion for a strong random password. If the client knows the RPC password, they have at least full access to the node. In addition, certain RPC commands can be misused to overwrite files and/or take over the account that is running hushd. (In the future we may restrict these commands, but full node access – including the ability to spend from and export keys held by the wallet – would still be possible unless wallet methods are disabled.) -Users should also refrain from changing the default setting that only allows RPC connections from localhost. Allowing connections from remote hosts would enable a MITM to execute arbitrary RPC commands, which could lead to compromise of the account running zcashd and loss of funds. For multi-user services that use one or more zcashd instances on the backend, the parameters passed in by users should be controlled to prevent confused-deputy attacks which could spend from any keys held by that zcashd. +Users should also refrain from changing the default setting that only allows RPC connections from localhost. Allowing connections from remote hosts would enable a MITM to execute arbitrary RPC commands, which could lead to compromise of the account running hushd and loss of funds. For multi-user services that use one or more hushd instances on the backend, the parameters passed in by users should be controlled to prevent confused-deputy attacks which could spend from any keys held by that zcashd. Block Chain Reorganization: Major Differences ------------------------------------------------- @@ -100,11 +100,9 @@ Private spending keys for z addresses are never logged. Potentially-Missing Required Modifications ------------------------------------------ -In addition to potential mistakes in code we added to Bitcoin Core, and -potential mistakes in our modifications to Bitcoin Core, it is also possible -that there were potential changes we were supposed to make to Bitcoin Core but +In addition to potential mistakes in code we added to Bitcoin Core, Zcash +and Komodo and +potential mistakes in our modifications to Bitcoin Core, Zcash and Komodo, it is also possible +that there were potential changes we were supposed to make to Bitcoin Core, Zcash and Komodo but didn't, either because we didn't even consider making those changes, or we ran -out of time. We have brainstormed and documented a variety of such possibilities -in [issue #826](https://github.com/zcash/zcash/issues/826), and believe that we -have changed or done everything that was necessary for the 1.0.0 launch. Users -may want to review this list themselves. +out of time. From 4a731fed47280bc177ec372fac125c0f2082dbde Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 18 Feb 2020 09:16:44 -0500 Subject: [PATCH 016/220] Update security-warnings.md --- doc/security-warnings.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/security-warnings.md b/doc/security-warnings.md index f12b4fe12..023efe92b 100644 --- a/doc/security-warnings.md +++ b/doc/security-warnings.md @@ -104,5 +104,5 @@ In addition to potential mistakes in code we added to Bitcoin Core, Zcash and Komodo and potential mistakes in our modifications to Bitcoin Core, Zcash and Komodo, it is also possible that there were potential changes we were supposed to make to Bitcoin Core, Zcash and Komodo but -didn't, either because we didn't even consider making those changes, or we ran -out of time. +didn't, either because we didn't even consider making those changes or have not found out about +them. Submitting Github issues is highly appreciated! From f6a8303b493f2025c62327a86b44b52a41151622 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 18 Feb 2020 09:18:37 -0500 Subject: [PATCH 017/220] Update security-warnings.md --- doc/security-warnings.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/security-warnings.md b/doc/security-warnings.md index 023efe92b..50862de52 100644 --- a/doc/security-warnings.md +++ b/doc/security-warnings.md @@ -1,13 +1,15 @@ Security Warnings ==================== -Security Audit +Security Audits -------------- -Hush has been subjected to a formal third-party security review. For security +Hush has not been subjected to a formal third-party security review! But the +Zcash source code has. For security announcements, audit results and other general security information, see https://z.cash/support/security.html + x86-64 Linux Only ----------------------- From 6a296f01d4dbadc01ea86e547702ff7c7fde10ec Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 18 Feb 2020 09:19:56 -0500 Subject: [PATCH 018/220] Update security-warnings.md --- doc/security-warnings.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/security-warnings.md b/doc/security-warnings.md index 50862de52..66797444b 100644 --- a/doc/security-warnings.md +++ b/doc/security-warnings.md @@ -9,6 +9,11 @@ Zcash source code has. For security announcements, audit results and other general security information, see https://z.cash/support/security.html +Hush does our best to integrate fixes and recommendations from Zcash audits +to our own code, such as audits on ZecWallet that apply to SilentDragon. +Hush also reports many new bugs and issues to upstream Zcash and many other +Zcash Protocol coins. + x86-64 Linux Only ----------------------- From c1fa21cad163fc2c4bcc4adbe95ffa25db3f02f6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 24 Feb 2020 05:42:11 -0500 Subject: [PATCH 019/220] Most Hush blocks have 2 coinbase, one for miner and one for FR; improves #82 --- src/rpc/blockchain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 0b22255d1..76375b80c 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1875,9 +1875,11 @@ inline CBlockIndex* LookupBlockIndex(const uint256& hash) return it == mapBlockIndex.end() ? nullptr : it->second; } +// Every coin can have different number of coinbase due to Founders Reward addresses/etc +#define COINBASE_PER_BLOCK 2 // given a transaction count X, subtract out coinbase and dpow transactions // to give an "organic count". We return 0 instead of negative values -#define ORG(X) ( (X - blockcount - nNotarizationsDiff) > 0 ? (X - blockcount - nNotarizationsDiff) : 0 ) +#define ORG(X) ( (X - COINBASE_PER_BLOCK*blockcount - nNotarizationsDiff) > 0 ? (X - COINBASE_PER_BLOCK*blockcount - nNotarizationsDiff) : 0 ) //TODO: Allow custom error message in this macro #define THROW_IF_SYNCING(INSYNC) if (INSYNC == 0) { throw runtime_error(strprintf("%s: Chain still syncing at height %d, aborting to prevent garbage data. Please wait until the chain is synced to run this RPC",__FUNCTION__,chainActive.Tip()->GetHeight())); } From c984c2e8d53c0e3abcf412e4f9126aa429070508 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 25 Feb 2020 11:54:23 +0100 Subject: [PATCH 020/220] port z_listsentbyaddress and add memo field from https://github.com/zerocurrencycoin/Zero/commit/c00e30b210245cc5cc4deada5c6202042a3b9da2 --- src/Makefile.am | 2 + src/rpc/client.cpp | 5 + src/rpc/register.h | 3 + src/wallet/rpchushwallet.cpp | 645 +++++++++++++++++++++++++++++++++++ src/wallet/rpchushwallet.h | 29 ++ 5 files changed, 684 insertions(+) create mode 100644 src/wallet/rpchushwallet.cpp create mode 100644 src/wallet/rpchushwallet.h diff --git a/src/Makefile.am b/src/Makefile.am index 4d44f8483..6277e0f98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -236,6 +236,7 @@ BITCOIN_CORE_H = \ wallet/crypter.h \ wallet/db.h \ wallet/rpcwallet.h \ + wallet/rpchushwallet.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ @@ -366,6 +367,7 @@ libbitcoin_wallet_a_SOURCES = \ cc/CCassetstx.cpp \ cc/CCtx.cpp \ wallet/rpcwallet.cpp \ + wallet/rpchushwallet.cpp \ wallet/wallet.cpp \ wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index ddc0915d7..1ed44b48c 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -170,6 +170,11 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_importviewingkey", 2 }, { "z_getpaymentdisclosure", 1}, { "z_getpaymentdisclosure", 2}, + { "z_listsentbyaddress", 1}, + { "z_listsentbyaddress", 2}, + { "z_listsentbyaddress", 3}, + { "z_listsentbyaddress", 4}, + { "z_listsentbyaddress", 5}, // crosschain { "assetchainproof", 1}, { "crosschainproof", 1}, diff --git a/src/rpc/register.h b/src/rpc/register.h index 245f76e22..725ed7550 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -34,6 +34,8 @@ void RegisterMiscRPCCommands(CRPCTable &tableRPC); void RegisterMiningRPCCommands(CRPCTable &tableRPC); /** Register raw transaction RPC commands */ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); +/** Register Experimental RPC commands */ +void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC); /** Register test transaction RPC commands */ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); @@ -46,6 +48,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) RegisterMiscRPCCommands(tableRPC); RegisterMiningRPCCommands(tableRPC); RegisterRawTransactionRPCCommands(tableRPC); + RegisterHushExclusiveRPCCommands(tableRPC); #ifdef TESTMODE RegisterTesttransactionsRPCCommands(tableRPC); #endif diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp new file mode 100644 index 000000000..89b5b5dcc --- /dev/null +++ b/src/wallet/rpchushwallet.cpp @@ -0,0 +1,645 @@ +// Copyright (c) 2020 The Hush developers +// Copyright (c) 2019 Cryptoforge +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "init.h" +#include "key_io.h" +#include "rpc/server.h" +#include "wallet.h" +#include "rpchushwallet.h" +#include "utilmoneystr.h" +#include + +using namespace std; +using namespace libzcash; + +bool EnsureWalletIsAvailable(bool avoidException); + +void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpends, CAmount& filteredSpends, const std::string& strAddress, bool filterByAddress) { + + LOCK2(cs_main, pwalletMain->cs_wallet); + + //Used to identify incomplete key sets + int vinCount = 0; + int vinSpendCount = 0; + int shieldedSpendCount = 0; + int shieldedSpendsSpentCount = 0; + + //Check address + bool isTAddress = false; + bool isZsAddress = false; + + CTxDestination tAddress = DecodeDestination(strAddress); + auto zAddress = DecodePaymentAddress(strAddress); + SaplingPaymentAddress zsAddress; + + if (filterByAddress) { + + if (IsValidDestination(tAddress)) + isTAddress = true; + + if (IsValidPaymentAddress(zAddress)) { + if (boost::get(&zAddress) != nullptr) { + zsAddress = boost::get(zAddress); + isZsAddress = true; + } + } + } + + + // Transparent Inputs belonging to the wallet + UniValue tSpends(UniValue::VARR); + if (isTAddress || !filterByAddress) { + for (int i = 0; i < wtx.vin.size(); i++) { + vinCount++; + const CTxIn& txin = wtx.vin[i]; + UniValue obj(UniValue::VOBJ); + CTxDestination address; + const CWalletTx* parent = pwalletMain->GetWalletTx(txin.prevout.hash); + if (parent != NULL) { + const CTxOut& parentOut = parent->vout[txin.prevout.n]; + ExtractDestination(parentOut.scriptPubKey, address); + if(IsMine(*pwalletMain, address)){ + vinSpendCount++; + totalSpends += CAmount(-parentOut.nValue); + obj.push_back(Pair("address",EncodeDestination(address))); + obj.push_back(Pair("scriptPubKey",HexStr(parentOut.scriptPubKey.begin(), parentOut.scriptPubKey.end()))); + obj.push_back(Pair("amount",ValueFromAmount(-parentOut.nValue))); + obj.push_back(Pair("spendTxid",parent->GetHash().ToString())); + obj.push_back(Pair("spendVout",(int)txin.prevout.n)); + CTxDestination filterAddress = DecodeDestination(strAddress); + if (address == tAddress || !filterByAddress) { + filteredSpends += CAmount(-parentOut.nValue); + tSpends.push_back(obj); + } + } + } + } + } + spends.push_back(Pair("transparentSpends",tSpends)); + + // Sapling Inputs belonging to the wallet + UniValue zsSpends(UniValue::VARR); + if (isZsAddress || !filterByAddress) { + for (int i = 0; i < wtx.vShieldedSpend.size(); i++) { + shieldedSpendCount++; + const SpendDescription& spendDesc = wtx.vShieldedSpend[i]; + UniValue obj(UniValue::VOBJ); + + SaplingOutPoint op = pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier]; + + if (pwalletMain->IsSaplingNullifierFromMe(spendDesc.nullifier)) { + const CWalletTx* parent = pwalletMain->GetWalletTx(pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash); + const OutputDescription& output = parent->vShieldedOutput[op.n]; + auto nd = pwalletMain->mapWallet[pwalletMain->mapSaplingNullifiersToNotes[spendDesc.nullifier].hash].mapSaplingNoteData[op]; + auto pt = libzcash::SaplingNotePlaintext::decrypt(output.encCiphertext,nd.ivk,output.ephemeralKey,output.cm); + + if (pt) { + auto note = pt.get(); + auto pa = nd.ivk.address(note.d); + auto address = pa.get(); + shieldedSpendsSpentCount++; + totalSpends += CAmount(-note.value()); + obj.push_back(Pair("address",EncodePaymentAddress(address))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(-note.value())))); + obj.push_back(Pair("spendTxid",parent->GetHash().ToString())); + obj.push_back(Pair("spendshieldedOutputIndex",(int)op.n)); + if (address == zsAddress || !filterByAddress) { + filteredSpends += CAmount(-note.value()); + zsSpends.push_back(obj); + } + } + } + } + } + spends.push_back(Pair("saplingSpends",zsSpends)); + + + spends.push_back(Pair("totalSpends",ValueFromAmount(filteredSpends))); + + if (!filterByAddress) { + if (filteredSpends != 0 && (vinCount != vinSpendCount || shieldedSpendCount != shieldedSpendsSpentCount)) { + spends.push_back(Pair("missingSpendingKeys", true)); + spends.push_back(Pair("vinCount", vinCount)); + spends.push_back(Pair("vinSpendCount", vinSpendCount)); + spends.push_back(Pair("shieldedSpendCount", shieldedSpendCount)); + spends.push_back(Pair("shieldedSpendsSpentCount", shieldedSpendsSpentCount)); + } else { + spends.push_back(Pair("missingSpendingKeys", false)); + } + } +} + + +void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress) { + + LOCK2(cs_main, pwalletMain->cs_wallet); + + //Check address + bool isTAddress = false; + bool isZsAddress = false; + + CTxDestination tAddress = DecodeDestination(strAddress); + auto zAddress = DecodePaymentAddress(strAddress); + SaplingPaymentAddress zsAddress; + + if (filterByAddress) { + + if (IsValidDestination(tAddress)) + isTAddress = true; + + if (IsValidPaymentAddress(zAddress)) { + if (boost::get(&zAddress) != nullptr) { + zsAddress = boost::get(zAddress); + isZsAddress = true; + } + } + } + + + //Transparent Received txos belonging to the wallet + UniValue tReceived(UniValue::VARR); + if (isTAddress || !filterByAddress) { + for (int i = 0; i < wtx.vout.size(); i++) { + const CTxOut& txout = wtx.vout[i]; + UniValue obj(UniValue::VOBJ); + CTxDestination address; + ExtractDestination(txout.scriptPubKey, address); + if(IsMine(*pwalletMain, address)){ + obj.push_back(Pair("address",EncodeDestination(address))); + obj.push_back(Pair("scriptPubKey",HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end()))); + obj.push_back(Pair("amount",ValueFromAmount(txout.nValue))); + obj.push_back(Pair("vout", i)); + if (address == tAddress || !filterByAddress) { + totalReceived += CAmount(txout.nValue); + tReceived.push_back(obj); + } + } + } + } + received.push_back(Pair("transparentReceived",tReceived)); + + + //Sapling Sends belonging to the wallet + UniValue zsReceived(UniValue::VARR); + if (isZsAddress || !filterByAddress) { + for (int i = 0; i < wtx.vShieldedOutput.size(); i++) { + const OutputDescription& outputDesc = wtx.vShieldedOutput[i]; + UniValue obj(UniValue::VOBJ); + bool changeTx = false; + //Decrypt sapling incoming commitments using IVK + std::set addresses; + pwalletMain->GetSaplingPaymentAddresses(addresses); + for (auto addr : addresses) { + libzcash::SaplingExtendedSpendingKey extsk; + if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + auto pt = libzcash::SaplingNotePlaintext::decrypt( + outputDesc.encCiphertext, extsk.expsk.full_viewing_key().in_viewing_key(), outputDesc.ephemeralKey, outputDesc.cm); + + if (pt) { + auto note = pt.get(); + obj.push_back(Pair("address",EncodePaymentAddress(addr))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(note.value())))); + obj.push_back(Pair("shieldedOutputIndex",i)); + + //Check Change Status + if (wtx.vShieldedSpend.size()!=0) { + std::set> nullifierSet; + nullifierSet = pwalletMain->GetNullifiersForAddresses({addr}); + BOOST_FOREACH(const SpendDescription& spendDesc, wtx.vShieldedSpend) { + if (nullifierSet.count(std::make_pair(addr, spendDesc.nullifier))) { + changeTx = true; + } + } + } + obj.push_back(Pair("change",changeTx)); + if (addr == zsAddress || !filterByAddress) { + totalReceived += CAmount(note.value()); + zsReceived.push_back(obj); + } + } + } + } + } + } + received.push_back(Pair("saplingReceived",zsReceived)); + + received.push_back(Pair("totalReceived",ValueFromAmount(totalReceived))); +} + + +void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress) { + + LOCK2(cs_main, pwalletMain->cs_wallet); + + //Used to identify incomplete key sets + int shieldedOutputCount = 0; + int shieldedOutputDecryptedCount = 0; + + //Check address + bool isTAddress = false; + bool isZsAddress = false; + + CTxDestination tAddress = DecodeDestination(strAddress); + auto zAddress = DecodePaymentAddress(strAddress); + SaplingPaymentAddress zsAddress; + + if (filterByAddress) { + + if (IsValidDestination(tAddress)) + isTAddress = true; + + if (IsValidPaymentAddress(zAddress)) { + if (boost::get(&zAddress) != nullptr) { + zsAddress = boost::get(zAddress); + isZsAddress = true; + } + } + } + + //All Transparent Sends in the transaction + + UniValue tSends(UniValue::VARR); + if (isTAddress || !filterByAddress) { + for (int i = 0; i < wtx.vout.size(); i++) { + const CTxOut& txout = wtx.vout[i]; + UniValue obj(UniValue::VOBJ); + CTxDestination address; + ExtractDestination(txout.scriptPubKey, address); + obj.push_back(Pair("address",EncodeDestination(address))); + obj.push_back(Pair("scriptPubKey",HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end()))); + obj.push_back(Pair("amount",ValueFromAmount(-txout.nValue))); + obj.push_back(Pair("vout", i)); + if (address == tAddress || !filterByAddress) { + totalSends += CAmount(-txout.nValue); + tSends.push_back(obj); + } + } + } + sends.push_back(Pair("transparentSends",tSends)); + + //All Shielded Sends in the transaction + UniValue zsSends(UniValue::VARR); + if (isZsAddress || !filterByAddress) { + for (int i = 0; i < wtx.vShieldedOutput.size(); i++) { + const OutputDescription& outputDesc = wtx.vShieldedOutput[i]; + shieldedOutputCount++; + UniValue obj(UniValue::VOBJ); + bool changeTx = false; + + //Decrypt sapling outgoing t to z transaction using HDseed + if (wtx.vShieldedSpend.size()==0) { + HDSeed seed; + if (pwalletMain->GetHDSeed(seed)) { + auto opt = libzcash::SaplingOutgoingPlaintext::decrypt( + outputDesc.outCiphertext,ovkForShieldingFromTaddr(seed),outputDesc.cv,outputDesc.cm,outputDesc.ephemeralKey); + + if (opt) { + auto opt_unwrapped = opt.get(); + auto pt = libzcash::SaplingNotePlaintext::decrypt( + outputDesc.encCiphertext,outputDesc.ephemeralKey,opt_unwrapped.esk,opt_unwrapped.pk_d,outputDesc.cm); + + if (pt) { + shieldedOutputDecryptedCount++; + auto pt_unwrapped = pt.get(); + libzcash::SaplingPaymentAddress sentAddr(pt_unwrapped.d, opt_unwrapped.pk_d); + obj.push_back(Pair("address",EncodePaymentAddress(sentAddr))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(pt_unwrapped.value())))); + obj.push_back(Pair("shieldedOutputIndex",i)); + obj.push_back(Pair("change",false)); + if (sentAddr == zsAddress || !filterByAddress) { + totalSends += CAmount(-pt_unwrapped.value()); + zsSends.push_back(obj); + } + } + } + } + + //attempt Decryption of Outgoing Sapling using wallet extended spending keys + } else { + std::set addresses; + pwalletMain->GetSaplingPaymentAddresses(addresses); + for (auto addr : addresses) { + libzcash::SaplingExtendedSpendingKey extsk; + if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + auto opt = libzcash::SaplingOutgoingPlaintext::decrypt( + outputDesc.outCiphertext,extsk.expsk.full_viewing_key().ovk,outputDesc.cv,outputDesc.cm,outputDesc.ephemeralKey); + + if (opt) { + auto opt_unwrapped = opt.get(); + auto pt = libzcash::SaplingNotePlaintext::decrypt( + outputDesc.encCiphertext,outputDesc.ephemeralKey,opt_unwrapped.esk,opt_unwrapped.pk_d,outputDesc.cm); + + if (pt) { + auto pt_unwrapped = pt.get(); + auto memo = pt_unwrapped.memo(); + shieldedOutputDecryptedCount++; + libzcash::SaplingPaymentAddress sentAddr(pt_unwrapped.d, opt_unwrapped.pk_d); + obj.push_back(Pair("address",EncodePaymentAddress(sentAddr))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(-pt_unwrapped.value())))); + obj.push_back(Pair("memo", HexStr(memo))); + + if (memo[0] <= 0xf4) { + auto end = std::find_if(memo.rbegin(), memo.rend(), [](unsigned char v) { return v != 0; }); + std::string memoStr(memo.begin(), end.base()); + if (utf8::is_valid(memoStr)) { + obj.push_back(Pair("memoStr", memoStr)); + } + } + obj.push_back(Pair("shieldedOutputIndex",i)); + + //Check Change Status + if (wtx.vShieldedSpend.size()!=0) { + std::set> nullifierSet; + nullifierSet = pwalletMain->GetNullifiersForAddresses({sentAddr}); + BOOST_FOREACH(const SpendDescription& spendDesc, wtx.vShieldedSpend) { + if (nullifierSet.count(std::make_pair(sentAddr, spendDesc.nullifier))) { + changeTx = true; + } + } + } + obj.push_back(Pair("change",changeTx)); + if (sentAddr == zsAddress || !filterByAddress) { + totalSends += CAmount(-pt_unwrapped.value()); + zsSends.push_back(obj); + } + } + } + } + } + } + } + } + sends.push_back(Pair("saplingSends",zsSends)); + + if (shieldedOutputCount != shieldedOutputDecryptedCount) { + sends.push_back(Pair("missingSaplingOVK", true)); + } else { + sends.push_back(Pair("missingSaplingOVK", false)); + } + + sends.push_back(Pair("totalSends",ValueFromAmount(totalSends))); +} + + +void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType) { + + LOCK2(cs_main, pwalletMain->cs_wallet); + + //Track total wallet spend and received + CAmount totalSpends = 0; + CAmount filteredSpends = 0; + CAmount totalReceived = 0; + CAmount totalSends = 0; + + //Various Univalue to be added to the final transaction + UniValue spends(UniValue::VOBJ); + UniValue received(UniValue::VOBJ); + UniValue sends(UniValue::VOBJ); + UniValue tx(UniValue::VOBJ); + + //Begin Compiling the Decrypted Transaction + tx.push_back(Pair("txid", wtx.GetHash().ToString())); + if (wtx.IsCoinBase()) + { + tx.push_back(Pair("coinbase", true)); + if (wtx.GetDepthInMainChain() < 1) + tx.push_back(Pair("category", "orphan")); + else if (wtx.GetBlocksToMaturity() > 0) + tx.push_back(Pair("category", "immature")); + else + tx.push_back(Pair("category", "generate")); + } else { + tx.push_back(Pair("coinbase", false)); + tx.push_back(Pair("category", "standard")); + } + + tx.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); + tx.push_back(Pair("blockindex", wtx.nIndex)); + int confirms = wtx.GetDepthInMainChain(); + if(confirms > 0) + { + tx.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + } else { + tx.push_back(Pair("blocktime", 0)); + } + tx.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight)); + tx.push_back(Pair("confirmations", confirms)); + tx.push_back(Pair("time", wtx.GetTxTime())); + tx.push_back(Pair("size", static_cast(GetSerializeSize(static_cast(wtx), SER_NETWORK, PROTOCOL_VERSION)))); + + //Wallet Conflicts + UniValue conflicts(UniValue::VARR); + BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) + conflicts.push_back(conflict.GetHex()); + tx.push_back(Pair("walletconflicts", conflicts)); + + // Return Type used to determine what is included in the transaction + // 0 Spends, Received and spends + // 1 Sends + // 2 Received + // 3 Spends + // TODO - Setup Enum, maybe... + + // Add Spends retrieved earlier + if (returnType != 2) { + zsTxSpendsToJSON(wtx, spends, totalSpends, filteredSpends, strAddress, fBool); + if ((!fBool || filteredSpends != 0) && (returnType == 0 || returnType == 1)) { + tx.push_back(Pair("spends",spends)); + } + } + // Get Received + if (returnType == 0 || returnType == 2) { + zsTxReceivedToJSON(wtx, received, totalReceived, strAddress, fBool); + if (!fBool || totalReceived != 0) { + tx.push_back(Pair("received",received)); + } + } + + // Get Sends + if (returnType == 0 || returnType == 3) { + //Only include sends if there are spends that belong to the wallet. + if (totalSpends != 0 || fBool) { + zsTxSendsToJSON(wtx, sends, totalSends, strAddress, fBool); + } + if (!fBool || totalSends != 0) { + tx.push_back(Pair("sends",sends)); + } + } + + if ((returnType == 0 && (!fBool || filteredSpends != 0 || totalReceived != 0 || totalSends != 0)) + || (returnType == 1 && (!fBool || filteredSpends != 0)) + || (returnType == 2 && (!fBool || totalReceived != 0)) + || (returnType == 3 && (!fBool || totalSends != 0))) { + ret.push_back(tx); + } + +} + +UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 5 || params.size() == 3) + throw runtime_error( + "z_listsentbyaddress\n" + "\nReturns decrypted Hush outputs sent to a single address.\n" + "\n" + "This function only returns information on addresses sent from wallet addresses with full spending keys." + "\n" + "\nArguments:\n" + "1. \"hushaddress:\" (string, required) \n" + "\n" + "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" + "\n" + "3. \"Filter Type:\" (numeric, optional, default=0) \n" + " Value of 0: Returns all transactions in the wallet\n" + " Value of 1: Returns the last x days of transactions\n" + " Value of 2: Returns transactions with confimations less than x\n" + "\n" + "4. \"Filter:\" (numeric, optional, default=999999) \n" + " Filter Type equal 0: paramater ignored\n" + " Filter Type equal 1: number represents the number of days returned\n" + " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" + "\n" + "5. \"Count:\" (numeric, optional, default=9999999) \n" + " Last n number of transactions returned\n" + "\n" + "Default Parameters:\n" + "2. 0 - O confimations required\n" + "3. 0 - Returns all transactions\n" + "4. 9999999 - Ignored\n" + "5. 9999999 - Return the last 9,999,999 transactions.\n" + "\n" + "\nResult:\n" + " \"txid\": \"transactionid\", (string) The transaction id.\n" + " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" + " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" + " \"blockindex\": n, (numeric) The block index containing the transaction\n" + " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" + " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" + " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" + " \"size\": xxx, (numeric) The transaction size\n" + " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" + " \"sends\": { A list of outputs of where funds were sent to in the transaction,\n" + " only available if the transaction has valid sends (inputs) belonging to the wallet\n" + " \"transparentSends\": [{ An Array of spends (outputs) for transparent addresses of the receipient\n" + " \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n" + " \"scriptPubKey\": \"script\", (string) Script for the Hush transparent address (t-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being sent " + CURRENCY_UNIT + ", negative for sends\n" + " \"vout\": : n, (numeric) the vout value\n" + " }],\n" + " \"saplingSends\": [{ An Array of spends (outputs) for sapling addresses\n" + " \"address\": \"hushaddress\", (string) Hush sapling address (z-address) of the receipient\n" + " \"amount\": x.xxxx, (numeric) Value of output being sent" + CURRENCY_UNIT + ", negative for sends\n" + " \"memo\": xxxxx, (string) hexademical string representation of memo field\n" + " \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n" + " \"shieldedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" + " \"change\": true/false (string) The note is change. This can result from sending funds\n" + " to the same address they came from, or incomplete useage\n" + " resulting in the remainder of the note used being sent back to the\n" + " same z-address.\n" + " }],\n" + " \"missingSaplingOVK\": true/false (string) True if the sapling outputs are not decryptable\n" + " }\n" + "\nExamples:\n" + + HelpExampleCli("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") + + HelpExampleRpc("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue ret(UniValue::VARR); + + //param values` + int64_t nMinConfirms = 0; + int64_t nFilterType = 0; + int64_t nFilter = 9999999; + int64_t nCount = 9999999; + + if (params.size() >= 2) + nMinConfirms = params[1].get_int64(); + + if (params.size() >= 4) { + nFilterType = params[2].get_int64(); + nFilter = params[3].get_int64(); + } + + if (params.size() == 5) { + nCount = params[4].get_int64(); + } + + if (nMinConfirms < 0) + throw runtime_error("Minimum confimations must be greater that 0"); + + if (nFilterType < 0 || nFilterType > 2) + throw runtime_error("Filter type must be 0, 1 or 2."); + + if (nFilter < 0) + throw runtime_error("Filter must be greater that 0."); + + //Created Ordered Transaction Map + map orderedTxs; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + const CWalletTx& wtx = (*it).second; + orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); + } + + + uint64_t t = GetTime(); + //Reverse Iterate thru transactions + for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { + const CWalletTx& wtx = (*it).second; + + if (!CheckFinalTx(wtx)) + continue; + + if (wtx.GetDepthInMainChain() < 0) + continue; + + if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted()) + continue; + + //Excude transactions with less confirmations than required + if (wtx.GetDepthInMainChain() < nMinConfirms) + continue; + + //Exclude Transactions older that max days old + if (wtx.GetDepthInMainChain() > 0 && nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) + continue; + + //Exclude transactions with greater than max confirmations + if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter) + continue; + + zsWalletTxJSON(wtx, ret, "*", false, 0); + + + if (ret.size() >= nCount) break; + } + + vector arrTmp = ret.getValues(); + + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); + + return ret; +} + +static const CRPCCommand commands[] = +{ // category name actor (function) okSafeMode + // --------------------- ------------------------ ----------------------- ---------- + { "Hush Exclusive", "z_listsentbyaddress", &z_listsentbyaddress, true }, +}; + +void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/wallet/rpchushwallet.h b/src/wallet/rpchushwallet.h new file mode 100644 index 000000000..2276f3f8b --- /dev/null +++ b/src/wallet/rpchushwallet.h @@ -0,0 +1,29 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_WALLET_RPCHUSHWALLET_H +#define BITCOIN_WALLET_RPCHUSHWALLET_H + +struct balancestruct { + CAmount confirmed; + CAmount unconfirmed; + CAmount locked; + CAmount immature; +}; + +void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpends, CAmount& filteredSpends, const std::string& strAddress, bool filterByAddress); +void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress); +void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress); +void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType); + + +class CRPCTable; + +void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC); + + + + + +#endif //BITCOIN_WALLET_RPCWALLET_H \ No newline at end of file From 49872e5fd750493d9fcdd32e1d5250c1d9349b20 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 25 Feb 2020 15:47:18 +0100 Subject: [PATCH 021/220] cleanup unnecessary lines --- src/wallet/rpchushwallet.cpp | 118 ++--------------------------------- src/wallet/rpchushwallet.h | 1 - 2 files changed, 5 insertions(+), 114 deletions(-) diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index 89b5b5dcc..e45ba71e7 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -131,104 +131,6 @@ void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpen } } - -void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress) { - - LOCK2(cs_main, pwalletMain->cs_wallet); - - //Check address - bool isTAddress = false; - bool isZsAddress = false; - - CTxDestination tAddress = DecodeDestination(strAddress); - auto zAddress = DecodePaymentAddress(strAddress); - SaplingPaymentAddress zsAddress; - - if (filterByAddress) { - - if (IsValidDestination(tAddress)) - isTAddress = true; - - if (IsValidPaymentAddress(zAddress)) { - if (boost::get(&zAddress) != nullptr) { - zsAddress = boost::get(zAddress); - isZsAddress = true; - } - } - } - - - //Transparent Received txos belonging to the wallet - UniValue tReceived(UniValue::VARR); - if (isTAddress || !filterByAddress) { - for (int i = 0; i < wtx.vout.size(); i++) { - const CTxOut& txout = wtx.vout[i]; - UniValue obj(UniValue::VOBJ); - CTxDestination address; - ExtractDestination(txout.scriptPubKey, address); - if(IsMine(*pwalletMain, address)){ - obj.push_back(Pair("address",EncodeDestination(address))); - obj.push_back(Pair("scriptPubKey",HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end()))); - obj.push_back(Pair("amount",ValueFromAmount(txout.nValue))); - obj.push_back(Pair("vout", i)); - if (address == tAddress || !filterByAddress) { - totalReceived += CAmount(txout.nValue); - tReceived.push_back(obj); - } - } - } - } - received.push_back(Pair("transparentReceived",tReceived)); - - - //Sapling Sends belonging to the wallet - UniValue zsReceived(UniValue::VARR); - if (isZsAddress || !filterByAddress) { - for (int i = 0; i < wtx.vShieldedOutput.size(); i++) { - const OutputDescription& outputDesc = wtx.vShieldedOutput[i]; - UniValue obj(UniValue::VOBJ); - bool changeTx = false; - //Decrypt sapling incoming commitments using IVK - std::set addresses; - pwalletMain->GetSaplingPaymentAddresses(addresses); - for (auto addr : addresses) { - libzcash::SaplingExtendedSpendingKey extsk; - if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { - auto pt = libzcash::SaplingNotePlaintext::decrypt( - outputDesc.encCiphertext, extsk.expsk.full_viewing_key().in_viewing_key(), outputDesc.ephemeralKey, outputDesc.cm); - - if (pt) { - auto note = pt.get(); - obj.push_back(Pair("address",EncodePaymentAddress(addr))); - obj.push_back(Pair("amount", ValueFromAmount(CAmount(note.value())))); - obj.push_back(Pair("shieldedOutputIndex",i)); - - //Check Change Status - if (wtx.vShieldedSpend.size()!=0) { - std::set> nullifierSet; - nullifierSet = pwalletMain->GetNullifiersForAddresses({addr}); - BOOST_FOREACH(const SpendDescription& spendDesc, wtx.vShieldedSpend) { - if (nullifierSet.count(std::make_pair(addr, spendDesc.nullifier))) { - changeTx = true; - } - } - } - obj.push_back(Pair("change",changeTx)); - if (addr == zsAddress || !filterByAddress) { - totalReceived += CAmount(note.value()); - zsReceived.push_back(obj); - } - } - } - } - } - } - received.push_back(Pair("saplingReceived",zsReceived)); - - received.push_back(Pair("totalReceived",ValueFromAmount(totalReceived))); -} - - void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -371,7 +273,7 @@ void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, } } } - sends.push_back(Pair("saplingSends",zsSends)); + sends.push_back(Pair("saplingSends",zsSends)); if (shieldedOutputCount != shieldedOutputDecryptedCount) { sends.push_back(Pair("missingSaplingOVK", true)); @@ -382,7 +284,6 @@ void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, sends.push_back(Pair("totalSends",ValueFromAmount(totalSends))); } - void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -448,14 +349,8 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd if ((!fBool || filteredSpends != 0) && (returnType == 0 || returnType == 1)) { tx.push_back(Pair("spends",spends)); } - } - // Get Received - if (returnType == 0 || returnType == 2) { - zsTxReceivedToJSON(wtx, received, totalReceived, strAddress, fBool); - if (!fBool || totalReceived != 0) { - tx.push_back(Pair("received",received)); - } - } + } + // Get Sends if (returnType == 0 || returnType == 3) { @@ -468,13 +363,11 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd } } - if ((returnType == 0 && (!fBool || filteredSpends != 0 || totalReceived != 0 || totalSends != 0)) + if ((returnType == 0 && (!fBool || filteredSpends != 0 || totalSends != 0)) || (returnType == 1 && (!fBool || filteredSpends != 0)) - || (returnType == 2 && (!fBool || totalReceived != 0)) - || (returnType == 3 && (!fBool || totalSends != 0))) { + || (returnType == 2 && (!fBool || totalSends != 0))) { ret.push_back(tx); } - } UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { @@ -617,7 +510,6 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) zsWalletTxJSON(wtx, ret, "*", false, 0); - if (ret.size() >= nCount) break; } diff --git a/src/wallet/rpchushwallet.h b/src/wallet/rpchushwallet.h index 2276f3f8b..3e8d942d1 100644 --- a/src/wallet/rpchushwallet.h +++ b/src/wallet/rpchushwallet.h @@ -13,7 +13,6 @@ struct balancestruct { }; void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpends, CAmount& filteredSpends, const std::string& strAddress, bool filterByAddress); -void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress); void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress); void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType); From 3b4e5d727c72b058b25db1fbb1d98e2b88827bc7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 25 Feb 2020 23:49:16 -0500 Subject: [PATCH 022/220] Revert "cleanup unnecessary lines" This reverts commit 49872e5fd750493d9fcdd32e1d5250c1d9349b20. --- src/wallet/rpchushwallet.cpp | 118 +++++++++++++++++++++++++++++++++-- src/wallet/rpchushwallet.h | 1 + 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index e45ba71e7..89b5b5dcc 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -131,6 +131,104 @@ void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpen } } + +void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress) { + + LOCK2(cs_main, pwalletMain->cs_wallet); + + //Check address + bool isTAddress = false; + bool isZsAddress = false; + + CTxDestination tAddress = DecodeDestination(strAddress); + auto zAddress = DecodePaymentAddress(strAddress); + SaplingPaymentAddress zsAddress; + + if (filterByAddress) { + + if (IsValidDestination(tAddress)) + isTAddress = true; + + if (IsValidPaymentAddress(zAddress)) { + if (boost::get(&zAddress) != nullptr) { + zsAddress = boost::get(zAddress); + isZsAddress = true; + } + } + } + + + //Transparent Received txos belonging to the wallet + UniValue tReceived(UniValue::VARR); + if (isTAddress || !filterByAddress) { + for (int i = 0; i < wtx.vout.size(); i++) { + const CTxOut& txout = wtx.vout[i]; + UniValue obj(UniValue::VOBJ); + CTxDestination address; + ExtractDestination(txout.scriptPubKey, address); + if(IsMine(*pwalletMain, address)){ + obj.push_back(Pair("address",EncodeDestination(address))); + obj.push_back(Pair("scriptPubKey",HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end()))); + obj.push_back(Pair("amount",ValueFromAmount(txout.nValue))); + obj.push_back(Pair("vout", i)); + if (address == tAddress || !filterByAddress) { + totalReceived += CAmount(txout.nValue); + tReceived.push_back(obj); + } + } + } + } + received.push_back(Pair("transparentReceived",tReceived)); + + + //Sapling Sends belonging to the wallet + UniValue zsReceived(UniValue::VARR); + if (isZsAddress || !filterByAddress) { + for (int i = 0; i < wtx.vShieldedOutput.size(); i++) { + const OutputDescription& outputDesc = wtx.vShieldedOutput[i]; + UniValue obj(UniValue::VOBJ); + bool changeTx = false; + //Decrypt sapling incoming commitments using IVK + std::set addresses; + pwalletMain->GetSaplingPaymentAddresses(addresses); + for (auto addr : addresses) { + libzcash::SaplingExtendedSpendingKey extsk; + if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + auto pt = libzcash::SaplingNotePlaintext::decrypt( + outputDesc.encCiphertext, extsk.expsk.full_viewing_key().in_viewing_key(), outputDesc.ephemeralKey, outputDesc.cm); + + if (pt) { + auto note = pt.get(); + obj.push_back(Pair("address",EncodePaymentAddress(addr))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(note.value())))); + obj.push_back(Pair("shieldedOutputIndex",i)); + + //Check Change Status + if (wtx.vShieldedSpend.size()!=0) { + std::set> nullifierSet; + nullifierSet = pwalletMain->GetNullifiersForAddresses({addr}); + BOOST_FOREACH(const SpendDescription& spendDesc, wtx.vShieldedSpend) { + if (nullifierSet.count(std::make_pair(addr, spendDesc.nullifier))) { + changeTx = true; + } + } + } + obj.push_back(Pair("change",changeTx)); + if (addr == zsAddress || !filterByAddress) { + totalReceived += CAmount(note.value()); + zsReceived.push_back(obj); + } + } + } + } + } + } + received.push_back(Pair("saplingReceived",zsReceived)); + + received.push_back(Pair("totalReceived",ValueFromAmount(totalReceived))); +} + + void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -273,7 +371,7 @@ void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, } } } - sends.push_back(Pair("saplingSends",zsSends)); + sends.push_back(Pair("saplingSends",zsSends)); if (shieldedOutputCount != shieldedOutputDecryptedCount) { sends.push_back(Pair("missingSaplingOVK", true)); @@ -284,6 +382,7 @@ void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, sends.push_back(Pair("totalSends",ValueFromAmount(totalSends))); } + void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -349,8 +448,14 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd if ((!fBool || filteredSpends != 0) && (returnType == 0 || returnType == 1)) { tx.push_back(Pair("spends",spends)); } - } - + } + // Get Received + if (returnType == 0 || returnType == 2) { + zsTxReceivedToJSON(wtx, received, totalReceived, strAddress, fBool); + if (!fBool || totalReceived != 0) { + tx.push_back(Pair("received",received)); + } + } // Get Sends if (returnType == 0 || returnType == 3) { @@ -363,11 +468,13 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd } } - if ((returnType == 0 && (!fBool || filteredSpends != 0 || totalSends != 0)) + if ((returnType == 0 && (!fBool || filteredSpends != 0 || totalReceived != 0 || totalSends != 0)) || (returnType == 1 && (!fBool || filteredSpends != 0)) - || (returnType == 2 && (!fBool || totalSends != 0))) { + || (returnType == 2 && (!fBool || totalReceived != 0)) + || (returnType == 3 && (!fBool || totalSends != 0))) { ret.push_back(tx); } + } UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { @@ -510,6 +617,7 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) zsWalletTxJSON(wtx, ret, "*", false, 0); + if (ret.size() >= nCount) break; } diff --git a/src/wallet/rpchushwallet.h b/src/wallet/rpchushwallet.h index 3e8d942d1..2276f3f8b 100644 --- a/src/wallet/rpchushwallet.h +++ b/src/wallet/rpchushwallet.h @@ -13,6 +13,7 @@ struct balancestruct { }; void zsTxSpendsToJSON(const CWalletTx& wtx, UniValue& spends, CAmount& totalSpends, CAmount& filteredSpends, const std::string& strAddress, bool filterByAddress); +void zsTxReceivedToJSON(const CWalletTx& wtx, UniValue& received, CAmount& totalReceived, const std::string& strAddress, bool filterByAddress); void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, const std::string& strAddress, bool filterByAddress); void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType); From a338a974c798a63d04e5124ff9173f7d59086dba Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 25 Feb 2020 23:49:49 -0500 Subject: [PATCH 023/220] Add z_listreceivedbyaddress from ZER --- src/wallet/rpchushwallet.cpp | 153 ++++++++++++++++++++++++++++++++--- src/wallet/rpcwallet.cpp | 2 + 2 files changed, 143 insertions(+), 12 deletions(-) diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index 89b5b5dcc..33eeca6b3 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -477,6 +477,147 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd } +UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 5 || params.size() == 3) + throw runtime_error( + "z_listreceivedbyaddress\n" + "\nReturns received outputs for a single address.\n" + "\n" + "This function only returns information on addresses with full spending keys." + "\n" + "\nArguments:\n" + "1. \"zeroaddress:\" (string, required) \n" + "\n" + "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" + "\n" + "3. \"Filter Type:\" (numeric, optional, default=0) \n" + " Value of 0: Returns all transactions in the wallet\n" + " Value of 1: Returns the last x days of transactions\n" + " Value of 2: Returns transactions with confimations less than x\n" + "\n" + "4. \"Filter:\" (numeric, optional, default=999999) \n" + " Filter Type equal 0: paramater ignored\n" + " Filter Type equal 1: number represents the number of days returned\n" + " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" + "\n" + "5. \"Count:\" (numeric, optional, default=9999999) \n" + " Last n number of transactions returned\n" + "\n" + "Default Parameters:\n" + "2. 0 - O confimations required\n" + "3. 0 - Returns all transactions\n" + "4. 9999999 - Ignored\n" + "5. 9999999 - Return the last 9,999,999 transactions.\n" + "\n" + "\nResult:\n" + " \"txid\": \"transactionid\", (string) The transaction id.\n" + " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" + " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" + " \"blockindex\": n, (numeric) The block index containing the transaction\n" + " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" + " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" + " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" + " \"size\": xxx, (numeric) The transaction size\n" + " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" + " \"recieved\": { A list of receives from the transaction\n" + " \"transparentReceived\": [{ An Array of txos received for transparent addresses\n" + " \"address\": \"zeroaddress\", (string) Hush transparent address (t-address)\n" + " \"scriptPubKey\": \"script\", (string) Script for the Zero transparent address (t-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" + " \"vout\": : n, (numeric) the vout value\n" + " }],\n" + " \"saplingReceived\": [{ An Array of utxos/notes received for sapling addresses\n" + " \"address\": \"zeroaddress\", (string) Shielded address (z-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" + " \"sheildedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" + " \"change\": true/false (string) The note is change. This can result from sending funds\n" + " to the same address they came from, or incomplete useage\n" + " resulting in the remainder of the note used being sent back to the\n" + " same z-address.\n" + " }],\n" + " },\n" + "\nExamples:\n" + + HelpExampleCli("z_listreceivedbyaddress", "R...") + + HelpExampleRpc("z_listreceivedbyaddress", "R...") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue ret(UniValue::VARR); + + //param values` + int64_t nMinConfirms = 0; + int64_t nFilterType = 0; + int64_t nFilter = 999999; + int64_t nCount = 9999999; + + if (params.size() >= 2) + nMinConfirms = params[1].get_int64(); + + if (params.size() >= 4) { + nFilterType = params[2].get_int64(); + nFilter = params[3].get_int64(); + } + + if (params.size() == 5) { + nCount = params[4].get_int64(); + } + + if (nMinConfirms < 0) + throw runtime_error("Minimum confimations must be greater that 0"); + + if (nFilterType < 0 || nFilterType > 2) + throw runtime_error("Filter type must be 0, 1 or 2."); + + if (nFilter < 0) + throw runtime_error("Filter must be greater that 0."); + + //Created Ordered Transaction Map + map orderedTxs; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + const CWalletTx& wtx = (*it).second; + orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); + } + + + uint64_t t = GetTime(); + //Reverse Iterate thru transactions + for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { + const CWalletTx& wtx = (*it).second; + bool includeTransaction = true; + + //Excude transactions with less confirmations than required + if (wtx.GetDepthInMainChain() < nMinConfirms) { + includeTransaction = false; + } + + //Exclude Transactions older that max days old + if (wtx.GetDepthInMainChain() > 0) { + if (nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) { + includeTransaction = false; + } + } + + //Exclude transactions with greater than max confirmations + if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter){ + includeTransaction = false; + } + + if (includeTransaction) { + zsWalletTxJSON(wtx, ret, params[0].get_str() , true, 2); + } + + if (ret.size() > nCount) break; + } + + return ret; +} + UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -631,15 +772,3 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) return ret; } - -static const CRPCCommand commands[] = -{ // category name actor (function) okSafeMode - // --------------------- ------------------------ ----------------------- ---------- - { "Hush Exclusive", "z_listsentbyaddress", &z_listsentbyaddress, true }, -}; - -void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC) -{ - for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) - tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); -} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 88cfbe504..bf8de6812 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8181,6 +8181,8 @@ static const CRPCCommand commands[] = { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, { "wallet", "z_viewtransaction", &z_viewtransaction, true }, + { "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true }, + { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true }, // TODO: rearrange into another category { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } From b06bd5720aea7f08846e18781ae1429fa2ad68cd Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 26 Feb 2020 00:20:02 -0500 Subject: [PATCH 024/220] Add z_listreceivedbyaddress from ZER and refactor some stuff --- src/rpc/register.h | 3 - src/wallet/rpchushwallet.cpp | 296 --------------------------------- src/wallet/rpchushwallet.h | 11 +- src/wallet/rpcwallet.cpp | 306 +++++++++++++++++++++++++++++++++++ 4 files changed, 308 insertions(+), 308 deletions(-) diff --git a/src/rpc/register.h b/src/rpc/register.h index 725ed7550..245f76e22 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -34,8 +34,6 @@ void RegisterMiscRPCCommands(CRPCTable &tableRPC); void RegisterMiningRPCCommands(CRPCTable &tableRPC); /** Register raw transaction RPC commands */ void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC); -/** Register Experimental RPC commands */ -void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC); /** Register test transaction RPC commands */ void RegisterTesttransactionsRPCCommands(CRPCTable &tableRPC); @@ -48,7 +46,6 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &tableRPC) RegisterMiscRPCCommands(tableRPC); RegisterMiningRPCCommands(tableRPC); RegisterRawTransactionRPCCommands(tableRPC); - RegisterHushExclusiveRPCCommands(tableRPC); #ifdef TESTMODE RegisterTesttransactionsRPCCommands(tableRPC); #endif diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index 33eeca6b3..62b7a4fc9 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -476,299 +476,3 @@ void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAd } } - -UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - if (fHelp || params.size() > 5 || params.size() == 3) - throw runtime_error( - "z_listreceivedbyaddress\n" - "\nReturns received outputs for a single address.\n" - "\n" - "This function only returns information on addresses with full spending keys." - "\n" - "\nArguments:\n" - "1. \"zeroaddress:\" (string, required) \n" - "\n" - "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" - "\n" - "3. \"Filter Type:\" (numeric, optional, default=0) \n" - " Value of 0: Returns all transactions in the wallet\n" - " Value of 1: Returns the last x days of transactions\n" - " Value of 2: Returns transactions with confimations less than x\n" - "\n" - "4. \"Filter:\" (numeric, optional, default=999999) \n" - " Filter Type equal 0: paramater ignored\n" - " Filter Type equal 1: number represents the number of days returned\n" - " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" - "\n" - "5. \"Count:\" (numeric, optional, default=9999999) \n" - " Last n number of transactions returned\n" - "\n" - "Default Parameters:\n" - "2. 0 - O confimations required\n" - "3. 0 - Returns all transactions\n" - "4. 9999999 - Ignored\n" - "5. 9999999 - Return the last 9,999,999 transactions.\n" - "\n" - "\nResult:\n" - " \"txid\": \"transactionid\", (string) The transaction id.\n" - " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" - " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" - " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" - " \"blockindex\": n, (numeric) The block index containing the transaction\n" - " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" - " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" - " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" - " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" - " \"size\": xxx, (numeric) The transaction size\n" - " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" - " \"recieved\": { A list of receives from the transaction\n" - " \"transparentReceived\": [{ An Array of txos received for transparent addresses\n" - " \"address\": \"zeroaddress\", (string) Hush transparent address (t-address)\n" - " \"scriptPubKey\": \"script\", (string) Script for the Zero transparent address (t-address)\n" - " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" - " \"vout\": : n, (numeric) the vout value\n" - " }],\n" - " \"saplingReceived\": [{ An Array of utxos/notes received for sapling addresses\n" - " \"address\": \"zeroaddress\", (string) Shielded address (z-address)\n" - " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" - " \"sheildedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" - " \"change\": true/false (string) The note is change. This can result from sending funds\n" - " to the same address they came from, or incomplete useage\n" - " resulting in the remainder of the note used being sent back to the\n" - " same z-address.\n" - " }],\n" - " },\n" - "\nExamples:\n" - + HelpExampleCli("z_listreceivedbyaddress", "R...") - + HelpExampleRpc("z_listreceivedbyaddress", "R...") - ); - - LOCK2(cs_main, pwalletMain->cs_wallet); - - UniValue ret(UniValue::VARR); - - //param values` - int64_t nMinConfirms = 0; - int64_t nFilterType = 0; - int64_t nFilter = 999999; - int64_t nCount = 9999999; - - if (params.size() >= 2) - nMinConfirms = params[1].get_int64(); - - if (params.size() >= 4) { - nFilterType = params[2].get_int64(); - nFilter = params[3].get_int64(); - } - - if (params.size() == 5) { - nCount = params[4].get_int64(); - } - - if (nMinConfirms < 0) - throw runtime_error("Minimum confimations must be greater that 0"); - - if (nFilterType < 0 || nFilterType > 2) - throw runtime_error("Filter type must be 0, 1 or 2."); - - if (nFilter < 0) - throw runtime_error("Filter must be greater that 0."); - - //Created Ordered Transaction Map - map orderedTxs; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - const CWalletTx& wtx = (*it).second; - orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); - } - - - uint64_t t = GetTime(); - //Reverse Iterate thru transactions - for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { - const CWalletTx& wtx = (*it).second; - bool includeTransaction = true; - - //Excude transactions with less confirmations than required - if (wtx.GetDepthInMainChain() < nMinConfirms) { - includeTransaction = false; - } - - //Exclude Transactions older that max days old - if (wtx.GetDepthInMainChain() > 0) { - if (nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) { - includeTransaction = false; - } - } - - //Exclude transactions with greater than max confirmations - if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter){ - includeTransaction = false; - } - - if (includeTransaction) { - zsWalletTxJSON(wtx, ret, params[0].get_str() , true, 2); - } - - if (ret.size() > nCount) break; - } - - return ret; -} - -UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - if (fHelp || params.size() > 5 || params.size() == 3) - throw runtime_error( - "z_listsentbyaddress\n" - "\nReturns decrypted Hush outputs sent to a single address.\n" - "\n" - "This function only returns information on addresses sent from wallet addresses with full spending keys." - "\n" - "\nArguments:\n" - "1. \"hushaddress:\" (string, required) \n" - "\n" - "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" - "\n" - "3. \"Filter Type:\" (numeric, optional, default=0) \n" - " Value of 0: Returns all transactions in the wallet\n" - " Value of 1: Returns the last x days of transactions\n" - " Value of 2: Returns transactions with confimations less than x\n" - "\n" - "4. \"Filter:\" (numeric, optional, default=999999) \n" - " Filter Type equal 0: paramater ignored\n" - " Filter Type equal 1: number represents the number of days returned\n" - " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" - "\n" - "5. \"Count:\" (numeric, optional, default=9999999) \n" - " Last n number of transactions returned\n" - "\n" - "Default Parameters:\n" - "2. 0 - O confimations required\n" - "3. 0 - Returns all transactions\n" - "4. 9999999 - Ignored\n" - "5. 9999999 - Return the last 9,999,999 transactions.\n" - "\n" - "\nResult:\n" - " \"txid\": \"transactionid\", (string) The transaction id.\n" - " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" - " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" - " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" - " \"blockindex\": n, (numeric) The block index containing the transaction\n" - " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" - " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" - " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" - " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" - " \"size\": xxx, (numeric) The transaction size\n" - " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" - " \"sends\": { A list of outputs of where funds were sent to in the transaction,\n" - " only available if the transaction has valid sends (inputs) belonging to the wallet\n" - " \"transparentSends\": [{ An Array of spends (outputs) for transparent addresses of the receipient\n" - " \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n" - " \"scriptPubKey\": \"script\", (string) Script for the Hush transparent address (t-address)\n" - " \"amount\": x.xxxx, (numeric) Value of output being sent " + CURRENCY_UNIT + ", negative for sends\n" - " \"vout\": : n, (numeric) the vout value\n" - " }],\n" - " \"saplingSends\": [{ An Array of spends (outputs) for sapling addresses\n" - " \"address\": \"hushaddress\", (string) Hush sapling address (z-address) of the receipient\n" - " \"amount\": x.xxxx, (numeric) Value of output being sent" + CURRENCY_UNIT + ", negative for sends\n" - " \"memo\": xxxxx, (string) hexademical string representation of memo field\n" - " \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n" - " \"shieldedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" - " \"change\": true/false (string) The note is change. This can result from sending funds\n" - " to the same address they came from, or incomplete useage\n" - " resulting in the remainder of the note used being sent back to the\n" - " same z-address.\n" - " }],\n" - " \"missingSaplingOVK\": true/false (string) True if the sapling outputs are not decryptable\n" - " }\n" - "\nExamples:\n" - + HelpExampleCli("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") - + HelpExampleRpc("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") - ); - - LOCK2(cs_main, pwalletMain->cs_wallet); - - UniValue ret(UniValue::VARR); - - //param values` - int64_t nMinConfirms = 0; - int64_t nFilterType = 0; - int64_t nFilter = 9999999; - int64_t nCount = 9999999; - - if (params.size() >= 2) - nMinConfirms = params[1].get_int64(); - - if (params.size() >= 4) { - nFilterType = params[2].get_int64(); - nFilter = params[3].get_int64(); - } - - if (params.size() == 5) { - nCount = params[4].get_int64(); - } - - if (nMinConfirms < 0) - throw runtime_error("Minimum confimations must be greater that 0"); - - if (nFilterType < 0 || nFilterType > 2) - throw runtime_error("Filter type must be 0, 1 or 2."); - - if (nFilter < 0) - throw runtime_error("Filter must be greater that 0."); - - //Created Ordered Transaction Map - map orderedTxs; - for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - const CWalletTx& wtx = (*it).second; - orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); - } - - - uint64_t t = GetTime(); - //Reverse Iterate thru transactions - for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { - const CWalletTx& wtx = (*it).second; - - if (!CheckFinalTx(wtx)) - continue; - - if (wtx.GetDepthInMainChain() < 0) - continue; - - if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted()) - continue; - - //Excude transactions with less confirmations than required - if (wtx.GetDepthInMainChain() < nMinConfirms) - continue; - - //Exclude Transactions older that max days old - if (wtx.GetDepthInMainChain() > 0 && nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) - continue; - - //Exclude transactions with greater than max confirmations - if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter) - continue; - - zsWalletTxJSON(wtx, ret, "*", false, 0); - - - if (ret.size() >= nCount) break; - } - - vector arrTmp = ret.getValues(); - - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - ret.clear(); - ret.setArray(); - ret.push_backV(arrTmp); - - return ret; -} diff --git a/src/wallet/rpchushwallet.h b/src/wallet/rpchushwallet.h index 2276f3f8b..b9a6d6f6f 100644 --- a/src/wallet/rpchushwallet.h +++ b/src/wallet/rpchushwallet.h @@ -1,3 +1,4 @@ +// Copyright (c) 2020 The Hush developers // Copyright (c) 2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,12 +19,4 @@ void zsTxSendsToJSON(const CWalletTx& wtx, UniValue& sends, CAmount& totalSends, void zsWalletTxJSON(const CWalletTx& wtx, UniValue& ret, const std::string strAddress, bool fBool, const int returnType); -class CRPCTable; - -void RegisterHushExclusiveRPCCommands(CRPCTable &tableRPC); - - - - - -#endif //BITCOIN_WALLET_RPCWALLET_H \ No newline at end of file +#endif //BITCOIN_WALLET_RPCWALLET_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bf8de6812..78b1c612a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -63,6 +63,7 @@ #include "komodo_defs.h" #include #include "sietch.h" +#include "rpchushwallet.h" using namespace std; @@ -3025,6 +3026,301 @@ uint64_t komodo_interestsum() return(0); } +UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 5 || params.size() == 3) + throw runtime_error( + "z_listreceivedbyaddress\n" + "\nReturns received outputs for a single address.\n" + "\n" + "This function only returns information on addresses with full spending keys." + "\n" + "\nArguments:\n" + "1. \"hushaddress:\" (string, required) \n" + "\n" + "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" + "\n" + "3. \"Filter Type:\" (numeric, optional, default=0) \n" + " Value of 0: Returns all transactions in the wallet\n" + " Value of 1: Returns the last x days of transactions\n" + " Value of 2: Returns transactions with confimations less than x\n" + "\n" + "4. \"Filter:\" (numeric, optional, default=999999) \n" + " Filter Type equal 0: paramater ignored\n" + " Filter Type equal 1: number represents the number of days returned\n" + " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" + "\n" + "5. \"Count:\" (numeric, optional, default=9999999) \n" + " Last n number of transactions returned\n" + "\n" + "Default Parameters:\n" + "2. 0 - O confimations required\n" + "3. 0 - Returns all transactions\n" + "4. 9999999 - Ignored\n" + "5. 9999999 - Return the last 9,999,999 transactions.\n" + "\n" + "\nResult:\n" + " \"txid\": \"transactionid\", (string) The transaction id.\n" + " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" + " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" + " \"blockindex\": n, (numeric) The block index containing the transaction\n" + " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" + " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" + " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" + " \"size\": xxx, (numeric) The transaction size\n" + " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" + " \"recieved\": { A list of receives from the transaction\n" + " \"transparentReceived\": [{ An Array of txos received for transparent addresses\n" + " \"address\": \"zeroaddress\", (string) Hush transparent address (t-address)\n" + " \"scriptPubKey\": \"script\", (string) Script for the transparent address (t-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" + " \"vout\": : n, (numeric) the vout value\n" + " }],\n" + " \"saplingReceived\": [{ An Array of utxos/notes received for sapling addresses\n" + " \"address\": \"zeroaddress\", (string) Shielded address (z-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being received " + CURRENCY_UNIT + ", positive for receives\n" + " \"sheildedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" + " \"change\": true/false (string) The note is change. This can result from sending funds\n" + " to the same address they came from, or incomplete useage\n" + " resulting in the remainder of the note used being sent back to the\n" + " same z-address.\n" + " }],\n" + " },\n" + "\nExamples:\n" + + HelpExampleCli("z_listreceivedbyaddress", "R...") + + HelpExampleRpc("z_listreceivedbyaddress", "R...") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue ret(UniValue::VARR); + + //param values` + int64_t nMinConfirms = 0; + int64_t nFilterType = 0; + int64_t nFilter = 999999; + int64_t nCount = 9999999; + + if (params.size() >= 2) + nMinConfirms = params[1].get_int64(); + + if (params.size() >= 4) { + nFilterType = params[2].get_int64(); + nFilter = params[3].get_int64(); + } + + if (params.size() == 5) { + nCount = params[4].get_int64(); + } + + if (nMinConfirms < 0) + throw runtime_error("Minimum confimations must be greater that 0"); + + if (nFilterType < 0 || nFilterType > 2) + throw runtime_error("Filter type must be 0, 1 or 2."); + + if (nFilter < 0) + throw runtime_error("Filter must be greater that 0."); + + //Created Ordered Transaction Map + map orderedTxs; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + const CWalletTx& wtx = (*it).second; + orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); + } + + + uint64_t t = GetTime(); + //Reverse Iterate thru transactions + for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { + const CWalletTx& wtx = (*it).second; + bool includeTransaction = true; + + //Excude transactions with less confirmations than required + if (wtx.GetDepthInMainChain() < nMinConfirms) { + includeTransaction = false; + } + + //Exclude Transactions older that max days old + if (wtx.GetDepthInMainChain() > 0) { + if (nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) { + includeTransaction = false; + } + } + + //Exclude transactions with greater than max confirmations + if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter){ + includeTransaction = false; + } + + if (includeTransaction) { + zsWalletTxJSON(wtx, ret, params[0].get_str() , true, 2); + } + + if (ret.size() > nCount) break; + } + + return ret; +} + +UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 5 || params.size() == 3) + throw runtime_error( + "z_listsentbyaddress\n" + "\nReturns decrypted Hush outputs sent to a single address.\n" + "\n" + "This function only returns information on addresses sent from wallet addresses with full spending keys." + "\n" + "\nArguments:\n" + "1. \"hushaddress:\" (string, required) \n" + "\n" + "2. \"Minimum Confimations:\" (numeric, optional, default=0) \n" + "\n" + "3. \"Filter Type:\" (numeric, optional, default=0) \n" + " Value of 0: Returns all transactions in the wallet\n" + " Value of 1: Returns the last x days of transactions\n" + " Value of 2: Returns transactions with confimations less than x\n" + "\n" + "4. \"Filter:\" (numeric, optional, default=999999) \n" + " Filter Type equal 0: paramater ignored\n" + " Filter Type equal 1: number represents the number of days returned\n" + " Filter Type equal 2: number represents the max confirmations for transaction to be returned\n" + "\n" + "5. \"Count:\" (numeric, optional, default=9999999) \n" + " Last n number of transactions returned\n" + "\n" + "Default Parameters:\n" + "2. 0 - O confimations required\n" + "3. 0 - Returns all transactions\n" + "4. 9999999 - Ignored\n" + "5. 9999999 - Return the last 9,999,999 transactions.\n" + "\n" + "\nResult:\n" + " \"txid\": \"transactionid\", (string) The transaction id.\n" + " \"coinbase\": \"coinbase\", (string) Coinbase transaction, true or false\n" + " \"category\": \"category\", (string) orphan (coinbase), immature (coinbase), generate (coinbase), regular\n" + " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction\n" + " \"blockindex\": n, (numeric) The block index containing the transaction\n" + " \"blocktime\": n, (numeric) The block time in seconds of the block containing the transaction, 0 for unconfirmed transactions\n" + " \"expiryheight\": n, (numeric) The expiry height of the transaction\n" + " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" + " \"time\": xxx, (numeric) The transaction time in seconds of the transaction\n" + " \"size\": xxx, (numeric) The transaction size\n" + " \"walletconflicts\": [conflicts], An array of wallet conflicts\n" + " \"sends\": { A list of outputs of where funds were sent to in the transaction,\n" + " only available if the transaction has valid sends (inputs) belonging to the wallet\n" + " \"transparentSends\": [{ An Array of spends (outputs) for transparent addresses of the receipient\n" + " \"address\": \"hushaddress\", (string) Hush transparent address (t-address)\n" + " \"scriptPubKey\": \"script\", (string) Script for the Hush transparent address (t-address)\n" + " \"amount\": x.xxxx, (numeric) Value of output being sent " + CURRENCY_UNIT + ", negative for sends\n" + " \"vout\": : n, (numeric) the vout value\n" + " }],\n" + " \"saplingSends\": [{ An Array of spends (outputs) for sapling addresses\n" + " \"address\": \"hushaddress\", (string) Hush sapling address (z-address) of the receipient\n" + " \"amount\": x.xxxx, (numeric) Value of output being sent" + CURRENCY_UNIT + ", negative for sends\n" + " \"memo\": xxxxx, (string) hexademical string representation of memo field\n" + " \"memoStr\" : \"memo\", (string) Only returned if memo contains valid UTF-8 text.\n" + " \"shieldedOutputIndex\": n, (numeric) The index of the ShieledOutput\n" + " \"change\": true/false (string) The note is change. This can result from sending funds\n" + " to the same address they came from, or incomplete useage\n" + " resulting in the remainder of the note used being sent back to the\n" + " same z-address.\n" + " }],\n" + " \"missingSaplingOVK\": true/false (string) True if the sapling outputs are not decryptable\n" + " }\n" + "\nExamples:\n" + + HelpExampleCli("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") + + HelpExampleRpc("z_listsentbyaddress", "t1KzZ5n2TPEGYXTZ3WYGL1AYEumEQaRoHaL") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + UniValue ret(UniValue::VARR); + + //param values` + int64_t nMinConfirms = 0; + int64_t nFilterType = 0; + int64_t nFilter = 9999999; + int64_t nCount = 9999999; + + if (params.size() >= 2) + nMinConfirms = params[1].get_int64(); + + if (params.size() >= 4) { + nFilterType = params[2].get_int64(); + nFilter = params[3].get_int64(); + } + + if (params.size() == 5) { + nCount = params[4].get_int64(); + } + + if (nMinConfirms < 0) + throw runtime_error("Minimum confimations must be greater that 0"); + + if (nFilterType < 0 || nFilterType > 2) + throw runtime_error("Filter type must be 0, 1 or 2."); + + if (nFilter < 0) + throw runtime_error("Filter must be greater that 0."); + + //Created Ordered Transaction Map + map orderedTxs; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + const CWalletTx& wtx = (*it).second; + orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); + } + + + uint64_t t = GetTime(); + //Reverse Iterate thru transactions + for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) { + const CWalletTx& wtx = (*it).second; + + if (!CheckFinalTx(wtx)) + continue; + + if (wtx.GetDepthInMainChain() < 0) + continue; + + if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted()) + continue; + + //Excude transactions with less confirmations than required + if (wtx.GetDepthInMainChain() < nMinConfirms) + continue; + + //Exclude Transactions older that max days old + if (wtx.GetDepthInMainChain() > 0 && nFilterType == 1 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (nFilter * 60 * 60 * 24))) + continue; + + //Exclude transactions with greater than max confirmations + if (nFilterType == 2 && wtx.GetDepthInMainChain() > nFilter) + continue; + + zsWalletTxJSON(wtx, ret, "*", false, 0); + + + if (ret.size() >= nCount) break; + } + + vector arrTmp = ret.getValues(); + + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); + + return ret; +} UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -3953,6 +4249,15 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK obj.push_back(Pair("txid", entry.op.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.note.value())))); obj.push_back(Pair("memo", HexStr(entry.memo))); + // give a string representation if valid utf8 + auto memo = entry.memo; + if (memo[0] <= 0xf4) { + auto end = std::find_if(memo.rbegin(), memo.rend(), [](unsigned char v) { return v != 0; }); + std::string memoStr(memo.begin(), end.base()); + if (utf8::is_valid(memoStr)) { + obj.push_back(Pair("memoStr", memoStr)); + } + } obj.push_back(Pair("outindex", (int)entry.op.n)); obj.push_back(Pair("rawconfirmations", entry.confirmations)); obj.push_back(Pair("confirmations", dpowconfs)); @@ -8188,6 +8493,7 @@ static const CRPCCommand commands[] = { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } }; + void RegisterWalletRPCCommands(CRPCTable &tableRPC) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) From 2152f4df6d873abea38dec39a1366204d1afb5c5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 26 Feb 2020 09:51:09 -0500 Subject: [PATCH 025/220] Port getalldata from ZER sans sproutness --- src/wallet/rpcwallet.cpp | 318 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 316 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 78b1c612a..1fb365c34 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3026,7 +3026,319 @@ uint64_t komodo_interestsum() return(0); } -UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { +/** + *Return current blockchain status, wallet balance, address balance and the last 200 transactions +**/ +UniValue getalldata(const UniValue& params, bool fHelp,const CPubKey&) +{ + if (fHelp || params.size() > 3) + throw runtime_error( + "getalldata \"datatype transactiontype \"\n" + "\n" + "This function only returns information on wallet addresses with full spending keys." + "\n" + "\nArguments:\n" + "1. \"datatype\" (integer, required) \n" + " Value of 0: Return address, balance, transactions and blockchain info\n" + " Value of 1: Return address, balance, blockchain info\n" + " Value of 2: Return transactions and blockchain info\n" + "2. \"transactiontype\" (integer, optional) \n" + " Value of 1: Return all transactions in the last 24 hours\n" + " Value of 2: Return all transactions in the last 7 days\n" + " Value of 3: Return all transactions in the last 30 days\n" + " Other number: Return all transactions in the last 24 hours\n" + "3. \"transactioncount\" (integer, optional) \n" + "\nResult:\n" + "\nExamples:\n" + + HelpExampleCli("getalldata", "0") + + HelpExampleRpc("getalldata", "0") + ); + + LOCK(cs_main); + + UniValue returnObj(UniValue::VOBJ); + int connectionCount = 0; + { + LOCK2(cs_main, cs_vNodes); + connectionCount = (int)vNodes.size(); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + int nMinDepth = 1; + + CAmount confirmed = 0; + CAmount unconfirmed = 0; + CAmount locked = 0; + CAmount immature = 0; + + CAmount privateConfirmed = 0; + CAmount privateUnconfirmed = 0; + CAmount privateLocked = 0; + CAmount privateImmature = 0; + + balancestruct txAmounts; + txAmounts.confirmed = 0; + txAmounts.unconfirmed = 0; + txAmounts.locked = 0; + txAmounts.immature = 0; + + + //Create map of addresses + //Add all Transaparent addresses to list + map addressBalances; + BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, pwalletMain->mapAddressBook) + { + string addressString = EncodeDestination(item.first); + if (addressBalances.count(addressString) == 0) + addressBalances.insert(make_pair(addressString,txAmounts)); + } + + //Add all Sapling addresses to map + std::set zs_addresses; + pwalletMain->GetSaplingPaymentAddresses(zs_addresses); + for (auto addr : zs_addresses) { + string addressString = EncodePaymentAddress(addr); + if (addressBalances.count(addressString) == 0) + addressBalances.insert(make_pair(addressString,txAmounts)); + } + + //Create Ordered List + map orderedTxs; + for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { + const uint256& wtxid = it->first; + const CWalletTx& wtx = (*it).second; + orderedTxs.insert(std::pair(wtx.nOrderPos, wtx)); + + unsigned int txType = 0; + // 0 Unassigend + // 1 Immature + // 2 Unconfirmed + // 3 Locked + + if (!CheckFinalTx(wtx)) + continue; + + if (wtx.GetDepthInMainChain() < 0) + continue; + + if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted()) + continue; + + //Assign Immature + if (txType == 0 && wtx.IsCoinBase() && wtx.GetBlocksToMaturity() > 0) + txType = 1; + + //Assign Unconfirmed + if (txType == 0 && wtx.GetDepthInMainChain() == 0) + txType = 2; + + for (unsigned int i = 0; i < wtx.vout.size(); i++) { + + CTxDestination address; + if (!ExtractDestination(wtx.vout[i].scriptPubKey, address)) + continue; + + //excluded coins that we dont have the spending keys for + isminetype mine = IsMine(*pwalletMain,address); + if (mine != ISMINE_SPENDABLE) + continue; + + //Exclude spent coins + if (pwalletMain->IsSpent(wtxid, i)) + continue; + + //Assign locked + if (txType == 0 && pwalletMain->IsLockedCoin((*it).first, i)) + txType = 3; + + //Assign Locked to 10000 Zer inputs for Zeronodes + //if (txType == 0 && fZeroNode && wtx.vout[i].nValue == 10000 * COIN) + // txType = 3; + + string addressString = EncodeDestination(address); + if (addressBalances.count(addressString) == 0) + addressBalances.insert(make_pair(addressString,txAmounts)); + + if (txType == 0) { + addressBalances.at(addressString).confirmed += wtx.vout[i].nValue; + confirmed += wtx.vout[i].nValue; + } else if (txType == 1) { + addressBalances.at(addressString).immature+= wtx.vout[i].nValue; + immature += wtx.vout[i].nValue; + } else if (txType == 2) { + addressBalances.at(addressString).unconfirmed += wtx.vout[i].nValue; + unconfirmed += wtx.vout[i].nValue; + } else if (txType == 3) { + addressBalances.at(addressString).locked += wtx.vout[i].nValue; + locked += wtx.vout[i].nValue; + } + } + + for (auto & pair : wtx.mapSaplingNoteData) { + SaplingOutPoint op = pair.first; + SaplingNoteData nd = pair.second; + + //Skip Spent + if (nd.nullifier && pwalletMain->IsSaplingSpent(*nd.nullifier)) + continue; + + //Decrypt sapling incoming commitments using IVK + for (auto addr : zs_addresses) { + libzcash::SaplingExtendedSpendingKey extsk; + if (pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk)) { + auto pt = libzcash::SaplingNotePlaintext::decrypt( + wtx.vShieldedOutput[op.n].encCiphertext,extsk.expsk.full_viewing_key().in_viewing_key(),wtx.vShieldedOutput[op.n].ephemeralKey,wtx.vShieldedOutput[op.n].cm); + + if (txType == 0 && pwalletMain->IsLockedNote(op)) + txType == 3; + + if (pt) { + auto note = pt.get(); + string addressString = EncodePaymentAddress(addr); + if (addressBalances.count(addressString) == 0) + addressBalances.insert(make_pair(addressString,txAmounts)); + + if (txType == 0) { + addressBalances.at(addressString).confirmed += note.value(); + privateConfirmed += note.value(); + } else if (txType == 1) { + addressBalances.at(addressString).immature += note.value(); + privateImmature += note.value(); + } else if (txType == 2) { + addressBalances.at(addressString).unconfirmed += note.value(); + privateUnconfirmed += note.value(); + } else if (txType == 3) { + addressBalances.at(addressString).locked += note.value(); + privateLocked += note.value(); + } + + continue; + + } + } + } + } + } + + + CAmount nBalance = 0; + CAmount nBalanceUnconfirmed = 0; + CAmount nBalanceTotal = 0; + CAmount totalBalance= confirmed + privateConfirmed; + CAmount totalUnconfirmed = unconfirmed + privateUnconfirmed; + + + returnObj.push_back(Pair("connectionCount", connectionCount)); + returnObj.push_back(Pair("besttime", chainActive.Tip()->GetBlockTime())); + returnObj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); + returnObj.push_back(Pair("transparentbalance", FormatMoney(confirmed))); + returnObj.push_back(Pair("transparentbalanceunconfirmed", FormatMoney(unconfirmed))); + returnObj.push_back(Pair("privatebalance", FormatMoney(privateConfirmed))); + returnObj.push_back(Pair("privatebalanceunconfirmed", FormatMoney(privateUnconfirmed))); + returnObj.push_back(Pair("totalbalance", FormatMoney(totalBalance))); + returnObj.push_back(Pair("totalunconfirmed", FormatMoney(totalUnconfirmed))); + returnObj.push_back(Pair("lockedbalance", FormatMoney(locked))); + returnObj.push_back(Pair("immaturebalance", FormatMoney(immature))); + + //get all t address + UniValue addressbalance(UniValue::VARR); + UniValue addrlist(UniValue::VOBJ); + + if (params.size() > 0 && (params[0].get_int() == 1 || params[0].get_int() == 0)) + { + for (map::iterator it = addressBalances.begin(); it != addressBalances.end(); ++it) { + UniValue addr(UniValue::VOBJ); + addr.push_back(Pair("amount", ValueFromAmount(it->second.confirmed))); + addr.push_back(Pair("unconfirmed", ValueFromAmount(it->second.unconfirmed))); + addr.push_back(Pair("locked", ValueFromAmount(it->second.locked))); + addr.push_back(Pair("immature", ValueFromAmount(it->second.immature))); + addr.push_back(Pair("ismine", true)); + addrlist.push_back(Pair(it->first, addr)); + } + } + + addressbalance.push_back(addrlist); + returnObj.push_back(Pair("addressbalance", addressbalance)); + + + //get transactions + int nCount = 200; + UniValue trans(UniValue::VARR); + UniValue transTime(UniValue::VARR); + + if (params.size() == 3) + { + nCount = params[2].get_int(); + } + + if (params.size() > 0 && (params[0].get_int() == 2 || params[0].get_int() == 0)) + { + int day = 365 * 30; //30 Years + if(params.size() > 1) + { + if(params[1].get_int() == 1) + { + day = 1; + } + else if(params[1].get_int() == 2) + { + day = 7; + } + else if(params[1].get_int() == 3) + { + day = 30; + } + else if(params[1].get_int() == 4) + { + day = 90; + } + else if(params[1].get_int() == 5) + { + day = 365; + } + } + + + uint64_t t = GetTime(); + for (map::reverse_iterator it = orderedTxs.rbegin(); it != orderedTxs.rend(); ++it) + { + const CWalletTx& wtx = (*it).second; + + if (!CheckFinalTx(wtx)) + continue; + + if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted()) + continue; + + //Excude transactions with less confirmations than required + if (wtx.GetDepthInMainChain() < 0 ) + continue; + + //Exclude Transactions older that max days old + if (wtx.GetDepthInMainChain() > 0 && mapBlockIndex[wtx.hashBlock]->GetBlockTime() < (t - (day * 60 * 60 * 24))) { + continue; + } + + zsWalletTxJSON(wtx, trans, "*", false, 0); + if (trans.size() >= nCount) break; + + } + + vector arrTmp = trans.getValues(); + + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + trans.clear(); + trans.setArray(); + trans.push_backV(arrTmp); + } + + returnObj.push_back(Pair("listtransactions", trans)); + return returnObj; +} + +UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey&) +{ if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -3167,7 +3479,8 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { return ret; } -UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { +UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) +{ if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -8429,6 +8742,7 @@ static const CRPCCommand commands[] = { "wallet", "encryptwallet", &encryptwallet, true }, { "wallet", "getaccountaddress", &getaccountaddress, true }, { "wallet", "getaccount", &getaccount, true }, + { "wallet", "getalldata", &getalldata, true }, { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true }, { "wallet", "getbalance", &getbalance, false }, { "wallet", "getnewaddress", &getnewaddress, true }, From 9e1c741905e0a420ee016177e77831747ea98ed1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 26 Feb 2020 14:12:15 -0500 Subject: [PATCH 026/220] Update convert params junk --- src/rpc/client.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 1ed44b48c..64b905d70 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -175,6 +175,12 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_listsentbyaddress", 3}, { "z_listsentbyaddress", 4}, { "z_listsentbyaddress", 5}, + { "z_listreceivedbyaddress", 1}, + { "z_listreceivedbyaddress", 2}, + { "z_listreceivedbyaddress", 3}, + { "z_listreceivedbyaddress", 4}, + { "z_listreceivedbyaddress", 5}, + // crosschain { "assetchainproof", 1}, { "crosschainproof", 1}, @@ -183,6 +189,10 @@ static const CRPCConvertParam vRPCConvertParams[] = { "height_MoM", 1}, { "calc_MoM", 2}, { "migrate_completeimporttransaction", 1}, + { "getalldata", 0}, + { "getalldata", 1}, + { "getalldata", 2}, + { "getalldata", 3} }; class CRPCConvertTable From a5515aa3363917f6b30e1745c4f9ca3e44d601c5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 26 Feb 2020 14:31:35 -0500 Subject: [PATCH 027/220] Fix z_validateaddress docs to remove sprout stuff and use a sapling address in examples --- src/rpc/misc.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 6f983bea7..a60f01290 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -638,17 +638,15 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my "{\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" " \"address\" : \"zaddr\", (string) The z address validated\n" - " \"type\" : \"xxxx\", (string) \"sprout\" or \"sapling\"\n" + " \"type\" : \"xxxx\", (string) \"sapling\"\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n" - " \"payingkey\" : \"hex\", (string) [sprout] The hex value of the paying key, a_pk\n" - " \"transmissionkey\" : \"hex\", (string) [sprout] The hex value of the transmission key, pk_enc\n" " \"diversifier\" : \"hex\", (string) [sapling] The hex value of the diversifier, d\n" " \"diversifiedtransmissionkey\" : \"hex\", (string) [sapling] The hex value of pk_d\n" "}\n" "\nExamples:\n" - + HelpExampleCli("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"") - + HelpExampleRpc("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"") + + HelpExampleCli("z_validateaddress", "\"zs1z7rejlpsa98s2rrrfkwmaxu53e4ue0ulcrw0h4x5g8jl04tak0d3mm47vdtahatqrlkngh9slya\"") + + HelpExampleRpc("z_validateaddress", "\"zs1z7rejlpsa98s2rrrfkwmaxu53e4ue0ulcrw0h4x5g8jl04tak0d3mm47vdtahatqrlkngh9slya\"") ); From a7250280d0edbc54c3a49d698fc3d55fa93fd113 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 27 Feb 2020 11:06:58 -0500 Subject: [PATCH 028/220] Remove deprecated Sprout benchmarking RPCs --- src/rpc/client.cpp | 7 +- src/rpc/server.cpp | 5 - src/rpc/server.h | 7 +- src/wallet/rpcwallet.cpp | 474 --------------------------------------- 4 files changed, 2 insertions(+), 491 deletions(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 64b905d70..4107ad6f8 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -130,12 +131,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getaddressdeltas", 0}, { "getaddressutxos", 0}, { "getaddressmempool", 0}, - { "zcrawjoinsplit", 1 }, - { "zcrawjoinsplit", 2 }, - { "zcrawjoinsplit", 3 }, - { "zcrawjoinsplit", 4 }, - { "zcbenchmark", 1 }, - { "zcbenchmark", 2 }, { "getblocksubsidy", 0}, { "z_listaddresses", 0}, { "z_listreceivedbyaddress", 1}, diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c052395a6..181de29bb 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -651,11 +651,6 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, - { "wallet", "zcbenchmark", &zc_benchmark, true }, - { "wallet", "zcrawkeygen", &zc_raw_keygen, true }, - { "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true }, - { "wallet", "zcrawreceive", &zc_raw_receive, true }, - { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false }, { "wallet", "z_getbalance", &z_getbalance, false }, { "wallet", "z_gettotalbalance", &z_gettotalbalance, false }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 6ce27894a..1cd4e993d 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush Developers +// Copyright (c) 2019-2020 The Hush Developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -402,11 +402,6 @@ extern UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey extern UniValue getdeprecationinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue setmocktime(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue resendwallettransactions(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue jumblr_deposit(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue jumblr_secret(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1fb365c34..79dab0c5b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3840,475 +3840,6 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp, const CPubKey& m return result; } -UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp) { - throw runtime_error( - "zcsamplejoinsplit\n" - "\n" - "Perform a joinsplit and return the JSDescription.\n" - ); - } - - LOCK(cs_main); - - uint256 joinSplitPubKey; - uint256 anchor = SproutMerkleTree().root(); - JSDescription samplejoinsplit(*pzcashParams, - joinSplitPubKey, - anchor, - {JSInput(), JSInput()}, - {JSOutput(), JSOutput()}, - 0, - 0); - - CDataStream ss(SER_NETWORK, SAPLING_TX_VERSION | (1 << 31)); - ss << samplejoinsplit; - - return HexStr(ss.begin(), ss.end()); -} - -UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() < 2) { - throw runtime_error( - "zcbenchmark benchmarktype samplecount\n" - "\n" - "Runs a benchmark of the selected type samplecount times,\n" - "returning the running times of each sample.\n" - "\n" - "Output: [\n" - " {\n" - " \"runningtime\": runningtime\n" - " },\n" - " {\n" - " \"runningtime\": runningtime\n" - " }\n" - " ...\n" - "]\n" - ); - } - - LOCK(cs_main); - - std::string benchmarktype = params[0].get_str(); - int samplecount = params[1].get_int(); - - if (samplecount <= 0) { - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid samplecount"); - } - - std::vector sample_times; - - JSDescription samplejoinsplit; - - if (benchmarktype == "verifyjoinsplit") { - CDataStream ss(ParseHexV(params[2].get_str(), "js"), SER_NETWORK, SAPLING_TX_VERSION | (1 << 31)); - ss >> samplejoinsplit; - } - - for (int i = 0; i < samplecount; i++) { - if (benchmarktype == "sleep") { - sample_times.push_back(benchmark_sleep()); - } else if (benchmarktype == "createjoinsplit") { - if (params.size() < 3) { - sample_times.push_back(benchmark_create_joinsplit()); - } else { - int nThreads = params[2].get_int(); - std::vector vals = benchmark_create_joinsplit_threaded(nThreads); - // Divide by nThreads^2 to get average seconds per JoinSplit because - // we are running one JoinSplit per thread. - sample_times.push_back(std::accumulate(vals.begin(), vals.end(), 0.0) / (nThreads*nThreads)); - } - } else if (benchmarktype == "verifyjoinsplit") { - sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit)); -#ifdef ENABLE_MINING - } else if (benchmarktype == "solveequihash") { - if (params.size() < 3) { - sample_times.push_back(benchmark_solve_equihash()); - } else { - int nThreads = params[2].get_int(); - std::vector vals = benchmark_solve_equihash_threaded(nThreads); - sample_times.insert(sample_times.end(), vals.begin(), vals.end()); - } -#endif - } else if (benchmarktype == "verifyequihash") { - sample_times.push_back(benchmark_verify_equihash()); - } else if (benchmarktype == "validatelargetx") { - // Number of inputs in the spending transaction that we will simulate - int nInputs = 11130; - if (params.size() >= 3) { - nInputs = params[2].get_int(); - } - sample_times.push_back(benchmark_large_tx(nInputs)); - } else if (benchmarktype == "trydecryptnotes") { - int nAddrs = params[2].get_int(); - sample_times.push_back(benchmark_try_decrypt_notes(nAddrs)); - } else if (benchmarktype == "incnotewitnesses") { - int nTxs = params[2].get_int(); - sample_times.push_back(benchmark_increment_note_witnesses(nTxs)); - } else if (benchmarktype == "connectblockslow") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - sample_times.push_back(benchmark_connectblock_slow()); - } else if (benchmarktype == "sendtoaddress") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - auto amount = AmountFromValue(params[2]); - sample_times.push_back(benchmark_sendtoaddress(amount)); - } else if (benchmarktype == "loadwallet") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - sample_times.push_back(benchmark_loadwallet()); - } else if (benchmarktype == "listunspent") { - sample_times.push_back(benchmark_listunspent()); - } else if (benchmarktype == "createsaplingspend") { - sample_times.push_back(benchmark_create_sapling_spend()); - } else if (benchmarktype == "createsaplingoutput") { - sample_times.push_back(benchmark_create_sapling_output()); - } else if (benchmarktype == "verifysaplingspend") { - sample_times.push_back(benchmark_verify_sapling_spend()); - } else if (benchmarktype == "verifysaplingoutput") { - sample_times.push_back(benchmark_verify_sapling_output()); - } else { - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid benchmarktype"); - } - } - - UniValue results(UniValue::VARR); - for (auto time : sample_times) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("runningtime", time)); - results.push_back(result); - } - - return results; -} - -UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 2) { - throw runtime_error( - "zcrawreceive zcsecretkey encryptednote\n" - "\n" - "DEPRECATED. Decrypts encryptednote and checks if the coin commitments\n" - "are in the blockchain as indicated by the \"exists\" result.\n" - "\n" - "Output: {\n" - " \"amount\": value,\n" - " \"note\": noteplaintext,\n" - " \"exists\": exists\n" - "}\n" - ); - } - - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VSTR)); - - LOCK(cs_main); - - auto spendingkey = DecodeSpendingKey(params[0].get_str()); - if (!IsValidSpendingKey(spendingkey)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); - } - if (boost::get(&spendingkey) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); - } - SproutSpendingKey k = boost::get(spendingkey); - - uint256 epk; - unsigned char nonce; - ZCNoteEncryption::Ciphertext ct; - uint256 h_sig; - - { - CDataStream ssData(ParseHexV(params[1], "encrypted_note"), SER_NETWORK, PROTOCOL_VERSION); - try { - ssData >> nonce; - ssData >> epk; - ssData >> ct; - ssData >> h_sig; - } catch(const std::exception &) { - throw runtime_error( - "encrypted_note could not be decoded" - ); - } - } - - ZCNoteDecryption decryptor(k.receiving_key()); - - SproutNotePlaintext npt = SproutNotePlaintext::decrypt( - decryptor, - ct, - epk, - h_sig, - nonce - ); - SproutPaymentAddress payment_addr = k.address(); - SproutNote decrypted_note = npt.note(payment_addr); - - assert(pwalletMain != NULL); - std::vector> witnesses; - uint256 anchor; - uint256 commitment = decrypted_note.cm(); - pwalletMain->WitnessNoteCommitment( - {commitment}, - witnesses, - anchor - ); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << npt; - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value()))); - result.push_back(Pair("note", HexStr(ss.begin(), ss.end()))); - result.push_back(Pair("exists", (bool) witnesses[0])); - return result; -} - - - -UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 5) { - throw runtime_error( - "zcrawjoinsplit rawtx inputs outputs vpub_old vpub_new\n" - " inputs: a JSON object mapping {note: zcsecretkey, ...}\n" - " outputs: a JSON object mapping {zcaddr: value, ...}\n" - "\n" - "DEPRECATED. Splices a joinsplit into rawtx. Inputs are unilaterally confidential.\n" - "Outputs are confidential between sender/receiver. The vpub_old and\n" - "vpub_new values are globally public and move transparent value into\n" - "or out of the confidential value store, respectively.\n" - "\n" - "Note: The caller is responsible for delivering the output enc1 and\n" - "enc2 to the appropriate recipients, as well as signing rawtxout and\n" - "ensuring it is mined. (A future RPC call will deliver the confidential\n" - "payments in-band on the blockchain.)\n" - "\n" - "Output: {\n" - " \"encryptednote1\": enc1,\n" - " \"encryptednote2\": enc2,\n" - " \"rawtxn\": rawtxout\n" - "}\n" - ); - } - - LOCK(cs_main); - - CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - - UniValue inputs = params[1].get_obj(); - UniValue outputs = params[2].get_obj(); - - CAmount vpub_old(0); - CAmount vpub_new(0); - - if (params[3].get_real() != 0.0) - vpub_old = AmountFromValue(params[3]); - - if (params[4].get_real() != 0.0) - vpub_new = AmountFromValue(params[4]); - - std::vector vjsin; - std::vector vjsout; - std::vector notes; - std::vector keys; - std::vector commitments; - - for (const string& name_ : inputs.getKeys()) { - auto spendingkey = DecodeSpendingKey(inputs[name_].get_str()); - if (!IsValidSpendingKey(spendingkey)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); - } - if (boost::get(&spendingkey) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); - } - SproutSpendingKey k = boost::get(spendingkey); - - keys.push_back(k); - - SproutNotePlaintext npt; - - { - CDataStream ssData(ParseHexV(name_, "note"), SER_NETWORK, PROTOCOL_VERSION); - ssData >> npt; - } - - SproutPaymentAddress addr = k.address(); - SproutNote note = npt.note(addr); - notes.push_back(note); - commitments.push_back(note.cm()); - } - - uint256 anchor; - std::vector> witnesses; - pwalletMain->WitnessNoteCommitment(commitments, witnesses, anchor); - - assert(witnesses.size() == notes.size()); - assert(notes.size() == keys.size()); - - { - for (size_t i = 0; i < witnesses.size(); i++) { - if (!witnesses[i]) { - throw runtime_error( - "joinsplit input could not be found in tree" - ); - } - - vjsin.push_back(JSInput(*witnesses[i], notes[i], keys[i])); - } - } - - while (vjsin.size() < ZC_NUM_JS_INPUTS) { - vjsin.push_back(JSInput()); - } - - for (const string& name_ : outputs.getKeys()) { - auto addrTo = DecodePaymentAddress(name_); - if (!IsValidPaymentAddress(addrTo)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address."); - } - if (boost::get(&addrTo) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses"); - } - CAmount nAmount = AmountFromValue(outputs[name_]); - - vjsout.push_back(JSOutput(boost::get(addrTo), nAmount)); - } - - while (vjsout.size() < ZC_NUM_JS_OUTPUTS) { - vjsout.push_back(JSOutput()); - } - - // TODO - if (vjsout.size() != ZC_NUM_JS_INPUTS || vjsin.size() != ZC_NUM_JS_OUTPUTS) { - throw runtime_error("unsupported joinsplit input/output counts"); - } - - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - - CMutableTransaction mtx(tx); - mtx.nVersion = 2; - mtx.joinSplitPubKey = joinSplitPubKey; - - JSDescription jsdesc(*pzcashParams, - joinSplitPubKey, - anchor, - {vjsin[0], vjsin[1]}, - {vjsout[0], vjsout[1]}, - vpub_old, - vpub_new); - - { - auto verifier = libzcash::ProofVerifier::Strict(); - assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey)); - } - - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - CScript scriptCode; - CTransaction signTx(mtx); - auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - - // Sanity check - assert(crypto_sign_verify_detached(&mtx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - mtx.joinSplitPubKey.begin() - ) == 0); - - CTransaction rawTx(mtx); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - - std::string encryptedNote1; - std::string encryptedNote2; - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x00); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[0]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey); - - encryptedNote1 = HexStr(ss2.begin(), ss2.end()); - } - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x01); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[1]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey); - - encryptedNote2 = HexStr(ss2.begin(), ss2.end()); - } - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("encryptednote1", encryptedNote1)); - result.push_back(Pair("encryptednote2", encryptedNote2)); - result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); - return result; -} - -UniValue zc_raw_keygen(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 0) { - throw runtime_error( - "zcrawkeygen\n" - "\n" - "DEPRECATED. Generate a zcaddr which can send and receive confidential values.\n" - "\n" - "Output: {\n" - " \"zcaddress\": zcaddr,\n" - " \"zcsecretkey\": zcsecretkey,\n" - " \"zcviewingkey\": zcviewingkey,\n" - "}\n" - ); - } - - auto k = SproutSpendingKey::random(); - auto addr = k.address(); - auto viewing_key = k.viewing_key(); - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("zcaddress", EncodePaymentAddress(addr))); - result.push_back(Pair("zcsecretkey", EncodeSpendingKey(k))); - result.push_back(Pair("zcviewingkey", EncodeViewingKey(viewing_key))); - return result; -} - - UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -8776,11 +8307,6 @@ static const CRPCCommand commands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, - { "wallet", "zcbenchmark", &zc_benchmark, true }, - { "wallet", "zcrawkeygen", &zc_raw_keygen, true }, - { "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true }, - { "wallet", "zcrawreceive", &zc_raw_receive, true }, - { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, false }, { "wallet", "z_listunspent", &z_listunspent, false }, { "wallet", "z_getbalance", &z_getbalance, false }, From cb004f5d57d4f2b5fc8afb0223621d663c13aaf2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 27 Feb 2020 11:11:59 -0500 Subject: [PATCH 029/220] Remove sprout code from z_exportwallet --- src/wallet/rpcdump.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b87672dc3..44639f663 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -666,18 +666,10 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys) file << "\n"; if (fDumpZKeys) { - std::set sproutAddresses; - pwalletMain->GetSproutPaymentAddresses(sproutAddresses); file << "\n"; file << "# Zkeys\n"; file << "\n"; - for (auto addr : sproutAddresses) { - libzcash::SproutSpendingKey key; - if (pwalletMain->GetSproutSpendingKey(addr, key)) { - std::string strTime = EncodeDumpTime(pwalletMain->mapSproutZKeyMetadata[addr].nCreateTime); - file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr)); - } - } + std::set saplingAddresses; pwalletMain->GetSaplingPaymentAddresses(saplingAddresses); file << "\n"; From 9b0d9865285ed02b812d43580b6d5609ff060d12 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 27 Feb 2020 18:20:14 -0500 Subject: [PATCH 030/220] Document default of -consolidation and add comment about number of zouts --- src/init.cpp | 2 +- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 9d10e9d4a..ce5dfb5a6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -448,7 +448,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); - strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation")); + strUsage += HelpMessageOpt("-consolidation", _("Enable auto Sapling note consolidation (default: false)")); strUsage += HelpMessageOpt("-consolidatesaplingaddress=", _("Specify Sapling Address to Consolidate. (default: all)")); strUsage += HelpMessageOpt("-consolidationtxfee", strprintf(_("Fee amount in Puposhis used send consolidation transactions. (default %i)"), DEFAULT_CONSOLIDATION_FEE)); strUsage += HelpMessageOpt("-deletetx", _("Enable Old Transaction Deletion")); diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 9152f0d8c..26809f2b8 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -167,6 +167,10 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { } builder.SetFee(fConsolidationTxFee); + + //TODO: we want at least 2 zouts and potentially Sietch + // We could split funds into 2 parts and send as 2 zouts + // or add amount=0 sietch zaddrs builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); //CTransaction tx = builder.Build(); From 2f891b0e148fce4e64d605b2e527eb4440c0e32c Mon Sep 17 00:00:00 2001 From: ca333 Date: Mon, 20 Jan 2020 15:13:50 +0100 Subject: [PATCH 031/220] add opretmintxfee --- src/miner.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/miner.cpp b/src/miner.cpp index 079e2bbf9..97270752f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -472,6 +472,40 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 // Size limits unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + + // Opret spam limits + if (mapArgs.count("-opretmintxfee")) + { + CAmount n = 0; + CFeeRate opretMinFeeRate; + if (ParseMoney(mapArgs["-opretmintxfee"], n) && n > 0) + opretMinFeeRate = CFeeRate(n); + else + opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 KMD per 250 Kb = 0.004 per 1 Kb = 400000 sat per 1 Kb) + + bool fSpamTx = false; + unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); + unsigned int nTxOpretSize = 0; + + // calc total oprets size + BOOST_FOREACH(const CTxOut& txout, tx.vout) { + if (txout.scriptPubKey.IsOpReturn()) { + CScript::const_iterator it = txout.scriptPubKey.begin() + 1; + opcodetype op; + std::vector opretData; + if (txout.scriptPubKey.GetOp(it, op, opretData)) { + //std::cerr << HexStr(opretData.begin(), opretData.end()) << std::endl; + nTxOpretSize += opretData.size(); + } + } + } + + if ((nTxOpretSize > 256) && (feeRate < opretMinFeeRate)) fSpamTx = true; + // std::cerr << tx.GetHash().ToString() << " nTxSize." << nTxSize << " nTxOpretSize." << nTxOpretSize << " feeRate." << feeRate.ToString() << " opretMinFeeRate." << opretMinFeeRate.ToString() << " fSpamTx." << fSpamTx << std::endl; + if (fSpamTx) continue; + // std::cerr << tx.GetHash().ToString() << " vecPriority.size() = " << vecPriority.size() << std::endl; + } + if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx { //fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize); From b2b76e82dad450f2185e7b553af52b03ced01c15 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 29 Feb 2020 08:44:13 +0100 Subject: [PATCH 032/220] Change KMD to Hush in opretMinFeeRate unit --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 97270752f..5bc83fac4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -481,7 +481,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if (ParseMoney(mapArgs["-opretmintxfee"], n) && n > 0) opretMinFeeRate = CFeeRate(n); else - opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 KMD per 250 Kb = 0.004 per 1 Kb = 400000 sat per 1 Kb) + opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 HUSH per 250 Kb = 0.004 per 1 Kb = 400000 puposhis per 1 Kb) bool fSpamTx = false; unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); From dc7525f12e6531b41596da64de533005542a4c5d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 4 Mar 2020 09:17:05 -0500 Subject: [PATCH 033/220] Untested sapling consolidation plus sietch outputs to reduce metadata leakage --- src/komodo_bitcoind.h | 1 + ...asyncrpcoperation_saplingconsolidation.cpp | 25 ++++++++++++++++--- src/wallet/rpcwallet.cpp | 3 ++- src/wallet/wallet.h | 1 + 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index b89aa5c0a..b5e825a58 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -24,6 +24,7 @@ #include "komodo_defs.h" #include "script/standard.h" #include "cc/CCinclude.h" +#include "sietch.h" int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 26809f2b8..0d1599916 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -1,3 +1,8 @@ +// Copyright (c) 2020 The Hush developers +// TODO: Forge should add his preferred copyright line here +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "assert.h" #include "boost/variant/static_visitor.hpp" #include "asyncrpcoperation_saplingconsolidation.h" @@ -11,11 +16,13 @@ #include "util.h" #include "utilmoneystr.h" #include "wallet.h" +//#include "sietch.h" CAmount fConsolidationTxFee = DEFAULT_CONSOLIDATION_FEE; bool fConsolidationMapUsed = false; const int CONSOLIDATION_EXPIRY_DELTA = 15; +extern string randomSietchZaddr(); AsyncRPCOperation_saplingconsolidation::AsyncRPCOperation_saplingconsolidation(int targetHeight) : targetHeight_(targetHeight) {} @@ -168,10 +175,22 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { builder.SetFee(fConsolidationTxFee); - //TODO: we want at least 2 zouts and potentially Sietch - // We could split funds into 2 parts and send as 2 zouts - // or add amount=0 sietch zaddrs + // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); + + // Add sietch zouts + int MIN_ZOUTS = 7; + for(size_t i = 0; i < MIN_ZOUTS; i++) { + // In Privacy Zdust We Trust -- Duke + string zdust = randomSietchZaddr(); + LogPrint("zrpcunsafe", "%s: Adding sietch output", getId(), zdust); + auto zaddr = DecodePaymentAddress(zdust); + if (IsValidPaymentAddress(zaddr)) { + auto sietchZoutput = boost::get(zaddr); + int amount=0; + builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); + } + } //CTransaction tx = builder.Build(); auto maybe_tx = builder.Build(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 79dab0c5b..8f5688026 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -62,7 +62,7 @@ #include "komodo_defs.h" #include -#include "sietch.h" +//#include "sietch.h" #include "rpchushwallet.h" using namespace std; @@ -79,6 +79,7 @@ uint32_t komodo_segid32(char *coinaddr); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only CBlockIndex *komodo_getblockindex(uint256 hash); +extern string randomSietchZaddr(); int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 79d24a86d..6b9a1d628 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -42,6 +42,7 @@ #include "zcash/Address.hpp" #include "zcash/zip32.h" #include "base58.h" +//#include "sietch.h" #include #include From 9c72f4c2f5b9a442e6e3c1acda91c603770f3670 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 6 Mar 2020 14:40:24 -0500 Subject: [PATCH 034/220] Change consolidation fee to be the default instead of zero and require zinput arity to be inside [3,8] --- .../asyncrpcoperation_saplingconsolidation.cpp | 13 +++++++++---- src/wallet/asyncrpcoperation_saplingconsolidation.h | 11 ++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 0d1599916..32601e0fd 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -120,7 +120,10 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { std::vector fromNotes; CAmount amountToSend = 0; - int maxQuantity = rand() % 35 + 10; + // max of 8 zins means the tx cannot reduce the anonset, + // since there will be 8 zins and 8 zouts at worst case + // This also helps reduce ztx creation time + int maxQuantity = rand() % 8 + 1; for (const SaplingNoteEntry& saplingEntry : saplingEntries) { libzcash::SaplingIncomingViewingKey ivk; @@ -132,14 +135,16 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { fromNotes.push_back(saplingEntry); } - //Only use a randomly determined number of notes between 10 and 45 + //Only use a randomly determined number of notes if (fromNotes.size() >= maxQuantity) break; } - //random minimum 2 - 12 required - int minQuantity = rand() % 10 + 2; + // minimum required + // We use 3 so that addresses can spent one zutxo and still have another zutxo to use while that + // tx is confirming + int minQuantity = 3; if (fromNotes.size() < minQuantity) continue; diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.h b/src/wallet/asyncrpcoperation_saplingconsolidation.h index 8e38204c7..9a80ff7c7 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.h +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.h @@ -1,11 +1,16 @@ +// Copyright (c) 2020 The Hush developers +// TODO: Forge should add his preferred copyright line here +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "amount.h" #include "asyncrpcoperation.h" #include "univalue.h" #include "zcash/Address.hpp" #include "zcash/zip32.h" -//Default fee used for consolidation transactions -static const CAmount DEFAULT_CONSOLIDATION_FEE = 0; +//Default fee used for consolidation transactions, in puposhis +static const CAmount DEFAULT_CONSOLIDATION_FEE = 10000; extern CAmount fConsolidationTxFee; extern bool fConsolidationMapUsed; @@ -34,4 +39,4 @@ private: void setConsolidationResult(int numTxCreated, const CAmount& amountConsolidated, const std::vector& consolidationTxIds); -}; \ No newline at end of file +}; From fad66953fb037ba9e40ba29760f9de8cec8cf09f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 6 Mar 2020 15:22:50 -0500 Subject: [PATCH 035/220] Cleanup --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 1 - src/wallet/rpcwallet.cpp | 1 - src/wallet/wallet.h | 3 +-- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 32601e0fd..e85ce5861 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -16,7 +16,6 @@ #include "util.h" #include "utilmoneystr.h" #include "wallet.h" -//#include "sietch.h" CAmount fConsolidationTxFee = DEFAULT_CONSOLIDATION_FEE; bool fConsolidationMapUsed = false; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 8f5688026..ea4b43a5a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -62,7 +62,6 @@ #include "komodo_defs.h" #include -//#include "sietch.h" #include "rpchushwallet.h" using namespace std; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6b9a1d628..ea327b2d9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -42,7 +42,6 @@ #include "zcash/Address.hpp" #include "zcash/zip32.h" #include "base58.h" -//#include "sietch.h" #include #include From a2b3316664ca772294a71b5f07499c229a6d0790 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 13:55:12 -0500 Subject: [PATCH 036/220] Port PR93 from @denioD --- qa/rpc-tests/mempool_resurrect_test.py | 3 + qa/rpc-tests/test_framework/util.py | 8 +++ qa/rpc-tests/wallet.py | 1 + qa/rpc-tests/wallet_1941.py | 2 + qa/rpc-tests/wallet_anchorfork.py | 1 + qa/rpc-tests/wallet_shieldcoinbase.py | 1 + qa/rpc-tests/zcjoinsplit.py | 3 + qa/rpc-tests/zmq_test.py | 18 +++--- src/init.cpp | 31 ++++------ src/main.cpp | 83 +++++++++++++------------- src/main.h | 4 ++ src/txmempool.cpp | 30 +++------- src/txmempool.h | 3 +- src/validationinterface.cpp | 83 +++++++++++++++++++++++++- src/validationinterface.h | 8 +-- src/wallet/wallet.cpp | 4 +- src/wallet/wallet.h | 5 +- src/zcbenchmarks.cpp | 4 +- 18 files changed, 186 insertions(+), 106 deletions(-) diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index 1cbbd2cd5..faa97d461 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -54,6 +54,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework): spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ] blocks.extend(self.nodes[0].generate(1)) + self.sync_all() # mempool should be empty, all txns confirmed assert_equal(set(self.nodes[0].getrawmempool()), set()) @@ -74,6 +75,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Generate another block, they should all get mined self.nodes[0].generate(1) + self.sync_all() + # mempool should be empty, all txns confirmed assert_equal(set(self.nodes[0].getrawmempool()), set()) for txid in spends1_id+spends2_id: diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index b41c4b451..78c66089a 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -60,6 +60,14 @@ def sync_blocks(rpc_connections, wait=1): break time.sleep(wait) + # Now that the block counts are in sync, wait for the internal + # notifications to finish + while True: + notified = [ x.getblockchaininfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + break + time.sleep(wait) + def sync_mempools(rpc_connections, wait=1): """ Wait until everybody has the same transactions in their memory diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 5d221a28c..0268dd292 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -31,6 +31,7 @@ class WalletTest (BitcoinTestFramework): print "Mining blocks..." self.nodes[0].generate(4) + self.sync_all() walletinfo = self.nodes[0].getwalletinfo() assert_equal(walletinfo['immature_balance'], 40) diff --git a/qa/rpc-tests/wallet_1941.py b/qa/rpc-tests/wallet_1941.py index d70b514fc..6f90f33bd 100755 --- a/qa/rpc-tests/wallet_1941.py +++ b/qa/rpc-tests/wallet_1941.py @@ -45,6 +45,7 @@ class Wallet1941RegressionTest (BitcoinTestFramework): self.nodes[0].setmocktime(starttime) self.nodes[0].generate(101) + self.sync_all() mytaddr = self.nodes[0].getnewaddress() # where coins were mined myzaddr = self.nodes[0].z_getnewaddress() @@ -63,6 +64,7 @@ class Wallet1941RegressionTest (BitcoinTestFramework): self.nodes[0].generate(1) self.nodes[0].setmocktime(starttime + 9000) self.nodes[0].generate(1) + self.sync_all() # Confirm the balance on node 0. resp = self.nodes[0].z_getbalance(myzaddr) diff --git a/qa/rpc-tests/wallet_anchorfork.py b/qa/rpc-tests/wallet_anchorfork.py index 0e2d19385..1cb16e152 100755 --- a/qa/rpc-tests/wallet_anchorfork.py +++ b/qa/rpc-tests/wallet_anchorfork.py @@ -27,6 +27,7 @@ class WalletAnchorForkTest (BitcoinTestFramework): def run_test (self): print "Mining blocks..." self.nodes[0].generate(4) + self.sync_all() walletinfo = self.nodes[0].getwalletinfo() assert_equal(walletinfo['immature_balance'], 40) diff --git a/qa/rpc-tests/wallet_shieldcoinbase.py b/qa/rpc-tests/wallet_shieldcoinbase.py index d8366c81d..f325b29ca 100755 --- a/qa/rpc-tests/wallet_shieldcoinbase.py +++ b/qa/rpc-tests/wallet_shieldcoinbase.py @@ -44,6 +44,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): print "Mining blocks..." self.nodes[0].generate(1) + self.sync_all() do_not_shield_taddr = self.nodes[0].getnewaddress() self.nodes[0].generate(4) diff --git a/qa/rpc-tests/zcjoinsplit.py b/qa/rpc-tests/zcjoinsplit.py index 7e5aba6e3..b3ca745f8 100755 --- a/qa/rpc-tests/zcjoinsplit.py +++ b/qa/rpc-tests/zcjoinsplit.py @@ -30,6 +30,7 @@ class JoinSplitTest(BitcoinTestFramework): protect_tx = self.nodes[0].signrawtransaction(joinsplit_result["rawtxn"]) self.nodes[0].sendrawtransaction(protect_tx["hex"]) self.nodes[0].generate(1) + self.sync_all() receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) assert_equal(receive_result["exists"], True) @@ -39,6 +40,7 @@ class JoinSplitTest(BitcoinTestFramework): addrtest = self.nodes[0].getnewaddress() for xx in range(0,10): self.nodes[0].generate(1) + self.sync_all() for x in range(0,50): self.nodes[0].sendtoaddress(addrtest, 0.01); @@ -47,6 +49,7 @@ class JoinSplitTest(BitcoinTestFramework): self.nodes[0].sendrawtransaction(joinsplit_result["rawtxn"]) self.nodes[0].generate(1) + self.sync_all() print "Done!" receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index d70e73114..dcb899861 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -37,15 +37,6 @@ class ZMQTest(BitcoinTestFramework): self.sync_all() print "listen..." - msg = self.zmqSubSocket.recv_multipart() - topic = msg[0] - assert_equal(topic, b"hashtx") - body = msg[1] - nseq = msg[2] - [nseq] # hush pyflakes - msgSequence = struct.unpack(' vImportFiles) } } -void ThreadNotifyRecentlyAdded() -{ - while (true) { - // Run the notifier on an integer second in the steady clock. - auto now = std::chrono::steady_clock::now().time_since_epoch(); - auto nextFire = std::chrono::duration_cast( - now + std::chrono::seconds(1)); - std::this_thread::sleep_until( - std::chrono::time_point(nextFire)); - - boost::this_thread::interruption_point(); - - mempool.NotifyRecentlyAdded(); - } -} - /** Sanity checks * Ensure that Hush is running in a usable environment with all * necessary library support. @@ -2088,6 +2072,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif // ENABLE_MINING + // Start the thread that notifies listeners of transactions that have been + // recently added to the mempool, or have been added to or removed from the + // chain. We perform this before step 10 (import blocks) so that the + // original value of chainActive.Tip(), which corresponds with the wallet's + // view of the chaintip, is passed to ThreadNotifyWallets before the chain + // tip changes again. + boost::function threadnotifywallets = boost::bind(&ThreadNotifyWallets, chainActive.Tip()); + threadGroup.create_thread( + boost::bind(&TraceThread>, "txnotify", threadnotifywallets) + ); + // ********************************************************* Step 9: data directory maintenance // if pruning, unset the service bit and perform the initial blockstore prune @@ -2155,10 +2150,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); #endif - // Start the thread that notifies listeners of transactions that have been - // recently added to the mempool. - threadGroup.create_thread(boost::bind(&TraceThread, "txnotify", &ThreadNotifyRecentlyAdded)); - if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(threadGroup, scheduler); diff --git a/src/main.cpp b/src/main.cpp index 2e0394779..848e5422a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4068,21 +4068,8 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) { // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); - // Get the current commitment tree - SproutMerkleTree newSproutTree; - SaplingMerkleTree newSaplingTree; - assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), newSproutTree)); - assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), newSaplingTree)); - // Let wallets know transactions went from 1-confirmed to - // 0-confirmed or conflicted: - std::vector TxToRemove; - for (int i = 0; i < block.vtx.size(); i++) - { - CTransaction &tx = block.vtx[i]; - SyncWithWallets(tx, NULL); - } - // Update cached incremental witnesses - GetMainSignals().ChainTip(pindexDelete, &block, newSproutTree, newSaplingTree, false); + // Updates to connected wallets are triggered by ThreadNotifyWallets + return true; } @@ -4156,6 +4143,11 @@ static int64_t nTimeFlush = 0; static int64_t nTimeChainState = 0; static int64_t nTimePostConnect = 0; +// Protected by cs_main +std::map> recentlyConflictedTxs; +uint64_t nRecentlyConflictedSequence = 0; +uint64_t nNotifiedSequence = 0; + /** * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. @@ -4175,14 +4167,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * } KOMODO_CONNECTING = (int32_t)pindexNew->GetHeight(); //fprintf(stderr,"%s connecting ht.%d maxsize.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pindexNew->GetHeight(),MAX_BLOCK_SIZE(pindexNew->GetHeight()),(int32_t)::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); - // Get the current commitment tree - SproutMerkleTree oldSproutTree; - SaplingMerkleTree oldSaplingTree; - if ( KOMODO_NSPV_FULLNODE ) - { - assert(pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), oldSproutTree)); - assert(pcoinsTip->GetSaplingAnchorAt(pcoinsTip->GetBestAnchor(SAPLING), oldSaplingTree)); - } + // Apply the block atomically to the chain state. int64_t nTime2 = GetTimeMicros(); nTimeReadFromDisk += nTime2 - nTime1; int64_t nTime3; @@ -4221,7 +4206,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); // Remove conflicting transactions from the mempool. - list txConflicted; + std::list txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload()); // Remove transactions that expire at new block height from mempool @@ -4231,18 +4216,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * UpdateTip(pindexNew); if ( KOMODO_NSPV_FULLNODE ) { - // Tell wallet about transactions that went from mempool - // to conflicted: - BOOST_FOREACH(const CTransaction &tx, txConflicted) { - SyncWithWallets(tx, NULL); - } - // ... and about transactions that got confirmed: - BOOST_FOREACH(const CTransaction &tx, pblock->vtx) { - SyncWithWallets(tx, pblock); - } - } - // Update cached incremental witnesses - GetMainSignals().ChainTip(pindexNew, pblock, oldSproutTree, oldSaplingTree, true); + + // Cache the conflicted transactions for subsequent notification. + // Updates to connected wallets are triggered by ThreadNotifyWallets + recentlyConflictedTxs.insert(std::make_pair(pindexNew, txConflicted)); + nRecentlyConflictedSequence += 1; EnforceNodeDeprecation(pindexNew->GetHeight()); @@ -4278,6 +4256,31 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * //fprintf(stderr,"%s: returning true\n", __FUNCTION__); return true; } +} +std::pair>, uint64_t> DrainRecentlyConflicted() +{ + uint64_t recentlyConflictedSequence; + std::map> txs; + { + LOCK(cs_main); + recentlyConflictedSequence = nRecentlyConflictedSequence; + txs.swap(recentlyConflictedTxs); + } + + return std::make_pair(txs, recentlyConflictedSequence); +} + +void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence) { + assert(Params().NetworkIDString() == "regtest"); + LOCK(cs_main); + nNotifiedSequence = recentlyConflictedSequence; +} + +bool ChainIsFullyNotified() { + assert(Params().NetworkIDString() == "regtest"); + LOCK(cs_main); + return nRecentlyConflictedSequence == nNotifiedSequence; +} /** * Return the tip of the chain with the most work in it, that isn't @@ -5316,10 +5319,10 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C return(false); } - if (ptx) - { - SyncWithWallets(*ptx, &block); - } + // if (ptx) + // { + // SyncWithWallets(*ptx, &block); + // } if ( ASSETCHAINS_CC != 0 ) { diff --git a/src/main.h b/src/main.h index c4bf4ea64..060b6b7cc 100644 --- a/src/main.h +++ b/src/main.h @@ -949,4 +949,8 @@ uint64_t CalculateCurrentUsage(); /** Return a CMutableTransaction with contextual default values based on set of consensus rules at height */ CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); +std::pair>, uint64_t> DrainRecentlyConflicted(); +void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence); +bool ChainIsFullyNotified(); + #endif // BITCOIN_MAIN_H diff --git a/src/txmempool.cpp b/src/txmempool.cpp index ed5951e08..8a99a99e6 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -844,7 +844,7 @@ bool CTxMemPool::nullifierExists(const uint256& nullifier, ShieldedType type) co } } -void CTxMemPool::NotifyRecentlyAdded() +std::pair, uint64_t> CTxMemPool::DrainRecentlyAdded() { uint64_t recentlyAddedSequence; std::vector txs; @@ -857,29 +857,13 @@ void CTxMemPool::NotifyRecentlyAdded() mapRecentlyAddedTx.clear(); } - // A race condition can occur here between these SyncWithWallets calls, and - // the ones triggered by block logic (in ConnectTip and DisconnectTip). It - // is harmless because calling SyncWithWallets(_, NULL) does not alter the - // wallet transaction's block information. - for (auto tx : txs) { - try { - SyncWithWallets(tx, NULL); - } catch (const boost::thread_interrupted&) { - fprintf(stderr,"%s: thread interrupted\n", __FUNCTION__); - throw; - } catch (const std::exception& e) { - PrintExceptionContinue(&e, "CTxMemPool::NotifyRecentlyAdded()"); - } catch (...) { - PrintExceptionContinue(NULL, "CTxMemPool::NotifyRecentlyAdded()"); - } - } + return std::make_pair(txs, recentlyAddedSequence); +} - // Update the notified sequence number. We only need this in regtest mode, - // and should not lock on cs after calling SyncWithWallets otherwise. - if (Params().NetworkIDString() == "regtest") { - LOCK(cs); - nNotifiedSequence = recentlyAddedSequence; - } +void CTxMemPool::SetNotifiedSequence(uint64_t recentlyAddedSequence) { + assert(Params().NetworkIDString() == "regtest"); + LOCK(cs); + nNotifiedSequence = recentlyAddedSequence; } bool CTxMemPool::IsFullyNotified() { diff --git a/src/txmempool.h b/src/txmempool.h index fbf7e4784..f8aa0e9a7 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -240,7 +240,8 @@ public: bool nullifierExists(const uint256& nullifier, ShieldedType type) const; - void NotifyRecentlyAdded(); + std::pair, uint64_t> DrainRecentlyAdded(); + void SetNotifiedSequence(uint64_t recentlyAddedSequence); bool IsFullyNotified(); unsigned long size() diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 6ea07be9e..f3bca6205 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -5,6 +5,17 @@ #include "validationinterface.h" +#include "chainparams.h" +#include "init.h" +#include "main.h" +#include "txmempool.h" +#include "ui_interface.h" + +#include + +#include +#include + static CMainSignals g_signals; CMainSignals& GetMainSignals() @@ -18,7 +29,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.RescanWallet.connect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn)); - g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5)); + g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); @@ -29,7 +40,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5)); + g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3)); g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); @@ -55,10 +66,76 @@ void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { g_signals.SyncTransaction(tx, pblock); } +struct CachedBlockData { + CBlockIndex *pindex; + std::pair oldTrees; + std::list txConflicted; + + CachedBlockData( + CBlockIndex *pindex, + std::pair oldTrees, + std::list txConflicted): + pindex(pindex), oldTrees(oldTrees), txConflicted(txConflicted) {} +}; + +void ThreadNotifyWallets(CBlockIndex *pindexLastTip) +{ + // If pindexLastTip == nullptr, the wallet is at genesis. + // However, the genesis block is not loaded synchronously. + // We need to wait for ThreadImport to finish. + while (pindexLastTip == nullptr) { + { + LOCK(cs_main); + pindexLastTip = chainActive.Genesis(); + } + MilliSleep(50); + } + + while (true) { + // Run the notifier on an integer second in the steady clock. + auto now = std::chrono::steady_clock::now().time_since_epoch(); + auto nextFire = std::chrono::duration_cast( + now + std::chrono::seconds(1)); + std::this_thread::sleep_until( + std::chrono::time_point(nextFire)); + + boost::this_thread::interruption_point(); + + auto chainParams = Params(); + + // + // Collect all the state we require + // + + // The common ancestor between the last chain tip we notified and the + // current chain tip. + const CBlockIndex *pindexFork; + // The stack of blocks we will notify as having been connected. + // Pushed in reverse, popped in order. + std::vector blockStack; + // Transactions that have been recently conflicted out of the mempool. + std::pair>, uint64_t> recentlyConflicted; + // Transactions that have been recently added to the mempool. + std::pair, uint64_t> recentlyAdded; + + { + LOCK(cs_main); + + // Figure out the path from the last block we notified to the + // current chain tip. + CBlockIndex *pindex = chainActive.Tip(); + pindexFork = chainActive.FindFork(pindexLastTip); + + // Fetch recently-conflicted transactions. These will include any + // block that has been connected since the last cycle, but we only + // notify for the conflicts created by the current active chain. + } + } +} void EraseFromWallets(const uint256 &hash) { g_signals.EraseTransaction(hash); } void RescanWallets() { g_signals.RescanWallet(); -} \ No newline at end of file +} diff --git a/src/validationinterface.h b/src/validationinterface.h index 30b9cf0a7..33cd5728e 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -26,8 +26,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn); void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllValidationInterfaces(); -/** Push an updated transaction to all registered wallets */ -void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); /** Erase a transaction from all registered wallets */ void EraseFromWallets(const uint256 &hash); /** Rescan all registered wallets */ @@ -39,7 +37,7 @@ protected: virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} virtual void EraseFromWallet(const uint256 &hash) {} virtual void RescanWallet() {} - virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, SaplingMerkleTree saplingTree, bool added) {} + virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, boost::optional> added) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual void UpdatedTransaction(const uint256 &hash) {} virtual void Inventory(const uint256 &hash) {} @@ -62,7 +60,7 @@ struct CMainSignals { /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ boost::signals2::signal UpdatedTransaction; /** Notifies listeners of a change to the tip of the active block chain. */ - boost::signals2::signal ChainTip; + boost::signals2::signal>)> ChainTip; /** Notifies listeners of a new active block chain. */ boost::signals2::signal SetBestChain; /** Notifies listeners about an inventory item being seen on the network. */ @@ -75,4 +73,6 @@ struct CMainSignals { CMainSignals& GetMainSignals(); +void ThreadNotifyWallets(CBlockIndex *pindexLastTip); + #endif // BITCOIN_VALIDATIONINTERFACE_H diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 953f738ef..f8127e83d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -588,9 +588,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock, - SproutMerkleTree sproutTree, - SaplingMerkleTree saplingTree, - bool added) + boost::optional> added) { if (added) { // Prevent witness cache building && consolidation transactions diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 79d24a86d..0c3b96330 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1253,7 +1253,10 @@ public: CAmount GetCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const; CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; CAmount GetChange(const CTransaction& tx) const; - void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, SaplingMerkleTree saplingTree, bool added); + void ChainTip( + const CBlockIndex *pindex, + const CBlock *pblock, + boost::optional> added); void RunSaplingConsolidation(int blockHeight); void CommitConsolidationTx(const CTransaction& tx); /** Saves witness caches and best block locator to disk. */ diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index c3783e97a..2f79e454b 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -309,7 +309,7 @@ double benchmark_increment_note_witnesses(size_t nTxs) index1.SetHeight(1); // Increment to get transactions witnessed - wallet.ChainTip(&index1, &block1, sproutTree, saplingTree, true); + wallet.ChainTip(&index1, &block1, std::make_pair(sproutTree, saplingTree)); // Second block CBlock block2; @@ -333,7 +333,7 @@ double benchmark_increment_note_witnesses(size_t nTxs) struct timeval tv_start; timer_start(tv_start); - wallet.ChainTip(&index2, &block2, sproutTree, saplingTree, true); + wallet.ChainTip(&index2, &block2, std::make_pair(sproutTree, saplingTree)); return timer_stop(tv_start); } From a2c8f752dfac11d039c7e37f87b004cca4496ace Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 13:58:22 -0500 Subject: [PATCH 037/220] Pull in validation interface changes from zcash commit 26a24da74503ae60cc9aa2d6e6ae0923ecd375fb --- src/validationinterface.cpp | 131 +++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 11 deletions(-) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index f3bca6205..aa66ef7c7 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php . #include "validationinterface.h" @@ -28,15 +28,18 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.RescanWallet.connect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn)); g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3)); g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); + g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); + g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); @@ -45,11 +48,12 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); - g_signals.RescanWallet.disconnect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn)); g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1)); } void UnregisterAllValidationInterfaces() { + g_signals.BlockFound.disconnect_all_slots(); + g_signals.ScriptForMining.disconnect_all_slots(); g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); @@ -58,7 +62,6 @@ void UnregisterAllValidationInterfaces() { g_signals.UpdatedTransaction.disconnect_all_slots(); g_signals.EraseTransaction.disconnect_all_slots(); g_signals.SyncTransaction.disconnect_all_slots(); - g_signals.RescanWallet.disconnect_all_slots(); g_signals.UpdatedBlockTip.disconnect_all_slots(); } @@ -129,13 +132,119 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) // Fetch recently-conflicted transactions. These will include any // block that has been connected since the last cycle, but we only // notify for the conflicts created by the current active chain. + recentlyConflicted = DrainRecentlyConflicted(); + + // Iterate backwards over the connected blocks we need to notify. + while (pindex && pindex != pindexFork) { + // Get the Sprout commitment tree as of the start of this block. + SproutMerkleTree oldSproutTree; + assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, oldSproutTree)); + + // Get the Sapling commitment tree as of the start of this block. + // We can get this from the `hashFinalSaplingRoot` of the last block + // However, this is only reliable if the last block was on or after + // the Sapling activation height. Otherwise, the last anchor was the + // empty root. + SaplingMerkleTree oldSaplingTree; + if (chainParams.GetConsensus().NetworkUpgradeActive( + pindex->pprev->nHeight, Consensus::UPGRADE_SAPLING)) { + assert(pcoinsTip->GetSaplingAnchorAt( + pindex->pprev->hashFinalSaplingRoot, oldSaplingTree)); + } else { + assert(pcoinsTip->GetSaplingAnchorAt(SaplingMerkleTree::empty_root(), oldSaplingTree)); + } + + blockStack.emplace_back( + pindex, + std::make_pair(oldSproutTree, oldSaplingTree), + recentlyConflicted.first.at(pindex)); + + pindex = pindex->pprev; + } + + recentlyAdded = mempool.DrainRecentlyAdded(); + } + + // + // Execute wallet logic based on the collected state. We MUST NOT take + // the cs_main or mempool.cs locks again until after the next sleep; + // doing so introduces a locking side-channel between this code and the + // network message processing thread. + // + + // Notify block disconnects + while (pindexLastTip && pindexLastTip != pindexFork) { + // Read block from disk. + CBlock block; + if (!ReadBlockFromDisk(block, pindexLastTip, chainParams.GetConsensus())) { + LogPrintf("*** %s\n", "Failed to read block while notifying wallets of block disconnects"); + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occurred, see debug.log for details"), + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + } + + // Let wallets know transactions went from 1-confirmed to + // 0-confirmed or conflicted: + for (const CTransaction &tx : block.vtx) { + SyncWithWallets(tx, NULL); + } + // Update cached incremental witnesses + GetMainSignals().ChainTip(pindexLastTip, &block, boost::none); + + // On to the next block! + pindexLastTip = pindexLastTip->pprev; + } + + // Notify block connections + while (!blockStack.empty()) { + auto blockData = blockStack.back(); + blockStack.pop_back(); + + // Read block from disk. + CBlock block; + if (!ReadBlockFromDisk(block, blockData.pindex, chainParams.GetConsensus())) { + LogPrintf("*** %s\n", "Failed to read block while notifying wallets of block connects"); + uiInterface.ThreadSafeMessageBox( + _("Error: A fatal internal error occurred, see debug.log for details"), + "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + } + + // Tell wallet about transactions that went from mempool + // to conflicted: + for (const CTransaction &tx : blockData.txConflicted) { + SyncWithWallets(tx, NULL); + } + // ... and about transactions that got confirmed: + for (const CTransaction &tx : block.vtx) { + SyncWithWallets(tx, &block); + } + // Update cached incremental witnesses + GetMainSignals().ChainTip(blockData.pindex, &block, blockData.oldTrees); + + // This block is done! + pindexLastTip = blockData.pindex; + } + + // Notify transactions in the mempool + for (auto tx : recentlyAdded.first) { + try { + SyncWithWallets(tx, NULL); + } catch (const boost::thread_interrupted&) { + throw; + } catch (const std::exception& e) { + PrintExceptionContinue(&e, "ThreadNotifyWallets()"); + } catch (...) { + PrintExceptionContinue(NULL, "ThreadNotifyWallets()"); + } + } + + // Update the notified sequence numbers. We only need this in regtest mode, + // and should not lock on cs or cs_main here otherwise. + if (chainParams.NetworkIDString() == "regtest") { + SetChainNotifiedSequence(recentlyConflicted.second); + mempool.SetNotifiedSequence(recentlyAdded.second); } } } -void EraseFromWallets(const uint256 &hash) { - g_signals.EraseTransaction(hash); -} - -void RescanWallets() { - g_signals.RescanWallet(); -} From 35c68602e78e9614e4ac999990c36590fe96f9fb Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 14:36:22 -0500 Subject: [PATCH 038/220] Port the BlockFound signal and parts of ScriptForMining from ZEC upstream --- src/miner.cpp | 3 +++ src/validationinterface.cpp | 6 +++--- src/validationinterface.h | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 5bc83fac4..8d3c5d4c4 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -983,6 +983,9 @@ static bool ProcessBlockFound(CBlock* pblock) } } + // Inform about the new block + GetMainSignals().BlockFound(pblock->GetHash()); + #ifdef ENABLE_WALLET // Remove key from key pool if ( IS_KOMODO_NOTARY == 0 ) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index aa66ef7c7..c93c9be08 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -33,13 +33,13 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); + //g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1)); - g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); + //g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1)); g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1)); g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); @@ -53,7 +53,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) { void UnregisterAllValidationInterfaces() { g_signals.BlockFound.disconnect_all_slots(); - g_signals.ScriptForMining.disconnect_all_slots(); + //g_signals.ScriptForMining.disconnect_all_slots(); g_signals.BlockChecked.disconnect_all_slots(); g_signals.Broadcast.disconnect_all_slots(); g_signals.Inventory.disconnect_all_slots(); diff --git a/src/validationinterface.h b/src/validationinterface.h index 33cd5728e..dea6e5547 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -69,6 +69,10 @@ struct CMainSignals { boost::signals2::signal Broadcast; /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; + // boost::signals2::signal&)> ScriptForMining; + /** Notifies listeners that a block has been successfully mined */ + boost::signals2::signal BlockFound; + }; CMainSignals& GetMainSignals(); From 3d7bed74c18b92fbc8c0caa3d8a4074002be145d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 17:22:41 -0500 Subject: [PATCH 039/220] Port more required code --- src/validationinterface.cpp | 2 +- src/validationinterface.h | 1 + src/wallet/wallet.h | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index c93c9be08..802b8b75c 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -147,7 +147,7 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) // empty root. SaplingMerkleTree oldSaplingTree; if (chainParams.GetConsensus().NetworkUpgradeActive( - pindex->pprev->nHeight, Consensus::UPGRADE_SAPLING)) { + pindex->pprev->GetHeight(), Consensus::UPGRADE_SAPLING)) { assert(pcoinsTip->GetSaplingAnchorAt( pindex->pprev->hashFinalSaplingRoot, oldSaplingTree)); } else { diff --git a/src/validationinterface.h b/src/validationinterface.h index dea6e5547..bc5477c99 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -43,6 +43,7 @@ protected: virtual void Inventory(const uint256 &hash) {} virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} + virtual void ResetRequestCount(const uint256 &hash) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0c3b96330..4673b584a 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1284,6 +1284,13 @@ public: } } + //void GetScriptForMining(boost::shared_ptr &script); + void ResetRequestCount(const uint256 &hash) + { + LOCK(cs_wallet); + mapRequestCount[hash] = 0; + }; + unsigned int GetKeyPoolSize() { AssertLockHeld(cs_wallet); // setKeyPool From 0f99a6ea3f28d81d069defcdc5e870e1f82849e2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 17:28:35 -0500 Subject: [PATCH 040/220] Port Network upgrade detection back to our KMD flavor --- src/validationinterface.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 802b8b75c..1c2d39495 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -146,10 +146,8 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) // the Sapling activation height. Otherwise, the last anchor was the // empty root. SaplingMerkleTree oldSaplingTree; - if (chainParams.GetConsensus().NetworkUpgradeActive( - pindex->pprev->GetHeight(), Consensus::UPGRADE_SAPLING)) { - assert(pcoinsTip->GetSaplingAnchorAt( - pindex->pprev->hashFinalSaplingRoot, oldSaplingTree)); + if (NetworkUpgradeActive(pindex->pprev->GetHeight(),Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { + assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, oldSaplingTree)); } else { assert(pcoinsTip->GetSaplingAnchorAt(SaplingMerkleTree::empty_root(), oldSaplingTree)); } From 61c2090dd63b2728d37fa6c3225d3560374f3359 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 17:48:34 -0500 Subject: [PATCH 041/220] Make the compiler Elder Gods happy --- src/init.cpp | 2 +- src/validationinterface.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 18c10d698..fccc16f6e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2143,7 +2143,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); LogPrintf("nBestHeight = %d\n", chainActive.Height()); #ifdef ENABLE_WALLET - RescanWallets(); + //RescanWallets(); LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0); LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 1c2d39495..799a60ceb 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -174,7 +174,7 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) while (pindexLastTip && pindexLastTip != pindexFork) { // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexLastTip, chainParams.GetConsensus())) { + if (!ReadBlockFromDisk(block, pindexLastTip,1)) { LogPrintf("*** %s\n", "Failed to read block while notifying wallets of block disconnects"); uiInterface.ThreadSafeMessageBox( _("Error: A fatal internal error occurred, see debug.log for details"), @@ -201,7 +201,7 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, blockData.pindex, chainParams.GetConsensus())) { + if (!ReadBlockFromDisk(block, blockData.pindex, 1)) { LogPrintf("*** %s\n", "Failed to read block while notifying wallets of block connects"); uiInterface.ThreadSafeMessageBox( _("Error: A fatal internal error occurred, see debug.log for details"), From 13b59f00ce9259c0285d9b3227d00c2388461881 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 7 Mar 2020 21:30:51 -0500 Subject: [PATCH 042/220] Clean up --- src/init.cpp | 4 +--- src/main.cpp | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index fccc16f6e..d513d0a06 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -2143,8 +2143,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size()); LogPrintf("nBestHeight = %d\n", chainActive.Height()); #ifdef ENABLE_WALLET - //RescanWallets(); - LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0); LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0); LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0); diff --git a/src/main.cpp b/src/main.cpp index 848e5422a..af8191782 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2060,8 +2060,6 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } } } - // This should be here still? - //SyncWithWallets(tx, NULL); return true; } @@ -5319,11 +5317,6 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C return(false); } - // if (ptx) - // { - // SyncWithWallets(*ptx, &block); - // } - if ( ASSETCHAINS_CC != 0 ) { LOCK2(cs_main,mempool.cs); From 699b59037af175efe4a85da6b62bb57c5a63f744 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 8 Mar 2020 08:55:42 -0400 Subject: [PATCH 043/220] Bump version to 3.3.2 --- configure.ac | 2 +- src/clientversion.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0f83b1e8f..cf712cc67 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) define(_CLIENT_VERSION_MINOR, 3) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/src/clientversion.h b/src/clientversion.h index eaa792d62..71fcee16f 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -34,7 +34,7 @@ // Must be kept in sync with configure.ac ! #define CLIENT_VERSION_MAJOR 3 #define CLIENT_VERSION_MINOR 3 -#define CLIENT_VERSION_REVISION 1 +#define CLIENT_VERSION_REVISION 2 #define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build From 5870f6f059249e54411f1027b839264cbf4b38d6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 8 Mar 2020 09:06:06 -0400 Subject: [PATCH 044/220] Update unix man pages --- doc/man/hush-cli.1 | 8 ++++---- doc/man/hush-tx.1 | 8 ++++---- doc/man/hushd.1 | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/doc/man/hush-cli.1 b/doc/man/hush-cli.1 index a1be67812..0c9080b59 100644 --- a/doc/man/hush-cli.1 +++ b/doc/man/hush-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSH-CLI "1" "January 2020" "hush-cli v3.3.1" "User Commands" +.TH HUSH-CLI "1" "March 2020" "hush-cli v3.3.2" "User Commands" .SH NAME -hush-cli \- manual page for hush-cli v3.3.1 +hush-cli \- manual page for hush-cli v3.3.2 .SH DESCRIPTION -Komodo RPC client version v3.3.1\-d4ac8162f +Komodo RPC client version v3.3.2\-699b59037 .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . @@ -71,7 +71,7 @@ Timeout in seconds during HTTP requests, or 0 for no timeout. (default: Read extra arguments from standard input, one per line until EOF/Ctrl\-D (recommended for sensitive information such as passphrases) .SH COPYRIGHT -Hush Daemon version v3.3.1-d4ac8162f +Hush Daemon version v3.3.2-699b59037 In order to ensure you are adequately protecting your privacy when using Hush, please see . diff --git a/doc/man/hush-tx.1 b/doc/man/hush-tx.1 index b707fd059..9004dcade 100644 --- a/doc/man/hush-tx.1 +++ b/doc/man/hush-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSH-TX "1" "January 2020" "hush-tx v3.3.1" "User Commands" +.TH HUSH-TX "1" "March 2020" "hush-tx v3.3.2" "User Commands" .SH NAME -hush-tx \- manual page for hush-tx v3.3.1 +hush-tx \- manual page for hush-tx v3.3.2 .SH DESCRIPTION -Hush komodo\-tx utility version v3.3.1\-d4ac8162f +Hush komodo\-tx utility version v3.3.2\-699b59037 .SS "Usage:" .TP komodo\-tx [options] [commands] @@ -84,7 +84,7 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT -Hush Daemon version v3.3.1-d4ac8162f +Hush Daemon version v3.3.2-699b59037 In order to ensure you are adequately protecting your privacy when using Hush, please see . diff --git a/doc/man/hushd.1 b/doc/man/hushd.1 index 0c47538ea..0cde080df 100644 --- a/doc/man/hushd.1 +++ b/doc/man/hushd.1 @@ -1,10 +1,10 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSHD "1" "January 2020" "hushd v3.3.1" "User Commands" +.TH HUSHD "1" "March 2020" "hushd v3.3.2" "User Commands" .SH NAME -hushd \- manual page for hushd v3.3.1 +hushd \- manual page for hushd v3.3.2 .SH DESCRIPTION Found binary: ./komodod -Hush Daemon version v3.3.1\-d4ac8162f +Hush Daemon version v3.3.2\-699b59037 .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . @@ -265,6 +265,36 @@ Do not load the wallet and disable wallet RPC calls .IP Set key pool size to (default: 100) .HP +\fB\-consolidation\fR +.IP +Enable auto Sapling note consolidation (default: false) +.HP +\fB\-consolidatesaplingaddress=\fR +.IP +Specify Sapling Address to Consolidate. (default: all) +.HP +\fB\-consolidationtxfee\fR +.IP +Fee amount in Puposhis used send consolidation transactions. (default +10000) +.HP +\fB\-deletetx\fR +.IP +Enable Old Transaction Deletion +.HP +\fB\-deleteinterval\fR +.IP +Delete transaction every blocks during inital block download +(default: 1000) +.HP +\fB\-keeptxnum\fR +.IP +Keep the last transactions (default: 200) +.HP +\fB\-keeptxfornblocks\fR +.IP +Keep transactions for at least blocks (default: 10000) +.HP \fB\-paytxfee=\fR .IP Fee (in KMD/kB) to add to transactions you send (default: 0.00) @@ -358,7 +388,7 @@ Debugging/Testing options: Output debugging information (default: 0, supplying is optional). If is not supplied or if = 1, output all debugging information. can be: addrman, alert, bench, -coindb, db, estimatefee, http, libevent, lock, mempool, net, +coindb, db, deletetx, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc). .HP @@ -599,7 +629,7 @@ Starting supply, default is 0 .IP Enforce transaction\-rate limit, default 0 .SH COPYRIGHT -Hush Daemon version v3.3.1-d4ac8162f +Hush Daemon version v3.3.2-699b59037 In order to ensure you are adequately protecting your privacy when using Hush, please see . From 9c4acae5fd2814314dcd142878529ebb30a38669 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 10:32:29 -0400 Subject: [PATCH 045/220] Move this inside another lexical scope to hopefully avoid compiler bugs in gcc 8.3 and clang 9.0 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index af8191782..d069c7068 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4157,8 +4157,8 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * assert(pindexNew->pprev == chainActive.Tip()); // Read block from disk. int64_t nTime1 = GetTimeMicros(); - CBlock block; if (!pblock) { + CBlock block; if (!ReadBlockFromDisk(block, pindexNew,1)) return AbortNode(state, "Failed to read block"); pblock = █ From ad4d87c653ca9e2cbc185768bfd201ab695c7016 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 11:04:36 -0400 Subject: [PATCH 046/220] Fix ConnectTip() from thread_notify merge --- src/main.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d069c7068..bed9d6ac8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4157,8 +4157,8 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * assert(pindexNew->pprev == chainActive.Tip()); // Read block from disk. int64_t nTime1 = GetTimeMicros(); + CBlock block; if (!pblock) { - CBlock block; if (!ReadBlockFromDisk(block, pindexNew,1)) return AbortNode(state, "Failed to read block"); pblock = █ @@ -4203,6 +4203,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * } int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); + // Remove conflicting transactions from the mempool. std::list txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload()); @@ -4212,8 +4213,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * // Update chainActive & related variables. UpdateTip(pindexNew); - if ( KOMODO_NSPV_FULLNODE ) - { // Cache the conflicted transactions for subsequent notification. // Updates to connected wallets are triggered by ThreadNotifyWallets @@ -4254,7 +4253,6 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * //fprintf(stderr,"%s: returning true\n", __FUNCTION__); return true; } -} std::pair>, uint64_t> DrainRecentlyConflicted() { uint64_t recentlyConflictedSequence; From 2aa376d286f9594c157ad1c1c7df58e2922d26d2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 16:31:54 -0400 Subject: [PATCH 047/220] Add z_getinfo, a place for various shielded details that do not fit other places --- src/init.cpp | 2 +- src/wallet/rpcwallet.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index d513d0a06..495394a4d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1936,7 +1936,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pwalletMain->GenerateNewSeed(); } - //Set Sapling Consolidation + //Set Sapling Consolidation pwalletMain->fSaplingConsolidationEnabled = GetBoolArg("-consolidation", false); fConsolidationTxFee = GetArg("-consolidationtxfee", DEFAULT_CONSOLIDATION_FEE); fConsolidationMapUsed = !mapMultiArgs["-consolidatesaplingaddress"].empty(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ea4b43a5a..c9a135173 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -79,6 +79,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only CBlockIndex *komodo_getblockindex(uint256 hash); extern string randomSietchZaddr(); +extern CAmount fConsolidationTxFee; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -3479,6 +3480,33 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey& return ret; } +UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) +{ + if (fHelp || params.size() > 0) { + throw runtime_error( + "z_getinfo\n" + "\nReturns various information about shielded operations, such as sapling consolidation details.\n" + ); + } + UniValue result(UniValue::VOBJ); + result.push_back(Pair("consolidation_enabled",(bool)pwalletMain->fSaplingConsolidationEnabled )); + result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); + result.push_back(Pair("deletetx",(int)fTxDeleteEnabled)); + result.push_back(Pair("delete_interval",(int)fDeleteInterval)); + result.push_back(Pair("keeptxnum",(int)fKeepLastNTransactions)); + result.push_back(Pair("keeptxfornblocks",(int)fDeleteTransactionsAfterNBlocks)); + + std::set saplingzaddrs = {}; + pwalletMain->GetSaplingPaymentAddresses(saplingzaddrs); + result.push_back(Pair("num_sapling_zaddrs",(int)saplingzaddrs.size())); + + std::shared_ptr q = getAsyncRPCQueue(); + std::vector ids = q->getAllOperationIds(); + result.push_back(Pair("num_op_ids",(int)ids.size())); + + return result; +} + UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { if (!EnsureWalletIsAvailable(fHelp)) @@ -8326,6 +8354,7 @@ static const CRPCCommand commands[] = { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, { "wallet", "z_viewtransaction", &z_viewtransaction, true }, + { "wallet", "z_getinfo", &z_getinfo, true }, { "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true }, // TODO: rearrange into another category From 67f666d5ff25ce82c3a7a13912fb29477343fbb1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 18:42:13 -0400 Subject: [PATCH 048/220] Tweak z_getinfo data slightly --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c9a135173..4c1564db1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3489,9 +3489,9 @@ UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) ); } UniValue result(UniValue::VOBJ); - result.push_back(Pair("consolidation_enabled",(bool)pwalletMain->fSaplingConsolidationEnabled )); + result.push_back(Pair("consolidation",(bool)pwalletMain->fSaplingConsolidationEnabled )); result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); - result.push_back(Pair("deletetx",(int)fTxDeleteEnabled)); + result.push_back(Pair("deletetx",(bool)fTxDeleteEnabled)); result.push_back(Pair("delete_interval",(int)fDeleteInterval)); result.push_back(Pair("keeptxnum",(int)fKeepLastNTransactions)); result.push_back(Pair("keeptxfornblocks",(int)fDeleteTransactionsAfterNBlocks)); From e4bfafc76cc26ba6af26eb569cab43b7535979ac Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:02:52 -0400 Subject: [PATCH 049/220] Better error checking in consolidation for when CommitTransaction() fails --- .../asyncrpcoperation_saplingconsolidation.cpp | 12 ++++++++---- src/wallet/wallet.cpp | 4 ++-- src/wallet/wallet.h | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index e85ce5861..da0d4b94c 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -209,10 +209,14 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { break; } - pwalletMain->CommitConsolidationTx(tx); - LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); - amountConsolidated += amountToSend - fConsolidationTxFee; - consolidationTxIds.push_back(tx.GetHash().ToString()); + if(pwalletMain->CommitConsolidationTx(tx)) { + LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); + amountConsolidated += amountToSend - fConsolidationTxFee; + consolidationTxIds.push_back(tx.GetHash().ToString()); + } else { + LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + return false; + } } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f8127e83d..df40a53ff 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -637,10 +637,10 @@ void CWallet::RunSaplingConsolidation(int blockHeight) { } } -void CWallet::CommitConsolidationTx(const CTransaction& tx) { +bool CWallet::CommitConsolidationTx(const CTransaction& tx) { CWalletTx wtx(this, tx); CReserveKey reservekey(pwalletMain); - CommitTransaction(wtx, reservekey); + return CommitTransaction(wtx, reservekey); } void CWallet::SetBestChain(const CBlockLocator& loc) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d9dc9e0a1..3dd658acb 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1258,7 +1258,7 @@ public: const CBlock *pblock, boost::optional> added); void RunSaplingConsolidation(int blockHeight); - void CommitConsolidationTx(const CTransaction& tx); + bool CommitConsolidationTx(const CTransaction& tx); /** Saves witness caches and best block locator to disk. */ void SetBestChain(const CBlockLocator& loc); std::set> GetNullifiersForAddresses(const std::set & addresses); From 744ef344381854cf3f7683fc176e75c80c2211ef Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:04:53 -0400 Subject: [PATCH 050/220] Add zindex to z_getinfo --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4c1564db1..c62a0552e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -80,6 +80,7 @@ int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private CBlockIndex *komodo_getblockindex(uint256 hash); extern string randomSietchZaddr(); extern CAmount fConsolidationTxFee; +extern bool fZindex; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -3489,6 +3490,7 @@ UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) ); } UniValue result(UniValue::VOBJ); + result.push_back(Pair("zindex",(bool)fZindex)); result.push_back(Pair("consolidation",(bool)pwalletMain->fSaplingConsolidationEnabled )); result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); result.push_back(Pair("deletetx",(bool)fTxDeleteEnabled)); From 736aa8cfaf8ac14dd59626c14470e92e1054df17 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:27:49 -0400 Subject: [PATCH 051/220] Add more data to failed consolidation ops --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index da0d4b94c..3ffb048ae 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -215,6 +215,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { consolidationTxIds.push_back(tx.GetHash().ToString()); } else { LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); return false; } From d8477c4d7bae3e619b3c1719f2c7a2a379d3d292 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:28:09 -0400 Subject: [PATCH 052/220] Remove some more sprout code, yay --- src/wallet/wallet.cpp | 122 +----------------------------------------- 1 file changed, 1 insertion(+), 121 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index df40a53ff..4c35c16e2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1173,96 +1173,6 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO auto wtxHash = wtxItem.second.GetHash(); int wtxHeight = mapBlockIndex[wtxItem.second.hashBlock]->GetHeight(); - for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { - - auto op = item.first; - auto* nd = &(item.second); - CBlockIndex* pblockindex; - uint256 blockRoot; - uint256 witnessRoot; - - if (!nd->nullifier) - ::ClearSingleNoteWitnessCache(nd); - - if (!nd->witnesses.empty() && nd->witnessHeight > 0) { - - //Skip all functions for validated witness while witness only = true - if (nd->witnessRootValidated && witnessOnly) - continue; - - //Skip Validation when witness root has been validated - if (nd->witnessRootValidated) { - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - - //Skip Validation when witness height is greater that block height - if (nd->witnessHeight > pindex->GetHeight() - 1) { - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - - //Validate the witness at the witness height - witnessRoot = nd->witnesses.front().root(); - pblockindex = chainActive[nd->witnessHeight]; - blockRoot = pblockindex->hashFinalSproutRoot; - if (witnessRoot == blockRoot) { - nd->witnessRootValidated = true; - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - } - - //Clear witness Cache for all other scenarios - pblockindex = chainActive[wtxHeight]; - ::ClearSingleNoteWitnessCache(nd); - - LogPrintf("Setting Inital Sprout Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); - - SproutMerkleTree sproutTree; - blockRoot = pblockindex->pprev->hashFinalSproutRoot; - pcoinsTip->GetSproutAnchorAt(blockRoot, sproutTree); - - //Cycle through blocks and transactions building sprout tree until the commitment needed is reached - const CBlock* pblock; - CBlock block; - ReadBlockFromDisk(block, pblockindex, 1); - pblock = █ - - for (const CTransaction& tx : block.vtx) { - auto hash = tx.GetHash(); - - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; - for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { - const uint256& note_commitment = jsdesc.commitments[j]; - - // Increment existing witness until the end of the block - if (!nd->witnesses.empty()) { - nd->witnesses.front().append(note_commitment); - } - - //Only needed for intial witness - if (nd->witnesses.empty()) { - sproutTree.append(note_commitment); - - // If this is our note, witness it - if (hash == wtxHash) { - JSOutPoint outPoint {hash, i, j}; - if (op == outPoint) { - nd->witnesses.push_front(sproutTree.witness()); - } - } - } - } - } - } - - nd->witnessHeight = pblockindex->GetHeight(); - UpdateSproutNullifierNoteMapWithTx(wtxItem.second); - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - } - for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { auto op = item.first; @@ -1307,7 +1217,7 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO pblockindex = chainActive[wtxHeight]; ::ClearSingleNoteWitnessCache(nd); - LogPrintf("Setting Inital Sapling Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); + LogPrintf("Setting Initial Sapling Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); SaplingMerkleTree saplingTree; blockRoot = pblockindex->pprev->hashFinalSaplingRoot; @@ -1396,31 +1306,6 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) if (wtxItem.second.GetDepthInMainChain() > 0) { - //Sprout - for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { - auto* nd = &(item.second); - if (nd->nullifier && nd->witnessHeight == pblockindex->GetHeight() - 1 - && GetSproutSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { - - - nd->witnesses.push_front(nd->witnesses.front()); - while (nd->witnesses.size() > WITNESS_CACHE_SIZE) { - nd->witnesses.pop_back(); - } - - for (const CTransaction& tx : block.vtx) { - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; - for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { - const uint256& note_commitment = jsdesc.commitments[j]; - nd->witnesses.front().append(note_commitment); - } - } - } - nd->witnessHeight = pblockindex->GetHeight(); - } - } - //Sapling for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { auto* nd = &(item.second); @@ -1639,11 +1524,6 @@ void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx) { { LOCK(cs_wallet); - for (const mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) { - if (item.second.nullifier) { - mapSproutNullifiersToNotes[*item.second.nullifier] = item.first; - } - } for (const mapSaplingNoteData_t::value_type& item : wtx.mapSaplingNoteData) { if (item.second.nullifier) { From 41662dc37079a56e6130128cb919a0e65110bee1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 10 Mar 2020 07:22:14 -0400 Subject: [PATCH 053/220] Remove sprout-related RPC docs --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c62a0552e..b54775d1a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3881,7 +3881,7 @@ UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk throw runtime_error( "z_getnewaddress ( type )\n" "\nReturns a new shielded address for receiving payments.\n" - "\nWith no arguments, returns a Sprout address.\n" + "\nWith no arguments, returns a Sapling address.\n" "\nArguments:\n" "1. \"type\" (string, optional, default=\"" + defaultType + "\") The type of address. One of [\"" + ADDR_TYPE_SAPLING + "\"].\n" @@ -5177,7 +5177,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp "4. transparent_limit (numeric, optional, default=" + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n" "4. shielded_limit (numeric, optional, default=" - + strprintf("%d Sprout or %d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT, MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" + + strprintf("%d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" "5. maximum_utxo_size (numeric, optional) eg, 0.0001 anything under 10000 satoshies will be merged, ignores 10,000 sat p2pk utxo that iguana uses, and merges coinbase utxo.\n" "6. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n" From 1beb2b1fa8bbd79fb2c8445cd48334f1e854b038 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 10 Mar 2020 07:22:23 -0400 Subject: [PATCH 054/220] Remove more sprouty code --- src/wallet/wallet.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4c35c16e2..2fb192e1e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1911,14 +1911,6 @@ void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx) if (mapWallet.count(txin.prevout.hash)) mapWallet[txin.prevout.hash].MarkDirty(); } - for (const JSDescription& jsdesc : tx.vjoinsplit) { - for (const uint256& nullifier : jsdesc.nullifiers) { - if (mapSproutNullifiersToNotes.count(nullifier) && - mapWallet.count(mapSproutNullifiersToNotes[nullifier].hash)) { - mapWallet[mapSproutNullifiersToNotes[nullifier].hash].MarkDirty(); - } - } - } for (const SpendDescription &spend : tx.vShieldedSpend) { uint256 nullifier = spend.nullifier; From 968890c5919cbcc739cd60647037f4c25ed4cdb4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 10 Mar 2020 09:10:05 -0400 Subject: [PATCH 055/220] More error checking and use a CAmount instead of int, which hopefully fixes CommitTransaction() bug --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 3ffb048ae..f8d6b017a 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -181,6 +181,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); + LogPrint("zrpcunsafe", "%s: Added consolidation output", getId(), addr); // Add sietch zouts int MIN_ZOUTS = 7; @@ -191,8 +192,11 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); - int amount=0; + CAmount amount=0; builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); + } else { + LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId(), zaddr); + break; } } //CTransaction tx = builder.Build(); From c271fb8cbde9b7e575a3759598750f1c79e374d7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 10 Mar 2020 09:10:12 -0400 Subject: [PATCH 056/220] Locks and docs --- src/wallet/rpcwallet.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b54775d1a..b8115767a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3483,12 +3483,21 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey& UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) { + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + if (fHelp || params.size() > 0) { throw runtime_error( "z_getinfo\n" "\nReturns various information about shielded operations, such as sapling consolidation details.\n" + "\nExamples:\n" + + HelpExampleCli("z_getinfo", "") + + HelpExampleRpc("z_getinfo", "") ); } + + LOCK2(cs_main, pwalletMain->cs_wallet); + UniValue result(UniValue::VOBJ); result.push_back(Pair("zindex",(bool)fZindex)); result.push_back(Pair("consolidation",(bool)pwalletMain->fSaplingConsolidationEnabled )); From 378b1e3e74e797511c955d2572b85ce520983396 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 08:44:00 -0400 Subject: [PATCH 057/220] Update coinsupply rpc docs --- src/rpc/misc.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a60f01290..fc4b39ef0 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -420,12 +420,12 @@ UniValue coinsupply(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nResult:\n" "{\n" " \"result\" : \"success\", (string) If the request was successful.\n" - " \"coin\" : \"KMD\", (string) The currency symbol of the coin for asset chains, otherwise KMD.\n" + " \"coin\" : \"HUSH3\", (string) The currency symbol of the coin for asset chains, otherwise HUSH3.\n" " \"height\" : 420, (integer) The height of this coin supply data\n" - " \"supply\" : \"777.0\", (float) The transparent coin supply\n" - " \"zfunds\" : \"0.777\", (float) The shielded coin supply (in zaddrs)\n" - " \"sprout\" : \"0.077\", (float) The sprout coin supply (in zcaddrs)\n" - " \"total\" : \"777.777\", (float) The total coin supply, i.e. sum of supply + zfunds\n" + " \"supply\" : \"555.0\", (float) The transparent coin supply\n" + " \"zfunds\" : \"0.55555\", (float) The shielded coin supply (in zaddrs)\n" + " \"sprout\" : \"0.000\", (float) The sprout coin supply (in zcaddrs)\n" + " \"total\" : \"555.55555\", (float) The total coin supply, i.e. sum of supply + zfunds\n" "}\n" "\nExamples:\n" + HelpExampleCli("coinsupply", "420") From 7691e89b1bcd80336dfff4989fbbdefee2054daf Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 08:48:54 -0400 Subject: [PATCH 058/220] We got rid of this verus bug: fatal error: OCTET_STRING.h, yay --- DEVELOPING.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 15942011d..c64fb5f4f 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -25,14 +25,8 @@ sometimes introduce weird bugs or make compiling really annoying. Switching branches and doing partial compiles in Komodo/Hush source code can introduce weird bugs, which are fixed by running `build.sh` again. -When in doubt, if you run into a compile error, especially if it mentions -`OCTET_STRING`, run `build.sh` again. Running `make clean` before switching -branches can often prevent those problems. - -``` -cryptoconditions/src/asn/SimpleSha256Condition.h:14:10: fatal error: OCTET_STRING.h: No such file or directory -``` - +Additionally, it's a good idea to run `make clean` before you switch +between branches. ## Partial compiles @@ -60,3 +54,7 @@ After successfully compiling Hush, you can generate a debian package of these bi This command will not work on Mac OS X. Currently you cannot generate a Debian package from operating systems other than Linux. + +## Updates to this document + +If you think something else should be in this guide, please send your suggestions! From d81ab5c9c752ed6f6b66a51fd9b95a2ebb58902b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 10:45:04 -0400 Subject: [PATCH 059/220] I think this should fix some compile issues --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index f8d6b017a..80034b109 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -181,21 +181,21 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output", getId(), addr); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr); // Add sietch zouts int MIN_ZOUTS = 7; for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - LogPrint("zrpcunsafe", "%s: Adding sietch output", getId(), zdust); + LogPrint("zrpcunsafe", "%s: Adding sietch output %s", getId(), zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); CAmount amount=0; builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId(), zaddr); + LogPrint("zrpcunsafe", "%s: Invalid payment address %s! Stopping.", getId(), zaddr); break; } } From c0c7d497d03fb07581da822b9b3755a3daa3c5a0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 15:03:23 -0400 Subject: [PATCH 060/220] Fix compile issues and hopefully better logging of consolidation --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 80034b109..47570aca3 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -181,21 +181,22 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr.GetHash().ToString().c_str() ); + // Add sietch zouts int MIN_ZOUTS = 7; for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - LogPrint("zrpcunsafe", "%s: Adding sietch output %s", getId(), zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); + LogPrint("zrpcunsafe", "%s: Adding sietch output %s", getId(), sietchZoutput.GetHash().ToString().c_str() ); CAmount amount=0; builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrint("zrpcunsafe", "%s: Invalid payment address %s! Stopping.", getId(), zaddr); + LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId()); break; } } From f3cc3b25df6ce2dbc68caff54616cf104f12631f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 21:06:09 -0400 Subject: [PATCH 061/220] Fix compiling komodo_curve25519.h on ARMv8 --- src/komodo_curve25519.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_curve25519.h b/src/komodo_curve25519.h index cba40561b..fd65b9ae3 100644 --- a/src/komodo_curve25519.h +++ b/src/komodo_curve25519.h @@ -81,7 +81,7 @@ bits320 fexpand(bits256 basepoint) return(out); } -#if __amd64__ +#if defined(__amd64__) || defined(__aarch64) // donna: special gcc mode for 128-bit integers. It's implemented on 64-bit platforms only as far as I know. typedef unsigned uint128_t __attribute__((mode(TI))); From 2439e5106b841ff3aedbeae85d9215e2a43d4c94 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 14 Mar 2020 21:23:58 -0400 Subject: [PATCH 062/220] Port zcash/zcash#4390 and the included bitcoin/bitcoin#8063 --- src/init.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 495394a4d..c1fb407ac 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2078,10 +2078,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // original value of chainActive.Tip(), which corresponds with the wallet's // view of the chaintip, is passed to ThreadNotifyWallets before the chain // tip changes again. - boost::function threadnotifywallets = boost::bind(&ThreadNotifyWallets, chainActive.Tip()); - threadGroup.create_thread( - boost::bind(&TraceThread>, "txnotify", threadnotifywallets) - ); + { + CBlockIndex *pindexLastTip; + { + LOCK(cs_main); + pindexLastTip = chainActive.Tip(); + } + boost::function threadnotifywallets = boost::bind(&ThreadNotifyWallets, pindexLastTip); + threadGroup.create_thread( + boost::bind(&TraceThread>, "txnotify", threadnotifywallets) + ); + } // ********************************************************* Step 9: data directory maintenance @@ -2124,10 +2131,22 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); - if (chainActive.Tip() == NULL) { - LogPrintf("Waiting for genesis block to be imported...\n"); - while (!fRequestShutdown && chainActive.Tip() == NULL) + + // Wait for genesis block to be processed + bool fHaveGenesis = false; + while (!fHaveGenesis && !fRequestShutdown) { + { + LOCK(cs_main); + fHaveGenesis = (chainActive.Tip() != NULL); MilliSleep(10); + } + + if (!fHaveGenesis) { + MilliSleep(10); + } + } + if (!fHaveGenesis) { + return false; } // ********************************************************* Step 11: start node From c7cd5d544913fb71af622873f705e4f633a98de9 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 15 Mar 2020 02:29:59 -0400 Subject: [PATCH 063/220] boost dep upgraded to 1.72.0 --- depends/packages/boost.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 800c424c5..48c60710d 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1_66_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.66.0/source -$(package)_sha256_hash=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9 +$(package)_version=1_72_0 +$(package)_download_path=https://dl.bintray.com/boostorg/release/1.72.0/source/ +$(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 $(package)_file_name=$(package)_$($(package)_version).tar.bz2 define $(package)_set_vars From 6605434eda27fe66ea419d1e1076202037c7d9cb Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 15 Mar 2020 02:42:30 -0400 Subject: [PATCH 064/220] upgraded dep libcurl 7.67.0 --- depends/packages/libcurl.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index 159817139..fd82dc4e0 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -1,9 +1,9 @@ package=libcurl -$(package)_version=7.64.1 +$(package)_version=7.67.0 $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.gz -$(package)_sha256_hash=432d3f466644b9416bc5b649d344116a753aeaa520c8beaf024a90cba9d3d35d +$(package)_sha256_hash=52af3361cf806330b88b4fe6f483b6844209d47ae196ac46da4de59bb361ab02 $(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-unknown-linux-gnu $(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32 $(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) From 5a0c3ac22bdaecd2fbf9ffd2e14368b9a8732a89 Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 15 Mar 2020 03:09:34 -0400 Subject: [PATCH 065/220] updated proton dep 0.26.0 --- depends/packages/proton.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/proton.mk b/depends/packages/proton.mk index 39428f54b..1bb5c8865 100644 --- a/depends/packages/proton.mk +++ b/depends/packages/proton.mk @@ -1,8 +1,8 @@ package=proton -$(package)_version=0.17.0 +$(package)_version=0.26.0 $(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version) $(package)_file_name=qpid-proton-$($(package)_version).tar.gz -$(package)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a +$(package)_sha256_hash=0eddac870f0085b9aeb0c9da333bd3f53fedb7c872164171a7cc06761ddbbd75 $(package)_patches=minimal-build.patch define $(package)_preprocess_cmds @@ -11,7 +11,7 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_PHP=OFF -DBUILD_JAVA=OFF -DBUILD_PERL=OFF -DBUILD_RUBY=OFF -DBUILD_JAVASCRIPT=OFF -DBUILD_GO=OFF + cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_PHP=OFF -DBUILD_JAVA=OFF -DBUILD_PERL=OFF -DBUILD_RUBY=OFF -DBUILD_JAVASCRIPT=OFF -DBUILD_GO=OFF -DBUILD_STATIC_LIBS=ON endef define $(package)_build_cmds From d5534ef04134c4d19f7f138efd460b32a87c857e Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 15 Mar 2020 03:11:20 -0400 Subject: [PATCH 066/220] updated deps native_ccache 3.7.4 --- depends/packages/native_ccache.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index b63c18b90..ac2bb9f28 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.3.1 -$(package)_download_path=https://www.samba.org/ftp/ccache -$(package)_file_name=ccache-$($(package)_version).tar.bz2 -$(package)_sha256_hash=cb6e4bafbb19ba0a2ec43386b123a5f92a20e1e3384c071d5d13e0cb3c84bf73 +$(package)_version=3.7.4 +$(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version) +$(package)_file_name=ccache-$($(package)_version).tar.xz +$(package)_sha256_hash=04c0af414b8cf89e541daed59735547fbfd323b1aaa983da0216f6b6731e6836 define $(package)_set_vars $(package)_config_opts= From 327609707fc2ecbf9f5c99a4e8a102b6fd1afc3c Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 15 Mar 2020 03:16:12 -0400 Subject: [PATCH 067/220] updated deps native_ccache 3.7.7 --- depends/packages/native_ccache.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index ac2bb9f28..b3693cc6f 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.7.4 +$(package)_version=3.7.7 $(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version) $(package)_file_name=ccache-$($(package)_version).tar.xz -$(package)_sha256_hash=04c0af414b8cf89e541daed59735547fbfd323b1aaa983da0216f6b6731e6836 +$(package)_sha256_hash=b7c1d6d6fe42f18e424de92746af863e0bc85794da3d69e44300840c478c98cd define $(package)_set_vars $(package)_config_opts= From 3740f2df717226bb11d9e86e96ec68b43455f376 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 15 Mar 2020 07:00:36 -0400 Subject: [PATCH 068/220] Add build-arm.sh from @radix42 --- zcutil/build-arm.sh | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 zcutil/build-arm.sh diff --git a/zcutil/build-arm.sh b/zcutil/build-arm.sh new file mode 100644 index 000000000..2131fa7cb --- /dev/null +++ b/zcutil/build-arm.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright (c) 2019-2020 radix42 +# Copyright (c) 2019-2020 The Hush developers +# Original aarch64 port by radix42. Thank you! + +set -eu -o pipefail + +cat <<'EOF' + ________________ +< Building Hush! > + ---------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +EOF + +if [ "x$*" = 'x--help' ] +then + cat ./zcutil/dragon.txt + cat < Date: Sun, 15 Mar 2020 09:27:39 -0400 Subject: [PATCH 069/220] Add hushd help for -opretmintxfee --- src/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index c1fb407ac..ac15db192 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -458,8 +458,8 @@ std::string HelpMessage(HelpMessageMode mode) if (showDebug) strUsage += HelpMessageOpt("-mintxfee=", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), - CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-opretmintxfee=", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 )); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); From 2e68231e130a6ac4323d56d8ae1cf1c9497cdf62 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 15 Mar 2020 15:17:41 -0400 Subject: [PATCH 070/220] Better 64bit check --- src/komodo_curve25519.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/komodo_curve25519.h b/src/komodo_curve25519.h index fd65b9ae3..b2f3ea49f 100644 --- a/src/komodo_curve25519.h +++ b/src/komodo_curve25519.h @@ -81,7 +81,8 @@ bits320 fexpand(bits256 basepoint) return(out); } -#if defined(__amd64__) || defined(__aarch64) +#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) || defined(_M_IA64) + // donna: special gcc mode for 128-bit integers. It's implemented on 64-bit platforms only as far as I know. typedef unsigned uint128_t __attribute__((mode(TI))); From 707d50e89496b4517a5293eceda54b22e09950f7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 15 Mar 2020 15:18:00 -0400 Subject: [PATCH 071/220] Only malloc_trim on unix+windows --- src/wallet/wallet.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2fb192e1e..20e137dc7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2951,8 +2951,12 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) { return; } } - // Miodrag: release memory back to the OS +#if defined(__unix__) || defined(_WIN64) + // Miodrag: release memory back to the OS malloc_trim(0); +#else + //TODO: This doesn't work on Mac +#endif } void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { From 2e51538df8d5602e757c383cc7232454aee7a195 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 16 Mar 2020 07:58:12 -0400 Subject: [PATCH 072/220] Add some debug --- src/transaction_builder.cpp | 2 ++ src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 3 ++- src/wallet/wallet.cpp | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 773792ba3..3964617ca 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -153,6 +153,7 @@ boost::optional TransactionBuilder::Build() // Send change to the specified change address. If no change address // was set, send change to the first Sapling address given as input. if (zChangeAddr) { + LogPrintf("%s: Adding specified Sapling change output: %s\n", __FUNCTION__, zChangeAddr->second.GetHash().ToString().c_str()); AddSaplingOutput(zChangeAddr->first, zChangeAddr->second, change); } else if (tChangeAddr) { // tChangeAddr has already been validated. @@ -162,6 +163,7 @@ boost::optional TransactionBuilder::Build() auto note = spends[0].note; libzcash::SaplingPaymentAddress changeAddr(note.d, note.pk_d); AddSaplingOutput(fvk.ovk, changeAddr, change); + LogPrintf("%s: Adding Sapling change output from first zinput: %s\n", __FUNCTION__, changeAddr.GetHash().ToString().c_str() ); } else { return boost::none; } diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 47570aca3..af15b5b76 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -189,7 +189,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - auto zaddr = DecodePaymentAddress(zdust); + auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); LogPrint("zrpcunsafe", "%s: Adding sietch output %s", getId(), sietchZoutput.GetHash().ToString().c_str() ); @@ -200,6 +200,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { break; } } + LogPrint("zrpcunsafe", "%s: Done adding sietch zouts", getId()); //CTransaction tx = builder.Build(); auto maybe_tx = builder.Build(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 20e137dc7..22d193a8c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -640,6 +640,7 @@ void CWallet::RunSaplingConsolidation(int blockHeight) { bool CWallet::CommitConsolidationTx(const CTransaction& tx) { CWalletTx wtx(this, tx); CReserveKey reservekey(pwalletMain); + fprintf(stderr,"%s: %s\n",__func__,tx.ToString().c_str()); return CommitTransaction(wtx, reservekey); } From 9f0197bba3edcac2b0a34551c885695a8b588bda Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 20 Mar 2020 11:31:58 -0400 Subject: [PATCH 073/220] Improved error handling and logging for sapling consolidation --- ...asyncrpcoperation_saplingconsolidation.cpp | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index af15b5b76..2ec6edadb 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -76,13 +76,15 @@ void AsyncRPCOperation_saplingconsolidation::main() { } bool AsyncRPCOperation_saplingconsolidation::main_impl() { - LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingconsolidation.\n", getId()); + bool status=true; + auto opid=getId(); + LogPrintf("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingconsolidation.\n", opid); auto consensusParams = Params().GetConsensus(); auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams); if (nextActivationHeight && targetHeight_ + CONSOLIDATION_EXPIRY_DELTA >= nextActivationHeight.get()) { - LogPrint("zrpcunsafe", "%s: Consolidation txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); + LogPrintf("zrpcunsafe", "%s: Consolidation txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); setConsolidationResult(0, 0, std::vector()); - return true; + return status; } std::vector sproutEntries; @@ -101,6 +103,8 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { if (boost::get(&zAddress) != nullptr) { libzcash::SaplingPaymentAddress saplingAddress = boost::get(zAddress); addresses.insert(saplingAddress ); + } else { + //TODO: how to handle invalid zaddrs? } } } else { @@ -150,7 +154,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { amountConsolidated += amountToSend; auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain); //builder.SetExpiryHeight(targetHeight_ + CONSOLIDATION_EXPIRY_DELTA); - LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - fConsolidationTxFee)); + LogPrintf("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - fConsolidationTxFee)); // Select Sapling notes std::vector ops; @@ -171,7 +175,8 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add Sapling spends for (size_t i = 0; i < notes.size(); i++) { if (!witnesses[i]) { - LogPrint("zrpcunsafe", "%s: Missing Witnesses. Stopping.\n", getId()); + LogPrintf("zrpcunsafe", "%s: Missing Witnesses. Stopping.\n", getId()); + status=false; break; } builder.AddSaplingSpend(extsk.expsk, notes[i], anchor, witnesses[i].get()); @@ -181,7 +186,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr.GetHash().ToString().c_str() ); + LogPrintf("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr.GetHash().ToString().c_str() ); // Add sietch zouts @@ -189,49 +194,55 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); + LogPrintf("zrpcunsafe", "%s: random zdust=%s", opid, zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); - LogPrint("zrpcunsafe", "%s: Adding sietch output %s", getId(), sietchZoutput.GetHash().ToString().c_str() ); + LogPrintf("zrpcunsafe", "%s: Adding OLD sietch output %d %s", getId(), i, sietchZoutput.GetHash().ToString().c_str() ); CAmount amount=0; + + // actually add our sietch zoutput, the new way builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId()); + LogPrintf("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId()); + status = false; break; } } - LogPrint("zrpcunsafe", "%s: Done adding sietch zouts", getId()); + LogPrintf("zrpcunsafe", "%s: Done adding %d sietch zouts", getId(), MIN_ZOUTS); //CTransaction tx = builder.Build(); auto maybe_tx = builder.Build(); if (!maybe_tx) { - LogPrint("zrpcunsafe", "%s: Failed to build transaction.", getId()); + LogPrint("zrpcunsafe", "%s: Failed to build transaction.",opid); + status=false; break; } CTransaction tx = maybe_tx.get(); if (isCancelled()) { - LogPrint("zrpcunsafe", "%s: Canceled. Stopping.\n", getId()); + LogPrintf("zrpcunsafe", "%s: Canceled. Stopping.\n", opid); + status=false; break; } if(pwalletMain->CommitConsolidationTx(tx)) { - LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); + LogPrintf("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); amountConsolidated += amountToSend - fConsolidationTxFee; consolidationTxIds.push_back(tx.GetHash().ToString()); } else { - LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + LogPrintf("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); - return false; + status = false; + break; } } } - LogPrint("zrpcunsafe", "%s: Created %d transactions with total Sapling output amount=%s\n", getId(), numTxCreated, FormatMoney(amountConsolidated)); + LogPrintf("zrpcunsafe", "%s: Created %d transactions with total Sapling output amount=%s,status=%d\n", getId(), numTxCreated, FormatMoney(amountConsolidated), (int)status); setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); - return true; - + return status; } void AsyncRPCOperation_saplingconsolidation::setConsolidationResult(int numTxCreated, const CAmount& amountConsolidated, const std::vector& consolidationTxIds) { From f5444b167988418f1fa5994ba1a8ead2485aeedd Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 26 Mar 2020 09:18:52 -0400 Subject: [PATCH 074/220] LogPrintf does not take a category argument, only LogPrint --- ...asyncrpcoperation_saplingconsolidation.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 2ec6edadb..784575d6c 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -78,11 +78,11 @@ void AsyncRPCOperation_saplingconsolidation::main() { bool AsyncRPCOperation_saplingconsolidation::main_impl() { bool status=true; auto opid=getId(); - LogPrintf("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingconsolidation.\n", opid); + LogPrint("zrpcunsafe", "%s: Beginning AsyncRPCOperation_saplingconsolidation.\n", opid); auto consensusParams = Params().GetConsensus(); auto nextActivationHeight = NextActivationHeight(targetHeight_, consensusParams); if (nextActivationHeight && targetHeight_ + CONSOLIDATION_EXPIRY_DELTA >= nextActivationHeight.get()) { - LogPrintf("zrpcunsafe", "%s: Consolidation txs would be created before a NU activation but may expire after. Skipping this round.\n", getId()); + LogPrint("zrpcunsafe", "%s: Consolidation txs would be created before a NU activation but may expire after. Skipping this round.\n",opid); setConsolidationResult(0, 0, std::vector()); return status; } @@ -154,7 +154,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { amountConsolidated += amountToSend; auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain); //builder.SetExpiryHeight(targetHeight_ + CONSOLIDATION_EXPIRY_DELTA); - LogPrintf("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", getId(), FormatMoney(amountToSend - fConsolidationTxFee)); + LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", opid, FormatMoney(amountToSend - fConsolidationTxFee)); // Select Sapling notes std::vector ops; @@ -175,7 +175,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add Sapling spends for (size_t i = 0; i < notes.size(); i++) { if (!witnesses[i]) { - LogPrintf("zrpcunsafe", "%s: Missing Witnesses. Stopping.\n", getId()); + LogPrint("zrpcunsafe", "%s: Missing Witnesses. Stopping.\n", opid); status=false; break; } @@ -186,7 +186,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrintf("zrpcunsafe", "%s: Added consolidation output %s", getId(), addr.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s", opid, addr.GetHash().ToString().c_str() ); // Add sietch zouts @@ -194,22 +194,22 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - LogPrintf("zrpcunsafe", "%s: random zdust=%s", opid, zdust); + LogPrint("zrpcunsafe", "%s: random zdust=%s", opid, zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); - LogPrintf("zrpcunsafe", "%s: Adding OLD sietch output %d %s", getId(), i, sietchZoutput.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Adding OLD sietch output %d %s", opid, i, sietchZoutput.GetHash().ToString().c_str() ); CAmount amount=0; // actually add our sietch zoutput, the new way builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrintf("zrpcunsafe", "%s: Invalid payment address! Stopping.", getId()); + LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", opid); status = false; break; } } - LogPrintf("zrpcunsafe", "%s: Done adding %d sietch zouts", getId(), MIN_ZOUTS); + LogPrint("zrpcunsafe", "%s: Done adding %d sietch zouts", opid, MIN_ZOUTS); //CTransaction tx = builder.Build(); auto maybe_tx = builder.Build(); @@ -221,17 +221,17 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { CTransaction tx = maybe_tx.get(); if (isCancelled()) { - LogPrintf("zrpcunsafe", "%s: Canceled. Stopping.\n", opid); + LogPrint("zrpcunsafe", "%s: Canceled. Stopping.\n", opid); status=false; break; } if(pwalletMain->CommitConsolidationTx(tx)) { - LogPrintf("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); + LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n",opid, tx.GetHash().ToString()); amountConsolidated += amountToSend - fConsolidationTxFee; consolidationTxIds.push_back(tx.GetHash().ToString()); } else { - LogPrintf("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n",opid , tx.GetHash().ToString()); setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); status = false; break; @@ -240,7 +240,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { } } - LogPrintf("zrpcunsafe", "%s: Created %d transactions with total Sapling output amount=%s,status=%d\n", getId(), numTxCreated, FormatMoney(amountConsolidated), (int)status); + LogPrint("zrpcunsafe", "%s: Created %d transactions with total Sapling output amount=%s,status=%d\n",opid , numTxCreated, FormatMoney(amountConsolidated), (int)status); setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); return status; } From 54ec0d09949c45a5880a71f43b6a946b7f01ca9a Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Sun, 29 Mar 2020 03:01:46 -0400 Subject: [PATCH 075/220] updated undefined behavior in accordance with zcash remedy rex4539 #4056 --- src/arith_uint256.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp index e9c0dd056..d7a5c0afe 100644 --- a/src/arith_uint256.cpp +++ b/src/arith_uint256.cpp @@ -193,9 +193,10 @@ unsigned int base_uint::bits() const { for (int pos = WIDTH - 1; pos >= 0; pos--) { if (pn[pos]) { - for (int bits = 31; bits > 0; bits--) { - if (pn[pos] & 1 << bits) + for (size_t bits = 31; bits > 0; bits--) { + if (pn[pos] & (1U << bits)) { return 32 * pos + bits + 1; + } } return 32 * pos + 1; } From ec162c7d85d43b62440abad221895f3110c8d065 Mon Sep 17 00:00:00 2001 From: ca333 Date: Sun, 5 Apr 2020 02:38:46 +0200 Subject: [PATCH 076/220] fix dead openssl download path updates openssl 1.1.1a download path jfyi: we are testing 1.1.1f in https://github.com/KomodoPlatform/komodo/pull/314 --- depends/packages/openssl.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index c5ac5bb32..276e887a7 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,6 +1,6 @@ package=openssl $(package)_version=1.1.1a -$(package)_download_path=https://www.openssl.org/source +$(package)_download_path=https://www.openssl.org/source/old/1.1.1 $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=fc20130f8b7cbd2fb918b2f14e2f429e109c31ddd0fb38fc5d71d9ffed3f9f41 $(package)_patches=ssl_fix.patch From 7665509d99954f8e49b20f59ea86cdc46e8e3838 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 08:37:33 -0400 Subject: [PATCH 077/220] Make this less noisy --- src/coins.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index b8370e193..38fac8252 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -436,8 +436,8 @@ void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers) { - if(fZdebug) - LogPrintf("%s\n", __FUNCTION__); + //if(fZdebug) + // LogPrintf("%s\n", __FUNCTION__); for (CNullifiersMap::iterator child_it = mapNullifiers.begin(); child_it != mapNullifiers.end();) { if (child_it->second.flags & CNullifiersCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization). CNullifiersMap::iterator parent_it = cacheNullifiers.find(child_it->first); From a49dc97e25f3c0054a1b9adfbfbc24baa136c4c0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 18:25:00 -0400 Subject: [PATCH 078/220] Log txid when IsFinalTx returns false --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index bed9d6ac8..449889747 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -957,7 +957,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) } else if (!txin.IsFinal()) { - LogPrintf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime); + LogPrintf("non-final txin txid.%s seq.%x locktime.%u vs nTime.%u\n",tx.GetHash().ToString().c_str(),txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime); return false; } } From a7dd309ad075f51bacdc8dcdd627cbdb42847698 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 18:37:02 -0400 Subject: [PATCH 079/220] Add copyright --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 784575d6c..3e4f72e8a 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2020 The Hush developers -// TODO: Forge should add his preferred copyright line here +// Copyright (c) 2019 CryptoForge // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From 848b78f848d5b9d670ba494c83f76d517a1b8935 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 23:01:14 -0400 Subject: [PATCH 080/220] Return early for unknown txs and log unconfirmed --- src/komodo_bitcoind.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index b5e825a58..39cf5da63 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -71,6 +71,7 @@ int tx_height( const uint256 &hash ){ uint256 hashBlock; if (!GetTransaction(hash, tx, hashBlock, true)) { fprintf(stderr,"tx hash %s does not exist!\n", hash.ToString().c_str() ); + return nHeight; } BlockMap::const_iterator it = mapBlockIndex.find(hashBlock); @@ -79,6 +80,7 @@ int tx_height( const uint256 &hash ){ //fprintf(stderr,"blockHash %s height %d\n",hashBlock.ToString().c_str(), nHeight); } else { // Unconfirmed xtns + fprintf(stderr,"tx %s is unconfirmed\n", hash.ToString().c_str() ); //fprintf(stderr,"block hash %s does not exist!\n", hashBlock.ToString().c_str() ); } return nHeight; From 28f5f51e5ef31ba0d879d9bc52db16bc0db78c7e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 23:03:27 -0400 Subject: [PATCH 081/220] Do not call BatchWrite* for sprout --- src/txdb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index b45df4448..46140f546 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -199,10 +199,10 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, mapCoins.erase(itOld); } - ::BatchWriteAnchors(batch, mapSproutAnchors, DB_SPROUT_ANCHOR); + //::BatchWriteAnchors(batch, mapSproutAnchors, DB_SPROUT_ANCHOR); ::BatchWriteAnchors(batch, mapSaplingAnchors, DB_SAPLING_ANCHOR); - ::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER); + //::BatchWriteNullifiers(batch, mapSproutNullifiers, DB_NULLIFIER); ::BatchWriteNullifiers(batch, mapSaplingNullifiers, DB_SAPLING_NULLIFIER); if (!hashBlock.IsNull()) From e03ef7f1082459e7c458601e59cfd671b09ba13c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 23:05:20 -0400 Subject: [PATCH 082/220] Avoid notes with height=0 --- src/wallet/wallet.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 22d193a8c..ef91d9089 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5360,6 +5360,9 @@ void CWallet::GetFilteredNotes( if (minDepth > 1) { int nHeight = tx_height(wtx.GetHash()); + if ( nHeight == 0 ) { + continue; + } int nDepth = wtx.GetDepthInMainChain(); int dpowconfs = komodo_dpowconfs(nHeight,nDepth); if ( dpowconfs < minDepth || dpowconfs > maxDepth) { From 4d56e542a837d4f4690790730f2d0f34bfe8f673 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 6 Apr 2020 23:07:11 -0400 Subject: [PATCH 083/220] Do not look for sprout notes --- src/wallet/wallet.cpp | 56 ------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ef91d9089..53b3af6a6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5375,62 +5375,6 @@ void CWallet::GetFilteredNotes( } } - for (auto & pair : wtx.mapSproutNoteData) { - JSOutPoint jsop = pair.first; - SproutNoteData nd = pair.second; - SproutPaymentAddress pa = nd.address; - - // skip notes which belong to a different payment address in the wallet - if (!(filterAddresses.empty() || filterAddresses.count(pa))) { - continue; - } - - // skip note which has been spent - if (ignoreSpent && nd.nullifier && IsSproutSpent(*nd.nullifier)) { - continue; - } - - // skip notes which cannot be spent - if (requireSpendingKey && !HaveSproutSpendingKey(pa)) { - continue; - } - - // skip locked notes - if (ignoreLocked && IsLockedNote(jsop)) { - continue; - } - - int i = jsop.js; // Index into CTransaction.vjoinsplit - int j = jsop.n; // Index into JSDescription.ciphertexts - - // Get cached decryptor - ZCNoteDecryption decryptor; - if (!GetNoteDecryptor(pa, decryptor)) { - // Note decryptors are created when the wallet is loaded, so it should always exist - throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa))); - } - - // determine amount of funds in the note - auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); - try { - SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( - decryptor, - wtx.vjoinsplit[i].ciphertexts[j], - wtx.vjoinsplit[i].ephemeralKey, - hSig, - (unsigned char) j); - - sproutEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()}); - - } catch (const note_decryption_failed &err) { - // Couldn't decrypt with this spending key - throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa))); - } catch (const std::exception &exc) { - // Unexpected failure - throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what())); - } - } - for (auto & pair : wtx.mapSaplingNoteData) { SaplingOutPoint op = pair.first; SaplingNoteData nd = pair.second; From 6cdf4dd765f04138f07433fc47bc1b20c38b069c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 00:11:53 -0400 Subject: [PATCH 084/220] Fix zrpcunsafe logging and log valueBalance when final_check fails --- src/main.cpp | 1 + .../asyncrpcoperation_saplingconsolidation.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 449889747..68cc7b439 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1327,6 +1327,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde )) { librustzcash_sapling_verification_ctx_free(ctx); + fprintf(stderr,"%s: valueBalance=%li\n", __func__, tx.valueBalance ); return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"), REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); } diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 3e4f72e8a..ea58efc65 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -186,7 +186,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output %s", opid, addr.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s\n", opid, addr.GetHash().ToString().c_str() ); // Add sietch zouts @@ -194,27 +194,27 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - LogPrint("zrpcunsafe", "%s: random zdust=%s", opid, zdust); + LogPrint("zrpcunsafe", "%s: random zdust=%s\n", opid, zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); - LogPrint("zrpcunsafe", "%s: Adding OLD sietch output %d %s", opid, i, sietchZoutput.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Adding OLD sietch output %d %s\n", opid, i, sietchZoutput.GetHash().ToString().c_str() ); CAmount amount=0; // actually add our sietch zoutput, the new way builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.", opid); + LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.\n", opid); status = false; break; } } - LogPrint("zrpcunsafe", "%s: Done adding %d sietch zouts", opid, MIN_ZOUTS); + LogPrint("zrpcunsafe", "%s: Done adding %d sietch zouts\n", opid, MIN_ZOUTS); //CTransaction tx = builder.Build(); auto maybe_tx = builder.Build(); if (!maybe_tx) { - LogPrint("zrpcunsafe", "%s: Failed to build transaction.",opid); + LogPrint("zrpcunsafe", "%s: Failed to build transaction.\n",opid); status=false; break; } From 3175039f62ee5676da1d2f8e278ae471df9b2e92 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 09:36:05 -0400 Subject: [PATCH 085/220] Log consolidation output amounts --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index ea58efc65..216d2fbba 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -186,7 +186,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output %s\n", opid, addr.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s with amount=%li\n", opid, addr.GetHash().ToString().c_str(), amountToSend - fConsolidationTxFee ); // Add sietch zouts From 88f846c3591aa917fc12d90fc04299586fb036a7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 13:36:21 -0400 Subject: [PATCH 086/220] Log more details for invalid binding sigs --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 68cc7b439..17b89a76b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1327,7 +1327,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde )) { librustzcash_sapling_verification_ctx_free(ctx); - fprintf(stderr,"%s: valueBalance=%li\n", __func__, tx.valueBalance ); + fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%d\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"), REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); } From cf4514deef1bab6eb6e7cafc64f22b991c2161c4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 13:36:46 -0400 Subject: [PATCH 087/220] Log more details during sapling consolidation --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 216d2fbba..7c71ac72c 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -154,7 +154,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { amountConsolidated += amountToSend; auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain); //builder.SetExpiryHeight(targetHeight_ + CONSOLIDATION_EXPIRY_DELTA); - LogPrint("zrpcunsafe", "%s: Beginning creating transaction with Sapling output amount=%s\n", opid, FormatMoney(amountToSend - fConsolidationTxFee)); + LogPrint("zrpcunsafe", "%s: Beginning to create transaction with Sapling output amount=%s\n", opid, FormatMoney(amountToSend - fConsolidationTxFee)); // Select Sapling notes std::vector ops; @@ -169,6 +169,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { std::vector> witnesses; { LOCK2(cs_main, pwalletMain->cs_wallet); + LogPrint("zrpcunsafe", "%s: Fetching note witenesses\n", opid); pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor); } @@ -180,6 +181,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { break; } builder.AddSaplingSpend(extsk.expsk, notes[i], anchor, witnesses[i].get()); + LogPrint("zrpcunsafe", "%s: Added consolidation input %d\n", opid, i); } builder.SetFee(fConsolidationTxFee); @@ -194,17 +196,16 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { for(size_t i = 0; i < MIN_ZOUTS; i++) { // In Privacy Zdust We Trust -- Duke string zdust = randomSietchZaddr(); - LogPrint("zrpcunsafe", "%s: random zdust=%s\n", opid, zdust); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { auto sietchZoutput = boost::get(zaddr); - LogPrint("zrpcunsafe", "%s: Adding OLD sietch output %d %s\n", opid, i, sietchZoutput.GetHash().ToString().c_str() ); + LogPrint("zrpcunsafe", "%s: Adding Sietch zdust output %d %s amount=%li\n", opid, i, zdust, amount); CAmount amount=0; // actually add our sietch zoutput, the new way builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); } else { - LogPrint("zrpcunsafe", "%s: Invalid payment address! Stopping.\n", opid); + LogPrint("zrpcunsafe", "%s: Invalid payment address %s! Stopping.\n", opid, zdust); status = false; break; } From a96a1ebce5dd8141283be0ad63c03cad53deda5d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 18:19:48 -0400 Subject: [PATCH 088/220] Use fee=0 if we have less than a fee worth of funds to consolidate --- .../asyncrpcoperation_saplingconsolidation.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 7c71ac72c..591df3071 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -154,7 +154,8 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { amountConsolidated += amountToSend; auto builder = TransactionBuilder(consensusParams, targetHeight_, pwalletMain); //builder.SetExpiryHeight(targetHeight_ + CONSOLIDATION_EXPIRY_DELTA); - LogPrint("zrpcunsafe", "%s: Beginning to create transaction with Sapling output amount=%s\n", opid, FormatMoney(amountToSend - fConsolidationTxFee)); + auto actualAmountToSend = amountToSend < fConsolidationTxFee ? 0 : amountToSend - fConsolidationTxFee; + LogPrint("zrpcunsafe", "%s: Beginning to create transaction with Sapling output amount=%s\n", opid, FormatMoney(actualAmountToSend)); // Select Sapling notes std::vector ops; @@ -187,9 +188,8 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { builder.SetFee(fConsolidationTxFee); // Add the actual consolidation tx - builder.AddSaplingOutput(extsk.expsk.ovk, addr, amountToSend - fConsolidationTxFee); - LogPrint("zrpcunsafe", "%s: Added consolidation output %s with amount=%li\n", opid, addr.GetHash().ToString().c_str(), amountToSend - fConsolidationTxFee ); - + builder.AddSaplingOutput(extsk.expsk.ovk, addr, actualAmountToSend); + LogPrint("zrpcunsafe", "%s: Added consolidation output %s with amount=%li\n", opid, addr.GetHash().ToString().c_str(), actualAmountToSend); // Add sietch zouts int MIN_ZOUTS = 7; @@ -198,9 +198,9 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { string zdust = randomSietchZaddr(); auto zaddr = DecodePaymentAddress(zdust); if (IsValidPaymentAddress(zaddr)) { + CAmount amount=0; auto sietchZoutput = boost::get(zaddr); LogPrint("zrpcunsafe", "%s: Adding Sietch zdust output %d %s amount=%li\n", opid, i, zdust, amount); - CAmount amount=0; // actually add our sietch zoutput, the new way builder.AddSaplingOutput(extsk.expsk.ovk, sietchZoutput, amount); @@ -229,7 +229,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { if(pwalletMain->CommitConsolidationTx(tx)) { LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n",opid, tx.GetHash().ToString()); - amountConsolidated += amountToSend - fConsolidationTxFee; + amountConsolidated += actualAmountToSend; consolidationTxIds.push_back(tx.GetHash().ToString()); } else { LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n",opid , tx.GetHash().ToString()); From 32400168c10fd91cdbddfea79fffe261a5e4a8c6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 21:15:39 -0400 Subject: [PATCH 089/220] Add logging for rare error cases in transaction builder --- src/transaction_builder.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 3964617ca..8b1acaca9 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -142,6 +142,7 @@ boost::optional TransactionBuilder::Build() change -= tOut.nValue; } if (change < 0) { + LogPrintf("%s: negative change!\n", __func__); return boost::none; } @@ -182,6 +183,7 @@ boost::optional TransactionBuilder::Build() auto nf = spend.note.nullifier( spend.expsk.full_viewing_key(), spend.witness.position()); if (!(cm && nf)) { + LogPrintf("%s: Invalid commitment or nullifier!\n", __FUNCTION__); librustzcash_sapling_proving_ctx_free(ctx); return boost::none; } @@ -205,6 +207,7 @@ boost::optional TransactionBuilder::Build() sdesc.rk.begin(), sdesc.zkproof.data())) { librustzcash_sapling_proving_ctx_free(ctx); + LogPrintf("%s: Invalid sapling spend proof!\n", __FUNCTION__); return boost::none; } @@ -218,6 +221,7 @@ boost::optional TransactionBuilder::Build() for (auto output : outputs) { auto cm = output.note.cm(); if (!cm) { + LogPrintf("%s: Invalid sapling note commitment!\n", __FUNCTION__); librustzcash_sapling_proving_ctx_free(ctx); return boost::none; } @@ -243,6 +247,7 @@ boost::optional TransactionBuilder::Build() odesc.cv.begin(), odesc.zkproof.begin())) { librustzcash_sapling_proving_ctx_free(ctx); + LogPrintf("%s: Invalid sapling output proof!\n", __FUNCTION__); return boost::none; } @@ -275,6 +280,7 @@ boost::optional TransactionBuilder::Build() dataToBeSigned = SignatureHash(scriptCode, mtx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); } catch (std::logic_error ex) { librustzcash_sapling_proving_ctx_free(ctx); + LogPrintf("%s: SignatureHash exception!\n", __func__); return boost::none; } @@ -293,6 +299,7 @@ boost::optional TransactionBuilder::Build() mtx.bindingSig.data()); librustzcash_sapling_proving_ctx_free(ctx); + LogPrintf("%s: Created spendAuth and binding sigs\n", __func__); // Transparent signatures CTransaction txNewConst(mtx); From 941f983a9f2491bbc454672a422674e66aa1d2ef Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 21:16:04 -0400 Subject: [PATCH 090/220] speling iz hard --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 591df3071..feb89a0ee 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -170,7 +170,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { std::vector> witnesses; { LOCK2(cs_main, pwalletMain->cs_wallet); - LogPrint("zrpcunsafe", "%s: Fetching note witenesses\n", opid); + LogPrint("zrpcunsafe", "%s: Fetching note witnesses\n", opid); pwalletMain->GetSaplingNoteWitnesses(ops, witnesses, anchor); } From be4812bd29f1be50a16b688f30db24037a7ac189 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 21:17:58 -0400 Subject: [PATCH 091/220] Use fee=0 if we do not have enough funds in this zaddr to pay a fee; track number of txs created --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index feb89a0ee..8f7078c81 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -185,7 +185,9 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { LogPrint("zrpcunsafe", "%s: Added consolidation input %d\n", opid, i); } - builder.SetFee(fConsolidationTxFee); + CAmount thisTxFee = amountToSend < fConsolidationTxFee ? 0 : fConsolidationTxFee; + LogPrint("zrpcunsafe", "%s: Using fee=%d\n", opid, thisTxFee); + builder.SetFee(thisTxFee); // Add the actual consolidation tx builder.AddSaplingOutput(extsk.expsk.ovk, addr, actualAmountToSend); @@ -231,13 +233,13 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n",opid, tx.GetHash().ToString()); amountConsolidated += actualAmountToSend; consolidationTxIds.push_back(tx.GetHash().ToString()); + numTxCreated++; } else { LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n",opid , tx.GetHash().ToString()); setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); status = false; break; } - } } From a0e36da33c0659555090955d4da815f0eb1e2d4b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 7 Apr 2020 22:17:43 -0400 Subject: [PATCH 092/220] Spelling --- src/wallet/wallet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3dd658acb..205a49008 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -94,7 +94,7 @@ static const int DEFAULT_TX_DELETE_INTERVAL = 1000; //Default Transaction Rentention N-BLOCKS static const unsigned int DEFAULT_TX_RETENTION_BLOCKS = 10000; -//Default Retenion Last N-Transactions +//Default Retention Last N-Transactions static const unsigned int DEFAULT_TX_RETENTION_LASTTX = 200; //Amount of transactions to delete per run while syncing From bd88898ce037f6ee0e7bb945d9da4b221f931e8f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 12 Apr 2020 05:55:08 -0400 Subject: [PATCH 093/220] Implement z2z transition period for mempool --- src/main.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 17b89a76b..aa8ba176e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1741,6 +1741,25 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel) { AssertLockHeld(cs_main); + uint32_t z2zTransitionWindow = 10; + uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow; + uint32_t z2zTransitionEnd = 340000; + bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + uint32_t nHeight = chainActive.Height(); + + // This only applies to HUSH3, other chains can start off z2z via ac_private=1 + if(ishush3) { + if((nHeight >= z2zTransitionStart) || (nHeight <= z2zTransitionEnd)) { + // During the z2z transition window, only coinbase tx's as part of blocks are allowed + // Theory: We want an empty mempool at our fork block height, and the only way to assure that + // is to have an empty mempool for a few previous blocks, to take care of potential re-orgs + // and edge cases. This empty mempool assures there will be no transactions involving taddrs + // stuck in the mempool, when the z2z rule takes effect. + // Thanks to jl777 for helping design this + fprintf(stderr,"%s: rejecting all tx's during z2z transition window at height=%d\n", __func__,nHeight); + return false; + } + } if (pfMissingInputs) *pfMissingInputs = false; uint32_t tiptime; From 3d9e662266a28f6d634185d239b6b23ec362b629 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Apr 2020 07:53:01 -0400 Subject: [PATCH 094/220] Switch to -ac_private=1 at our z2z fork height --- src/main.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index aa8ba176e..7575a4e0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3368,6 +3368,19 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return(false); //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->GetHeight()); AssertLockHeld(cs_main); + + bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + if(!ASSETCHAINS_PRIVATE && ishush3) { + unsigned int z2zForkHeight = 340000; + unsigned int nHeight = pindex->GetHeight(); + if(nHeight >= z2zForkHeight) { + // At startup, HUSH3 doesn't know a block height yet and so we must wait until + // connecting a block + fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,nHeight); + ASSETCHAINS_PRIVATE = 1; + } + } + bool fExpensiveChecks = true; if (fCheckpointsEnabled) { CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); From e51556083793c3c5272f31b3e64cf6cfecddae27 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 14 Apr 2020 22:27:24 -0400 Subject: [PATCH 095/220] Improve and remove mention of sprout in this error message --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7575a4e0a..20c6cffe6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1591,11 +1591,11 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio if ( counter++ < 10 ) fprintf(stderr,"found taddr in private chain: z_z.%d z_t.%d t_z.%d vinsize.%d\n",z_z,z_t,t_z,(int32_t)tx.vin.size()); if ( z_t == 0 || z_z != 0 || t_z != 0 || tx.vin.size() != 0 ) - return state.DoS(100, error("CheckTransaction(): this is a private chain, only sprout -> taddr allowed until deadline"),REJECT_INVALID, "bad-txns-acprivacy-chain"); + return state.DoS(100, error("CheckTransaction(): this is a private chain, sending to taddrs not allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain"); } if ( ASSETCHAINS_TXPOW != 0 ) { - // genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + // BTC genesis coinbase 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b uint256 txid = tx.GetHash(); if ( ((ASSETCHAINS_TXPOW & 2) != 0 && iscoinbase != 0) || ((ASSETCHAINS_TXPOW & 1) != 0 && iscoinbase == 0) ) { From 77cc82428bab83079bdd3a0751645b2a8a25cc27 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 00:59:47 -0400 Subject: [PATCH 096/220] Hush Smart Chains --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index ac15db192..b9bc096a7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -581,7 +581,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-metricsui", _("Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise)")); strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600)); } - strUsage += HelpMessageGroup(_("Komodo Asset Chain options:")); + strUsage += HelpMessageGroup(_("Hush Smart Chain options:")); strUsage += HelpMessageOpt("-ac_algo", _("Choose PoW mining algorithm, default is Equihash")); strUsage += HelpMessageOpt("-ac_blocktime", _("Block time in seconds, default is 60")); strUsage += HelpMessageOpt("-ac_cc", _("Cryptoconditions, default 0")); From a2013ecc39219151067578661b3dbf13b4e1fe7f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 02:07:19 -0400 Subject: [PATCH 097/220] Fix incorrect error message --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 20c6cffe6..cfe851f7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6121,7 +6121,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) // Create new CBlockIndex* pindexNew = new CBlockIndex(); if (!pindexNew) - throw runtime_error("LoadBlockIndex(): new CBlockIndex failed"); + throw runtime_error("InsertBlockIndex(): new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); //fprintf(stderr,"inserted to block index %s\n",hash.ToString().c_str()); From 41a4c84633945f868061abd0b17741ecceaa1935 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 15 Apr 2020 02:39:18 -0400 Subject: [PATCH 098/220] Refactor z2z and additionally set ac_private=1 when loading block index from disk This should avoid the edge case when a node starts up after the z2z block height but has not yet seen a new block and so does not yet know it is an -ac_private=1 chain, as currently that is set in ConnectBlock. --- src/main.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cfe851f7f..472a8bb90 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -114,6 +114,8 @@ bool fAlerts = DEFAULT_ALERTS; /* If the tip is older than this (in seconds), the node is considered to be in initial block download. */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; +bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; +unsigned int z2zForkHeight = 340000; unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1742,14 +1744,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { AssertLockHeld(cs_main); uint32_t z2zTransitionWindow = 10; - uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow; - uint32_t z2zTransitionEnd = 340000; - bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; - uint32_t nHeight = chainActive.Height(); + uint32_t z2zTransitionStart = z2zForkHeight - z2zTransitionWindow; + uint32_t nHeight = chainActive.Height(); // This only applies to HUSH3, other chains can start off z2z via ac_private=1 if(ishush3) { - if((nHeight >= z2zTransitionStart) || (nHeight <= z2zTransitionEnd)) { + if((nHeight >= z2zTransitionStart) || (nHeight <= z2zForkHeight)) { // During the z2z transition window, only coinbase tx's as part of blocks are allowed // Theory: We want an empty mempool at our fork block height, and the only way to assure that // is to have an empty mempool for a few previous blocks, to take care of potential re-orgs @@ -3371,7 +3371,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; if(!ASSETCHAINS_PRIVATE && ishush3) { - unsigned int z2zForkHeight = 340000; unsigned int nHeight = pindex->GetHeight(); if(nHeight >= z2zForkHeight) { // At startup, HUSH3 doesn't know a block height yet and so we must wait until @@ -6338,6 +6337,13 @@ bool static LoadBlockIndexDB() chainActive.SetTip(it->second); + // Try to detect if we are z2z based on height of blocks on disk + // This helps to set it correctly on startup before a new block is connected + if(ishush3 && chainActive.Height() >= z2zForkHeight) { + LogPrintf("%s: enabled ac_private=1 at height=%d\n", __func__, chainActive.Height()); + ASSETCHAINS_PRIVATE = 1; + } + // Set hashFinalSproutRoot for the end of best chain it->second->hashFinalSproutRoot = pcoinsTip->GetBestAnchor(SPROUT); From 2bfc18b26d1485dc8d6d3ac1da60a6d9af3ef11a Mon Sep 17 00:00:00 2001 From: Charles <18726788+csharpee@users.noreply.github.com> Date: Thu, 16 Apr 2020 16:48:58 -0400 Subject: [PATCH 099/220] Fix package dep for ccache xz to gz compression algo. --- depends/packages/native_ccache.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/depends/packages/native_ccache.mk b/depends/packages/native_ccache.mk index b3693cc6f..64fee77ba 100644 --- a/depends/packages/native_ccache.mk +++ b/depends/packages/native_ccache.mk @@ -1,8 +1,8 @@ package=native_ccache -$(package)_version=3.7.7 +$(package)_version=3.7.9 $(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version) -$(package)_file_name=ccache-$($(package)_version).tar.xz -$(package)_sha256_hash=b7c1d6d6fe42f18e424de92746af863e0bc85794da3d69e44300840c478c98cd +$(package)_file_name=ccache-$($(package)_version).tar.gz +$(package)_sha256_hash=92838e2133c9e704fdab9ee2608dad86c99021278b9ac47d065aa8ff2ea8ce36 define $(package)_set_vars $(package)_config_opts= From 1009c7933de1d284e83afc139a599b0efd1785cf Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 16 Apr 2020 22:10:25 -0400 Subject: [PATCH 100/220] CLI arg -z2zforkheight and avoid a compiler warning --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 472a8bb90..e1beb5c5d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; -unsigned int z2zForkHeight = 340000; +unsigned int z2zForkHeight = GetArg("-z2zforkheight",340000); unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1329,7 +1329,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde )) { librustzcash_sapling_verification_ctx_free(ctx); - fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%d\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); + fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%li\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"), REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); } From b3c7e048ab583556e79bd5651abc49b443227740 Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Sat, 25 Apr 2020 00:30:06 +0200 Subject: [PATCH 101/220] add z_getnotescount as rpc call ported for Hush from https://github.com/zcash/zcash/pull/4465 --- src/rpc/client.cpp | 1 + src/wallet/rpcwallet.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 4107ad6f8..79011da34 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -139,6 +139,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_listunspent", 2 }, { "z_listunspent", 3 }, { "z_getbalance", 1}, + { "z_getnotescount", 0}, { "z_gettotalbalance", 0}, { "z_gettotalbalance", 1}, { "z_gettotalbalance", 2}, diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b8115767a..5afd0c4e8 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4213,6 +4213,42 @@ UniValue z_getbalance(const UniValue& params, bool fHelp, const CPubKey& mypk) return ValueFromAmount(nBalance); } +UniValue z_getnotescount(const UniValue& params, bool fHelp,const CPubKey& mypk) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 1) + throw runtime_error( + "z_getnotescount\n" + "\nArguments:\n" + "1. minconf (numeric, optional, default=1) Only include notes in transactions confirmed at least this many times.\n" + "\nReturns the number of sprout and sapling notes available in the wallet.\n" + "\nResult:\n" + "{\n" + " \"sapling\" (numeric) the number of sapling notes in the wallet\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("z_getnotescount", "0") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + int sapling = 0; + for (auto& wtx : pwalletMain->mapWallet) { + if (wtx.second.GetDepthInMainChain() >= nMinDepth) { + sapling += wtx.second.mapSaplingNoteData.size(); + } + } + UniValue ret(UniValue::VOBJ); + ret.push_back(Pair("sapling", sapling)); + + return ret; +} UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& mypk) { @@ -8368,6 +8404,7 @@ static const CRPCCommand commands[] = { "wallet", "z_getinfo", &z_getinfo, true }, { "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true }, + { "wallet", "z_getnotescount", &z_getnotescount, false }, // TODO: rearrange into another category { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } From ed0385b52465bbde771408e83441c7a600dc06f3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 30 Apr 2020 06:51:54 -0400 Subject: [PATCH 102/220] Initial merge of subatomic dapp from KMD upstream from dev branch of https://github.com/jl777/komodo/ commit d75041c478bcd721d44be0ab9af45c3d2ba2f69b --- src/cc/dapps/subatomic.c | 1429 +++++++++++++++++++++++++++++++++++ src/cc/dapps/subatomic.json | 26 + 2 files changed, 1455 insertions(+) create mode 100644 src/cc/dapps/subatomic.c create mode 100644 src/cc/dapps/subatomic.json diff --git a/src/cc/dapps/subatomic.c b/src/cc/dapps/subatomic.c new file mode 100644 index 000000000..2f6ebf824 --- /dev/null +++ b/src/cc/dapps/subatomic.c @@ -0,0 +1,1429 @@ +/****************************************************************************** + * Copyright © 2014-2020 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// build subatomic and put in path: git pull; gcc cc/dapps/subatomic.c -lm -o subatomic; cp subatomic /usr/bin +// alice sends relcoin and gets basecoin + +#define DEXP2P_CHAIN ((char *)"DEX") +#define DEXP2P_PUBKEYS ((char *)"subatomic") +#include "dappinc.h" + +// for OTC mode, the following 4 functions are the only ones that should be needed to support a new "coin" +//int64_t subatomic_getbalance(char *coin); +//bits256 subatomic_coinpayment(int32_t OTCmode,char *coin,char *destaddr,uint64_t paytoshis,char *memostr); +//cJSON *subatomic_txidwait(char *coin,bits256 txid,char *hexstr,int32_t numseconds); +//int64_t subatomic_verifypayment(char *coin,cJSON *rawtx,uint64_t destsatoshis,char *destaddr); + +// TODO: +// address conversion +// new inventory types: +// anonsend + +// bob nodes: +// mutex for bob instances +// "deposits" messages and approved bobs +// volume caps per coin and non-notarized exposure + +// later: +// sharded storage + +#define SUBATOMIC_OTCDEFAULT 1 +#define SUBATOMIC_TIMEOUT 60 +#define SUBATOMIC_LOCKTIME 3600 +#define SUBATOMIC_TXFEE 10000 + +#define SUBATOMIC_PRIORITY 5 + +#define SUBATOMIC_OPENREQUEST 1 +#define SUBATOMIC_APPROVED 2 +#define SUBATOMIC_OPENED 3 +#define SUBATOMIC_PAYMENT 4 +#define SUBATOMIC_PAIDINFULL 5 +#define SUBATOMIC_CLOSED 6 + +cJSON *SUBATOMIC_json; +int32_t SUBATOMIC_retval = -1; + +struct abinfo +{ + char pubkey[67],recvaddr[64],recvZaddr[128],secp[67]; +}; + +struct coininfo +{ + uint64_t satoshis,txfee,maxamount; + char istoken,iszaddr,isfile,isexternal,tokenid[65],coin[16],name[16],cli[256],acname[16],coinstr[16]; +}; + +struct msginfo +{ + UT_hash_handle hh; + bits256 bobpayment,alicepayment; + double price; + uint64_t gotpayment; + uint32_t origid,openrequestid,approvalid,openedid,paymentids[100],paidid,closedid,locktime; + int32_t bobflag,status,OTCmode; + char payload[128],approval[128],senderpub[67],msigaddr[64],redeemscript[256]; + struct coininfo base,rel; + struct abinfo alice,bob; +} *Messages; + +uint64_t subatomic_txfee(char *coin) +{ + return(SUBATOMIC_TXFEE); +} + +char *subatomic_checkname(char *tmpstr,struct msginfo *mp,int32_t baserel,char *coin) +{ + int32_t i,n; cJSON *external,*item; char *coinstr,*clistr; struct coininfo *ptr; + ptr = (baserel == 0) ? &mp->base : &mp->rel; + if ( coin[0] == 0 ) + return(coin); + if ( (external= jarray(&n,SUBATOMIC_json,"externalcoins")) != 0 && n > 0 ) + { + for (i=0; icli) ) + { + ptr->isexternal = 1; + strcpy(ptr->cli,clistr); + //fprintf(stderr,"found external coin %s %s\n",coin,clistr); + } + } + } + if ( coin[0] == '#' ) + { + strcpy(ptr->coinstr,coin); + strcpy(ptr->acname,""); + ptr->isfile = 1; + return(coin); + } + else if ( coin[0] != 'z' ) + { + for (i=1; coin[i]!=0; i++) + if ( coin[i] == '.' ) + { + dpow_tokenregister(ptr->tokenid,0,coin,0); + if ( ptr->tokenid[0] != 0 ) + { + strcpy(tmpstr,coin); + tmpstr[i] = 0; + //fprintf(stderr,"found a tokenmap %s -> %s %s\n",coin,tmpstr,ptr->tokenid); + ptr->istoken = 1; + strcpy(ptr->acname,coin); + strcpy(ptr->coinstr,""); + return(tmpstr); + } + } + if ( ptr->isexternal == 0 ) + { + if ( strcmp(coin,"KMD") != 0 ) + { + strcpy(ptr->acname,coin); + strcpy(ptr->coinstr,""); + } + else + { + strcpy(ptr->coinstr,coin); + strcpy(ptr->acname,""); + } + } + else + { + strcpy(ptr->coinstr,coin); + strcpy(ptr->acname,""); + } + return(coin); + } + else + { + for (i=1; coin[i]!=0; i++) + if ( isupper(coin[i]) == 0 ) + return(coin); + if ( strcmp(coin+1,"KMD") != 0 ) + ptr->iszaddr = 1; + return(coin+1); + } +} + +int32_t subatomic_zonly(struct coininfo *coin) +{ + if ( strcmp(coin->coin,"PIRATE") == 0 ) + return(1); + else return(coin->iszaddr); +} + +// //////////////////////////////// the four key functions needed to support a new item for subatomics + +int64_t _subatomic_getbalance(struct coininfo *coin) +{ + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; + if ( (retjson= subatomic_cli(coin->cli,&retstr,"getbalance","","","","","","","")) != 0 ) + { + fprintf(stderr,"_subatomic_getbalance.(%s) %s returned json!\n",coin->coinstr,coin->cli); + free_json(retjson); + } + else if ( retstr != 0 ) + { + amount = atof(retstr) * SATOSHIDEN; + sprintf(cmpstr,"%.8f",dstr(amount)); + if ( strcmp(retstr,cmpstr) != 0 ) + amount++; + //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); + free(retstr); + } + return (amount); +} + +bits256 _subatomic_sendtoaddress(struct coininfo *coin,char *destaddr,int64_t satoshis) +{ + char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid; + memset(txid.bytes,0,sizeof(txid)); + sprintf(numstr,"%.8f",(double)satoshis/SATOSHIDEN); + if ( (retjson= subatomic_cli(coin->cli,&retstr,"sendtoaddress",destaddr,numstr,"false","","","","")) != 0 ) + { + fprintf(stderr,"unexpected _subatomic_sendtoaddress json.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + if ( strlen(retstr) >= 64 ) + { + retstr[64] = 0; + decode_hex(txid.bytes,32,retstr); + } + fprintf(stderr,"_subatomic_sendtoaddress %s %.8f txid.(%s)\n",destaddr,(double)satoshis/SATOSHIDEN,bits256_str(str,txid)); + free(retstr); + } + return(txid); +} + +cJSON *_subatomic_rawtransaction(struct coininfo *coin,bits256 txid) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= subatomic_cli(coin->cli,&retstr,"getrawtransaction",bits256_str(str,txid),"1","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"_subatomic_rawtransaction.(%s) %s error.(%s)\n",coin->coin,coin->name,retstr); + free(retstr); + } + return(0); +} + +int64_t subatomic_getbalance(struct coininfo *coin) +{ + char *coinstr,*acname=""; FILE *fp; int64_t retval = 0; + if ( strcmp(coin->coin,"KMD") != 0 ) + { + acname = coin->coin; + coinstr = ""; + } else coinstr = coin->coin; + if ( coin->isfile != 0 ) + { + if ( (fp= fopen(coin->name+1,"rb")) != 0 ) // if alice, add bob pubkey to fname + { + fclose(fp); + retval = SATOSHIDEN; + } + return(retval); + } + else if ( subatomic_zonly(coin) != 0 ) + return(z_getbalance(coinstr,acname,DPOW_recvZaddr)); + else + { + if ( coin->istoken != 0 ) + { + if ( get_getbalance(coinstr,acname) < SUBATOMIC_TXFEE ) + { + fprintf(stderr,"not enough balance to send token\n"); + return(0); + } + //fprintf(stderr,"token balance %s\n",coin->tokenid); + return(get_tokenbalance(coinstr,acname,coin->tokenid) * SATOSHIDEN); + } + else if ( coin->isexternal == 0 ) + return(get_getbalance(coinstr,acname)); + else return(_subatomic_getbalance(coin)); + } +} + +bits256 subatomic_coinpayment(uint32_t origid,int32_t OTCmode,struct coininfo *coin,char *destaddr,uint64_t paytoshis,char *memostr,char *destpub,char *senderpub) +{ + bits256 txid; char opidstr[128],opretstr[32],str[65],*status,*coinstr,*acname=""; cJSON *retjson,*retjson2,*item,*res; int32_t i,pending=0; + memset(&txid,0,sizeof(txid)); + if ( OTCmode == 0 ) + { + fprintf(stderr,"micropayment channels are not supported yet\n"); + return(txid); + } + if ( coin->isfile != 0 ) + { + fprintf(stderr,"start broadcast of (%s)\n",coin->coin+1); + if ( (retjson= dpow_publish(SUBATOMIC_PRIORITY,coin->coin+1)) != 0 ) // spawn thread + { + sprintf(opretstr,"%08x",juint(retjson,"id")); + sprintf(opidstr,"%u",origid); + if ( (retjson2= dpow_broadcast(SUBATOMIC_PRIORITY,opretstr,"inbox",opidstr,senderpub,"","")) != 0 ) + free_json(retjson2); + fprintf(stderr,"broadcast file.(%s) and send id.%u to alice (%s)\n",coin->coin+1,juint(retjson,"id"),jprint(retjson,0)); + txid = jbits256(retjson,"filehash"); + free_json(retjson); + } + fprintf(stderr,"end broadcast of (%s) to %s\n",coin->coin+1,senderpub); + return(txid); + } + else if ( subatomic_zonly(coin) != 0 ) + { + if ( memostr[0] == 0 ) + memostr = "beef"; + z_sendmany(opidstr,"",coin->coin,DPOW_recvZaddr,destaddr,paytoshis,memostr); + for (i=0; icoin,opidstr)) != 0 ) + { + item = jitem(retjson,0); + if ( (status= jstr(item,"status")) != 0 ) + { + if ( strcmp(status,"executing") == 0 ) + pending++; + else + { + res = jobj(item,"result"); + txid = jbits256(res,"txid"); + //fprintf(stderr,"got Ztx txid.%s\n",bits256_str(str,txid)); + free_json(retjson); + break; + } + /*else if ( clearresults != 0 ) + { + if ( (result= z_getoperationresult(coinstr,"",jstri(array,i))) != 0 ) + { + free_json(result); + } + }*/ + } + free_json(retjson); + } + sleep(1); + } + if ( i == 60 ) + printf("%u timed out waiting for opid to finish\n",origid); + } + else + { + if ( strcmp(coin->coin,"KMD") != 0 ) + { + acname = coin->coin; + coinstr = ""; + } else coinstr = coin->coin; + if ( coin->istoken != 0 ) + txid = tokentransfer(coinstr,acname,coin->tokenid,destpub,paytoshis/SATOSHIDEN); + else if ( coin->isexternal == 0 ) + { + sprintf(opretstr,"%08x",origid); + txid = sendtoaddress(coinstr,acname,destaddr,paytoshis,opretstr); + } else txid = _subatomic_sendtoaddress(coin,destaddr,paytoshis); + printf("%u got txid.%s\n",origid,bits256_str(str,txid)); + } + return(txid); +} + +cJSON *subatomic_txidwait(struct coininfo *coin,bits256 txid,char *hexstr,int32_t numseconds,char *senderpub) +{ + int32_t i,zflag; char *coinstr,str[65],*acname=""; cJSON *rawtx; bits256 z; bits256 filehash; + memset(&z,0,sizeof(z)); + if ( memcmp(&z,&txid,sizeof(txid)) == 0 ) + return(0); + if ( hexstr != 0 && hexstr[0] != 0 ) // probably not worth doing and zaddr is a problem to decode + { + // compare against txid + // if matches, sendrawtransaction if OTC mode, decoode and return if channels mode + } + zflag = (subatomic_zonly(coin) != 0); + if ( strcmp(coin->coin,"KMD") != 0 ) + { + acname = coin->coin; + coinstr = ""; + } else coinstr = coin->coin; + for (i=0; iisfile != 0 ) + { + if ( (rawtx= dpow_subscribe(SUBATOMIC_PRIORITY,coin->coin+1,senderpub)) != 0 ) + { + filehash = jbits256(rawtx,"filehash"); + if ( memcmp(&filehash,&txid,sizeof(filehash)) != 0 ) + { + fprintf(stderr,"waiting (%s) (%s)\n",coin->coin+1,jprint(rawtx,0)); + free_json(rawtx); + rawtx = 0; + } else return(rawtx); + } + } + else if ( zflag != 0 ) + rawtx = get_z_viewtransaction(coinstr,acname,txid); + else if ( coin->isexternal == 0 ) + rawtx = get_rawtransaction(coinstr,acname,txid); + else rawtx = _subatomic_rawtransaction(coin,txid); + if ( rawtx != 0 ) + return(rawtx); + sleep(1); + } + printf("%s/%s timeout waiting for %s\n",coin->name,coin->coin,bits256_str(str,txid)); + return(0); +} + +int64_t subatomic_verifypayment(struct coininfo *coin,cJSON *rawtx,uint64_t destsatoshis,char *destaddr,bits256 txid) +{ + int32_t i,n,m,valid=0; bits256 tokenid,filehash,checkhash; cJSON *array,*item,*sobj,*a; char *addr,*acname,*coinstr,tokenaddr[64],*hex; uint8_t hexbuf[512],pub33[33]; uint64_t netval,recvsatoshis = 0; + if ( coin->isfile != 0 ) + { + filehash = jbits256(rawtx,"filehash"); + checkhash = jbits256(rawtx,"checkhash"); + if ( memcmp(&txid,&filehash,sizeof(txid)) == 0 && memcmp(&txid,&checkhash,sizeof(txid)) == 0 ) + { + fprintf(stderr,"verified file is matching the filehash (%s)\n",jprint(rawtx,0)); + return(SATOSHIDEN); + } else return(0); + } + else if ( subatomic_zonly(coin) != 0 ) + { + if ( (array= jarray(&n,rawtx,"outputs")) != 0 && n > 0 ) + { + for (i=0; iistoken != 0 ) + { + if ( (array= jarray(&n,rawtx,"vout")) != 0 && n > 0 ) + { + item = jitem(array,0); + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (a= jarray(&m,sobj,"addresses")) != 0 && m == 1 ) + { + if ( strcmp(coin->coin,"KMD") != 0 ) + { + acname = coin->coin; + coinstr = ""; + } else coinstr = coin->coin; + if ( get_tokenaddress(coinstr,acname,tokenaddr) != 0 ) + { + //fprintf(stderr,"tokenaddr.%s\n",tokenaddr); + if ( (addr= jstri(a,0)) != 0 && strcmp(addr,tokenaddr) == 0 ) + recvsatoshis += SATOSHIDEN * (uint64_t)(jdouble(item,"value")*SATOSHIDEN + 0.000000004999); + else fprintf(stderr,"miscompare (%s) vs %s\n",jprint(sobj,0),addr); + } + } + item = jitem(array,n-1); + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (hex= jstr(sobj,"hex")) != 0 && (m= is_hexstr(hex,0)) > 1 && m/2 < sizeof(hexbuf) ) + { + m >>= 1; + decode_hex(hexbuf,m,hex); + decode_hex(tokenid.bytes,32,coin->tokenid); + decode_hex(pub33,33,DPOW_secpkeystr); + // opret 69len EVAL_TOKENS 't' tokenid 1 33 pub33 + if ( hexbuf[0] == 0x6a && hexbuf[1] == 0x45 && hexbuf[2] == 0xf2 && hexbuf[3] == 't' && memcmp(&hexbuf[4],&tokenid,sizeof(tokenid)) == 0 && hexbuf[4+32] == 1 && hexbuf[4+32+1] == 33 && memcmp(&hexbuf[4+32+2],pub33,33) == 0 ) + { + valid = 1; + //fprintf(stderr,"validated it is a token transfer!\n"); + } else fprintf(stderr,"need to validate tokentransfer.(%s) %s %d\n",hex,DPOW_secpkeystr,memcmp(&hexbuf[4+32+2],pub33,33) == 0); + //6a 45 f2 74 2b1feef719ecb526b07416dd432bce603ac6dc8bfe794cddf105cb52f6aae3cd 01 21 02b27de3ee5335518b06f69f4fbabb029cfc737613b100996841d5532b324a5a61 + + } + recvsatoshis *= valid; + } + } + else + { + if ( (array= jarray(&n,rawtx,"vout")) != 0 && n > 0 ) + { + for (i=0; iorigid = origid; + HASH_ADD(hh,Messages,origid,sizeof(origid),mp); + return(mp); +} + +int32_t subatomic_status(struct msginfo *mp,int32_t status) +{ + static FILE *fp; + if ( fp == 0 ) + { + int32_t i,oid,s,n,num,count; struct msginfo *m; long fsize; + if ( (fp= fopen("SUBATOMIC.DB","rb+")) == 0 ) + { + if ( (fp= fopen("SUBATOMIC.DB","wb")) == 0 ) + { + fprintf(stderr,"cant create SUBATOMIC.DB\n"); + exit(-1); + } + } + else + { + fseek(fp,0,SEEK_END); + fsize = ftell(fp); + if ( (fsize % (sizeof(uint32_t)*2)) != 0 ) + { + fprintf(stderr,"SUBATOMIC.DB illegal filesize.%ld\n",fsize); + exit(-1); + } + n = (int32_t)(fsize / (sizeof(uint32_t)*2)); + rewind(fp); + for (i=num=count=0; i SUBATOMIC_CLOSED ) + { + fprintf(stderr,"SUBATOMIC.DB corrupted at filepos.%ld: illegal status.%d\n",ftell(fp),s); + exit(-1); + } + //fprintf(stderr,"%u <- %d\n",oid,s); + if ( (m= subatomic_find(oid)) == 0 ) + { + m = subatomic_add(oid); + count++; + } + if ( s > m->status ) + { + m->status = s; + num++; + } + } + fprintf(stderr,"initialized %d messages, updated %d out of total.%d\n",count,num,n); + } + } + if ( mp->status >= status ) + return(-1); + if ( fwrite(&mp->origid,1,sizeof(mp->origid),fp) != sizeof(mp->origid) || fwrite(&status,1,sizeof(status),fp) != sizeof(status) ) + fprintf(stderr,"error updating SUBATOMIC.DB, risk of double spends\n"); + fflush(fp); + mp->status = status; + return(0); +} + +struct msginfo *subatomic_tracker(uint32_t origid) +{ + struct msginfo *mp; + if ( (mp= subatomic_find(origid)) == 0 ) + { + mp = subatomic_add(origid); + subatomic_status(mp,0); + } + return(mp); +} + +char *subatomic_hexstr(char *jsonstr) +{ + char *hexstr; int32_t i,c,n = (int32_t)strlen(jsonstr); + hexstr = malloc(2*n + 3); + strcpy(hexstr,jsonstr); + for (i=0; iorigid); + jaddnum(item,"price",mp->price); + jaddnum(item,"openrequest",mp->openrequestid); + jaddstr(item,"base",mp->base.name); + jaddstr(item,"basecoin",mp->base.coin); + jadd64bits(item,"basesatoshis",mp->base.satoshis); + jadd64bits(item,"basetxfee",mp->base.txfee); + jadd64bits(item,"maxbaseamount",mp->base.maxamount); + jaddstr(item,"rel",mp->rel.name); + jaddstr(item,"relcoin",mp->rel.coin); + jadd64bits(item,"relsatoshis",mp->rel.satoshis); + jadd64bits(item,"reltxfee",mp->rel.txfee); + jadd64bits(item,"maxrelamount",mp->rel.maxamount); + jaddstr(item,"alice",mp->alice.pubkey); + jaddstr(item,"alicesecp",mp->alice.secp); + jaddstr(item,"bob",mp->bob.pubkey); + jaddstr(item,"bobsecp",mp->bob.secp); + if ( subatomic_zonly(&mp->rel) != 0 ) + jaddstr(item,"bobZaddr",mp->bob.recvZaddr); + else jaddstr(item,"bobaddr",mp->bob.recvaddr); + if ( mp->rel.istoken != 0 ) + jaddstr(item,"bobtoken",mp->rel.tokenid); + if ( subatomic_zonly(&mp->base) != 0 ) + jaddstr(item,"aliceZaddr",mp->alice.recvZaddr); + else jaddstr(item,"aliceaddr",mp->alice.recvaddr); + if ( mp->base.istoken != 0 ) + jaddstr(item,"alicetoken",mp->base.tokenid); + return(item); +} + +uint64_t subatomic_orderbook_mpset(struct msginfo *mp,char *basecheck) +{ + cJSON *retjson; char *tagA,*tagB,*senderpub,*str,tmpstr[32]; int32_t matches=0; double volA,volB; int64_t txfee=0; + strcpy(mp->base.name,basecheck); + strcpy(mp->base.coin,subatomic_checkname(tmpstr,mp,0,basecheck)); + mp->rel.txfee = subatomic_txfee(mp->rel.coin); + if ( (retjson= dpow_get(mp->origid)) != 0 ) + { + //fprintf(stderr,"dpow_get.(%s) (%s/%s)\n",jprint(retjson,0),mp->base.coin,mp->rel.coin); + if ( (senderpub= jstr(retjson,"senderpub")) != 0 && is_hexstr(senderpub,0) == 66 && (tagA= jstr(retjson,"tagA")) != 0 && (tagB= jstr(retjson,"tagB")) != 0 && strncmp(tagB,mp->rel.name,strlen(mp->rel.name)) == 0 && strlen(tagA) < sizeof(mp->base.name) ) + { + strcpy(mp->base.name,tagA); + strcpy(mp->base.coin,subatomic_checkname(tmpstr,mp,0,tagA)); + if ( basecheck[0] == 0 || strncmp(basecheck,tagA,strlen(basecheck)) == 0 ) + matches = 1; + else if ( strcmp(tagA,mp->base.name) == 0 ) + matches = 1; + else if ( mp->bobflag != 0 && tagA[0] == '#' && strcmp(mp->base.name,"#allfiles") == 0 ) + matches = 1; + if ( matches != 0 ) + { + if ( (str= jstr(retjson,"decrypted")) != 0 && strlen(str) < 128 ) + strcpy(mp->payload,str); + mp->locktime = juint(retjson,"timestamp") + SUBATOMIC_LOCKTIME; + mp->base.txfee = subatomic_txfee(mp->base.coin); + strcpy(mp->senderpub,senderpub); + volB = jdouble(retjson,"amountB"); + volA = jdouble(retjson,"amountA"); + mp->base.maxamount = volA*SATOSHIDEN + 0.0000000049999; + mp->rel.maxamount = volB*SATOSHIDEN + 0.0000000049999; + if ( 0 && mp->rel.istoken == 0 ) + txfee = mp->rel.txfee; + if ( mp->base.maxamount != 0 && mp->rel.maxamount != 0 && volA > SMALLVAL && volB > SMALLVAL && mp->rel.satoshis <= mp->rel.maxamount ) + { + mp->price = volA / volB; + mp->base.satoshis = (mp->rel.satoshis - txfee) * mp->price; + //fprintf(stderr,"base satoshis.%llu\n",(long long)mp->base.satoshis); + } else fprintf(stderr,"%u rel %llu vs (%llu %llu)\n",mp->origid,(long long)mp->rel.satoshis,(long long)mp->base.maxamount,(long long)mp->rel.maxamount); + } else printf("%u didnt match (%s) tagA.%s %s, tagB.%s %s %d %d\n",mp->origid,basecheck,tagA,mp->base.name,tagB,mp->rel.name,tagA[0] == '#', strcmp(mp->base.name,"#allfiles") == 0); + } else printf("%u didnt compare tagA.%s %s, tagB.%s %s\n",mp->origid,tagA,mp->base.name,tagB,mp->rel.name); + free_json(retjson); + } + return(mp->base.satoshis); +} + +char *randhashstr(char *str) +{ + bits256 rands; int32_t i; + for (i=0; i<32; i++) + rands.bytes[i] = rand() >> 17; + bits256_str(str,rands); + return(str); +} + +void subatomic_extrafields(cJSON *dest,cJSON *src) +{ + char *str; + if ( (str= jstr(src,"approval")) != 0 ) + jaddstr(dest,"approval",str); + if ( (str= jstr(src,"opened")) != 0 ) + jaddstr(dest,"opened",str); + if ( (str= jstr(src,"payamount")) != 0 ) + jaddstr(dest,"payamount",str); + if ( (str= jstr(src,"destaddr")) != 0 ) + jaddstr(dest,"destaddr",str); + if ( (str= jstr(src,"bobpayment")) != 0 ) + jaddstr(dest,"bobpayment",str); + if ( (str= jstr(src,"alicepayment")) != 0 ) + jaddstr(dest,"alicepayment",str); + if ( (str= jstr(src,"bobaddr")) != 0 ) + jaddstr(dest,"bobaddr",str); + if ( (str= jstr(src,"bobZaddr")) != 0 ) + jaddstr(dest,"bobZaddr",str); + if ( (str= jstr(src,"aliceaddr")) != 0 ) + jaddstr(dest,"aliceaddr",str); + if ( (str= jstr(src,"aliceZaddr")) != 0 ) + jaddstr(dest,"aliceZaddr",str); + if ( (str= jstr(src,"alicetoken")) != 0 ) + jaddstr(dest,"alicetoken",str); + if ( (str= jstr(src,"bobtoken")) != 0 ) + jaddstr(dest,"bobtoken",str); +} + +char *subatomic_submit(cJSON *argjson,int32_t tobob) +{ + char *jsonstr,*hexstr; + jaddnum(argjson,"tobob",tobob != 0); + jsonstr = jprint(argjson,1); + hexstr = subatomic_hexstr(jsonstr); + free(jsonstr); + return(hexstr); +} + +#define SCRIPT_OP_IF 0x63 +#define SCRIPT_OP_ELSE 0x67 +#define SCRIPT_OP_DUP 0x76 +#define SCRIPT_OP_ENDIF 0x68 +#define SCRIPT_OP_TRUE 0x51 +#define SCRIPT_OP_2 0x52 +#define SCRIPT_OP_3 0x53 +#define SCRIPT_OP_DROP 0x75 +#define SCRIPT_OP_EQUALVERIFY 0x88 +#define SCRIPT_OP_HASH160 0xa9 +#define SCRIPT_OP_EQUAL 0x87 +#define SCRIPT_OP_CHECKSIG 0xac +#define SCRIPT_OP_CHECKMULTISIG 0xae +#define SCRIPT_OP_CHECKMULTISIGVERIFY 0xaf +#define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 + +int32_t subatomic_redeemscript(char *redeemscript,uint32_t locktime,char *pubkeyA,char *pubkeyB) // not needed +{ + // if ( refund ) OP_HASH160 <2of2 multisig hash> OP_EQUAL // standard multisig + // else CLTV OP_DROP OP_CHECKSIG // standard spend + uint8_t pubkeyAbytes[33],pubkeyBbytes[33],hex[4096]; int32_t i,n = 0; + decode_hex(pubkeyAbytes,33,pubkeyA); + decode_hex(pubkeyBbytes,33,pubkeyB); + hex[n++] = SCRIPT_OP_IF; + hex[n++] = SCRIPT_OP_2; + hex[n++] = 33, memcpy(&hex[n],pubkeyAbytes,33), n += 33; + hex[n++] = 33, memcpy(&hex[n],pubkeyBbytes,33), n += 33; + hex[n++] = SCRIPT_OP_2; + hex[n++] = SCRIPT_OP_CHECKMULTISIG; + hex[n++] = SCRIPT_OP_ELSE; + hex[n++] = 4; + hex[n++] = locktime & 0xff, locktime >>= 8; + hex[n++] = locktime & 0xff, locktime >>= 8; + hex[n++] = locktime & 0xff, locktime >>= 8; + hex[n++] = locktime & 0xff; + hex[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; + hex[n++] = SCRIPT_OP_DROP; + hex[n++] = 33; memcpy(&hex[n],pubkeyAbytes,33); n += 33; + hex[n++] = SCRIPT_OP_CHECKSIG; + hex[n++] = SCRIPT_OP_ENDIF; + for (i=0; i>4) & 0xf); + redeemscript[i*2 + 1] = hexbyte(hex[i] & 0xf); + } + redeemscript[n*2] = 0; + /*tmpbuf[0] = SCRIPT_OP_HASH160; + tmpbuf[1] = 20; + calc_OP_HASH160(scriptPubKey,tmpbuf+2,redeemscript); + tmpbuf[22] = SCRIPT_OP_EQUAL; + init_hexbytes_noT(scriptPubKey,tmpbuf,23); + if ( p2shaddr != 0 ) + { + p2shaddr[0] = 0; + if ( (btc_addr= base58_encode_check(addrtype,true,tmpbuf+2,20)) != 0 ) + { + if ( strlen(btc_addr->str) < 36 ) + strcpy(p2shaddr,btc_addr->str); + cstr_free(btc_addr,true); + } + }*/ + return(n); +} + +int32_t subatomic_approved(struct msginfo *mp,cJSON *approval,cJSON *msgjson,char *senderpub) +{ + char *hexstr,numstr[32],redeemscript[1024],*coin,*acname=""; cJSON *retjson,*decodejson; int32_t i,retval = 0; + subatomic_extrafields(approval,msgjson); + if ( mp->OTCmode == 0 ) + { + coin = (mp->bobflag != 0) ? mp->base.coin : mp->rel.coin; // the other side gets this coin + if ( strcmp(coin,"KMD") != 0 ) + { + acname = coin; + coin = ""; + } + if ( get_createmultisig2(coin,acname,mp->msigaddr,mp->redeemscript,mp->alice.secp,mp->bob.secp) != 0 ) + { + subatomic_redeemscript(redeemscript,mp->locktime,mp->alice.secp,mp->bob.secp); + if ( (decodejson= get_decodescript(coin,acname,redeemscript)) != 0 ) + { + fprintf(stderr,"%s %s msigaddr.%s %s -> %s %s\n",mp->bobflag!=0?"bob":"alice",(mp->bobflag != 0) ? mp->base.coin : mp->rel.coin,mp->msigaddr,mp->redeemscript,redeemscript,jprint(decodejson,0)); + free(decodejson); + } + } + } + sprintf(numstr,"%u",mp->origid); + for (i=0; numstr[i]!=0; i++) + sprintf(&mp->approval[i<<1],"%02x",numstr[i]); + sprintf(&mp->approval[i<<1],"%02x",' '); + i++; + mp->approval[i<<1] = 0; + jaddstr(approval,"approval",mp->approval); + hexstr = subatomic_submit(approval,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"approved",senderpub,"","")) != 0 ) + { + if ( (mp->approvalid= juint(retjson,"id")) != 0 ) + retval = 1; + printf("%u approvalid.%u (%s)\n",mp->origid,mp->approvalid,senderpub); + subatomic_status(mp,SUBATOMIC_APPROVED); + free_json(retjson); + } + free(hexstr); + return(retval); +} + +int32_t subatomic_opened(struct msginfo *mp,cJSON *opened,cJSON *msgjson,char *senderpub) +{ + char *hexstr,channelstr[65]; cJSON *retjson; int32_t retval = 0; + subatomic_extrafields(opened,msgjson); + jaddstr(opened,"opened",randhashstr(channelstr)); + hexstr = subatomic_submit(opened,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"opened",senderpub,"","")) != 0 ) + { + if ( (mp->openedid= juint(retjson,"id")) != 0 ) + retval = 1; + printf("%u openedid.%u\n",mp->origid,mp->openedid); + subatomic_status(mp,SUBATOMIC_OPENED); + free_json(retjson); + } + free(hexstr); + return(retval); +} + +int32_t subatomic_payment(struct msginfo *mp,cJSON *payment,cJSON *msgjson,char *senderpub) +{ + bits256 txid; uint64_t paytoshis; cJSON *retjson; char numstr[32],*coin,*dest,*hexstr; int32_t retval = 0; + if ( mp->bobflag == 0 ) + { + coin = mp->rel.name; + paytoshis = mp->rel.satoshis; + if ( subatomic_zonly(&mp->rel) != 0 ) + dest = mp->bob.recvZaddr; + else dest = mp->bob.recvaddr; + sprintf(numstr,"%llu",(long long)paytoshis); + jaddstr(payment,"alicepays",numstr); + jaddstr(payment,"bobdestaddr",dest); + txid = subatomic_coinpayment(mp->origid,mp->OTCmode,&mp->rel,dest,paytoshis,mp->approval,mp->bob.secp,senderpub); + jaddbits256(payment,"alicepayment",txid); + mp->alicepayment = txid; + hexstr = 0; // get it from rawtransaction of txid + jaddstr(payment,"alicetx",hexstr); + } + else + { + coin = mp->base.name; + paytoshis = mp->base.satoshis; + if ( subatomic_zonly(&mp->base) != 0 ) + dest = mp->alice.recvZaddr; + else dest = mp->alice.recvaddr; + sprintf(numstr,"%llu",(long long)paytoshis); + jaddstr(payment,"bobpays",numstr); + jaddstr(payment,"alicedestaddr",dest); + txid = subatomic_coinpayment(mp->origid,mp->OTCmode,&mp->base,dest,paytoshis,mp->approval,mp->alice.secp,senderpub); + jaddbits256(payment,"bobpayment",txid); + mp->bobpayment = txid; + hexstr = 0; // get it from rawtransaction of txid + jaddstr(payment,"bobtx",hexstr); + } + hexstr = subatomic_submit(payment,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"payment",senderpub,"","")) != 0 ) + { + if ( (mp->paymentids[0]= juint(retjson,"id")) != 0 ) + retval = 1; + printf("%u: %.8f %s -> %s, paymentid[0] %u\n",mp->origid,dstr(paytoshis),coin,dest,mp->paymentids[0]); + subatomic_status(mp,SUBATOMIC_PAYMENT); + free_json(retjson); + } + free(hexstr); + return(retval); +} + +int32_t subatomic_paidinfull(struct msginfo *mp,cJSON *paid,cJSON *msgjson,char *senderpub) +{ + char *hexstr; cJSON *retjson; int32_t retval = 0; + jaddstr(paid,"paid","in full"); + subatomic_extrafields(paid,msgjson); + hexstr = subatomic_submit(paid,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"paid",senderpub,"","")) != 0 ) + { + if ( (mp->paidid= juint(retjson,"id")) != 0 ) + retval = 1; + printf("%u paidid.%u\n",mp->origid,mp->paidid); + subatomic_status(mp,SUBATOMIC_PAIDINFULL); + free_json(retjson); + } + free(hexstr); + return(retval); +} + +int32_t subatomic_closed(struct msginfo *mp,cJSON *closed,cJSON *msgjson,char *senderpub) +{ + char *hexstr; cJSON *retjson; int32_t retval = 0; + jaddnum(closed,"closed",mp->origid); + subatomic_extrafields(closed,msgjson); + hexstr = subatomic_submit(closed,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"closed",senderpub,"","")) != 0 ) + { + if ( (mp->closedid= juint(retjson,"id")) != 0 ) + retval = 1; + subatomic_status(mp,SUBATOMIC_CLOSED); + printf("%u closedid.%u\n",mp->origid,mp->closedid); + free_json(retjson); + } + free(hexstr); + return(retval); +} + +uint32_t subatomic_alice_openrequest(struct msginfo *origmp) +{ + struct msginfo *mp; cJSON *retjson,*openrequest; char *hexstr,*str,tmpstr[32]; + mp = subatomic_tracker(origmp->origid); + mp->origid = origmp->origid; + mp->rel.satoshis = origmp->rel.satoshis; + mp->rel.istoken = origmp->rel.istoken; + strcpy(mp->rel.tokenid,origmp->rel.tokenid); + strcpy(mp->rel.name,origmp->rel.name); + strcpy(mp->rel.coin,subatomic_checkname(tmpstr,mp,1,origmp->rel.name)); + strcpy(mp->alice.pubkey,DPOW_pubkeystr); + strcpy(mp->alice.secp,DPOW_secpkeystr); + strcpy(mp->alice.recvZaddr,DPOW_recvZaddr); + strcpy(mp->alice.recvaddr,DPOW_recvaddr); + printf("rel.%s/%s %s openrequest %u status.%d (%s/%s)\n",mp->rel.name,mp->rel.coin,mp->rel.tokenid,mp->origid,mp->status,mp->alice.recvaddr,mp->alice.recvZaddr); + if ( mp->status == 0 && subatomic_orderbook_mpset(mp,"") != 0 ) + { + strcpy(mp->bob.pubkey,mp->senderpub); + if ( subatomic_zonly(&mp->base) != 0 || subatomic_zonly(&mp->rel) != 0 ) + mp->OTCmode = 1; + else mp->OTCmode = SUBATOMIC_OTCDEFAULT; + strcpy(origmp->base.name,mp->base.name); + strcpy(origmp->base.coin,mp->base.coin); + origmp->base.istoken = mp->base.istoken; + strcpy(origmp->base.tokenid,mp->base.tokenid); + origmp->OTCmode = mp->OTCmode; + if ( mp->rel.istoken != 0 && ((mp->rel.satoshis % SATOSHIDEN) != 0 || mp->rel.iszaddr != 0) ) + { + printf("%u cant do zaddr or fractional rel %s.%s tokens %.8f\n",mp->origid,mp->rel.coin,mp->rel.tokenid,dstr(mp->rel.satoshis)); + return(0); + } + else if ( mp->base.istoken != 0 && ((mp->base.satoshis % SATOSHIDEN) != 0 || mp->base.iszaddr != 0 ) ) + { + printf("%u cant do zaddr or fractional base %s.%s tokens %.8f\n",mp->origid,mp->base.coin,mp->base.tokenid,dstr(mp->base.satoshis)); + return(0); + } + else if ( (openrequest= subatomic_mpjson(mp)) != 0 ) + { + hexstr = subatomic_submit(openrequest,!mp->bobflag); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,(char *)"inbox",(char *)"openrequest",mp->bob.pubkey,"","")) != 0 ) + { + mp->openrequestid = juint(retjson,"id"); + printf("%u openrequest.%u -> (%s)\n",mp->origid,mp->openrequestid,mp->bob.pubkey); + subatomic_status(mp,SUBATOMIC_OPENREQUEST); + free_json(retjson); + } + free(hexstr); + } + } + return(mp->openrequestid); +} + +void subatomic_bob_gotopenrequest(uint32_t inboxid,char *senderpub,cJSON *msgjson,char *basename,char *relname) +{ + struct msginfo *mp; cJSON *approval; int32_t origid; char *addr,tmpstr[32],*coin,*acname=""; + origid = juint(msgjson,"origid"); + mp = subatomic_tracker(origid); + strcpy(mp->base.name,basename); + strcpy(mp->base.coin,subatomic_checkname(tmpstr,mp,0,basename)); + strcpy(mp->rel.name,relname); + strcpy(mp->rel.coin,subatomic_checkname(tmpstr,mp,1,relname)); + mp->origid = origid; + mp->rel.satoshis = j64bits(msgjson,"relsatoshis"); + mp->bobflag = 1; + strcpy(mp->bob.pubkey,DPOW_pubkeystr); + strcpy(mp->bob.secp,DPOW_secpkeystr); + strcpy(mp->bob.recvZaddr,DPOW_recvZaddr); + strcpy(mp->bob.recvaddr,DPOW_recvaddr); + if ( (addr= jstr(msgjson,"aliceaddr")) != 0 ) + strcpy(mp->alice.recvaddr,addr); + if ( (addr= jstr(msgjson,"aliceZaddr")) != 0 ) + strcpy(mp->alice.recvZaddr,addr); + if ( (addr= jstr(msgjson,"alicesecp")) != 0 ) + strcpy(mp->alice.secp,addr); + if ( subatomic_zonly(&mp->base) != 0 || subatomic_zonly(&mp->rel) != 0 ) + mp->OTCmode = 1; + else mp->OTCmode = SUBATOMIC_OTCDEFAULT; + printf("%u got open request\n",mp->origid); + if ( mp->status == 0 && subatomic_orderbook_mpset(mp,basename) != 0 && (approval= subatomic_mpjson(mp)) != 0 ) + { + if ( mp->rel.istoken != 0 && ((mp->rel.satoshis % SATOSHIDEN) != 0 || mp->rel.iszaddr != 0) ) + { + printf("%u cant do zaddr or fractional rel %s.%s tokens %.8f\n",mp->origid,mp->rel.coin,mp->rel.tokenid,dstr(mp->rel.satoshis)); + subatomic_closed(mp,approval,msgjson,senderpub); + return; + } + else if ( mp->base.istoken != 0 && ((mp->base.satoshis % SATOSHIDEN) != 0 || mp->base.iszaddr != 0 ) ) + { + printf("%u cant do zaddr or fractional base %s.%s tokens %.8f\n",mp->origid,mp->base.coin,mp->base.tokenid,dstr(mp->base.satoshis)); + subatomic_closed(mp,approval,msgjson,senderpub); + return; + } + else if ( subatomic_getbalance(&mp->base) < mp->base.satoshis ) + { + printf("%u bob node low on %s funds! %.8f not enough for %.8f\n",mp->origid,mp->base.coin,dstr(subatomic_getbalance(&mp->base)),dstr(mp->base.satoshis)); + subatomic_closed(mp,approval,msgjson,senderpub); + } + else + { + printf("%u bob (%s/%s) gotopenrequest origid.%u status.%d (%s/%s) SENDERPUB.(%s)\n",mp->origid,mp->base.name,mp->rel.name,mp->origid,mp->status,mp->bob.recvaddr,mp->bob.recvZaddr,senderpub); + subatomic_approved(mp,approval,msgjson,senderpub); + } + } +} + +int32_t subatomic_channelapproved(uint32_t inboxid,char *senderpub,cJSON *msgjson,struct msginfo *origmp) +{ + struct msginfo *mp; cJSON *approval; char *addr,*coin,*acname; int32_t retval = 0; + mp = subatomic_tracker(juint(msgjson,"origid")); + if ( subatomic_orderbook_mpset(mp,mp->base.name) != 0 && (approval= subatomic_mpjson(mp)) != 0 ) + { + printf("%u iambob.%d (%s/%s) channelapproved origid.%u status.%d\n",mp->origid,mp->bobflag,mp->base.name,mp->rel.name,mp->origid,mp->status); + if ( mp->bobflag == 0 && mp->status == SUBATOMIC_OPENREQUEST ) + { + if ( (addr= jstr(msgjson,"bobaddr")) != 0 ) + strcpy(mp->bob.recvaddr,addr); + if ( (addr= jstr(msgjson,"bobZaddr")) != 0 ) + strcpy(mp->bob.recvZaddr,addr); + if ( (addr= jstr(msgjson,"bobsecp")) != 0 ) + strcpy(mp->bob.secp,addr); + retval = subatomic_approved(mp,approval,msgjson,senderpub); + } + else if ( mp->bobflag != 0 && mp->status == SUBATOMIC_APPROVED ) + retval = subatomic_opened(mp,approval,msgjson,senderpub); + } + return(retval); +} + +int32_t subatomic_incomingopened(uint32_t inboxid,char *senderpub,cJSON *msgjson,struct msginfo *origmp) +{ + struct msginfo *mp; cJSON *payment; int32_t retval = 0; + mp = subatomic_tracker(juint(msgjson,"origid")); + if ( subatomic_orderbook_mpset(mp,mp->base.name) != 0 && (payment= subatomic_mpjson(mp)) != 0 ) + { + printf("%u iambob.%d (%s/%s) incomingchannel status.%d\n",mp->origid,mp->bobflag,mp->base.name,mp->rel.name,mp->status); + if ( mp->bobflag == 0 && mp->status == SUBATOMIC_APPROVED ) + retval = subatomic_payment(mp,payment,msgjson,senderpub); + else if ( mp->bobflag != 0 && mp->status == SUBATOMIC_OPENED ) + retval = 1; // nothing to do + } + return(retval); +} + +int32_t subatomic_incomingpayment(uint32_t inboxid,char *senderpub,cJSON *msgjson,struct msginfo *origmp) +{ + static FILE *fp; + struct msginfo *mp; cJSON *pay,*rawtx,*retjson; bits256 txid; char str[65],*hexstr; int32_t retval = 0; + mp = subatomic_tracker(juint(msgjson,"origid")); + if ( subatomic_orderbook_mpset(mp,mp->base.name) != 0 && (pay= subatomic_mpjson(mp)) != 0 ) + { + printf("%u iambob.%d (%s/%s) incomingpayment status.%d\n",mp->origid,mp->bobflag,mp->base.name,mp->rel.name,mp->status); + if ( mp->bobflag == 0 ) + { + txid = jbits256(msgjson,"bobpayment"); + jaddbits256(msgjson,"alicepayment",mp->alicepayment); + printf("%u alice waits for %s.%s to be in mempool (%.8f -> %s)\n",mp->origid,mp->base.name,bits256_str(str,txid),dstr(mp->base.satoshis),subatomic_zonly(&mp->base) == 0 ? mp->alice.recvaddr : mp->alice.recvZaddr); + hexstr = jstr(msgjson,"bobtx"); + if ( (rawtx= subatomic_txidwait(&mp->base,txid,hexstr,SUBATOMIC_TIMEOUT,senderpub)) != 0 ) + { + if ( subatomic_verifypayment(&mp->base,rawtx,mp->base.satoshis,subatomic_zonly(&mp->base) == 0 ? mp->alice.recvaddr : mp->alice.recvZaddr,txid) >= 0 ) + mp->gotpayment = 1; + free_json(rawtx); + } + if ( mp->gotpayment != 0 ) + { + printf("%u SWAP COMPLETE <<<<<<<<<<<<<<<<\n",mp->origid); + SUBATOMIC_retval = 0; + if ( mp->base.iszaddr == 0 ) + { + sprintf(str,"%u",mp->origid); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,bits256_str(str,mp->alicepayment),(char *)"completed",str,DPOW_pubkeystr,"","")) != 0 ) + free_json(retjson); + } + } + else + { + printf("%u SWAP INCOMPLETE, waiting on %s.%s\n",mp->origid,mp->base.name,bits256_str(str,txid)); + if ( (fp= fopen("SUBATOMIC.incomplete","a+")) != 0 ) + { + char *jsonstr = jprint(msgjson,0); + fwrite(jsonstr,1,strlen(jsonstr),fp); + fputc('\n',fp); + fclose(fp); + free(jsonstr); + } + if ( mp->base.iszaddr == 0 ) + { + sprintf(str,"%u",mp->origid); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,bits256_str(str,mp->alicepayment),(char *)"incomplete",str,DPOW_pubkeystr,"","")) != 0 ) + free_json(retjson); + } + subatomic_closed(mp,pay,msgjson,senderpub); + exit(-1); + } + } + if ( mp->gotpayment != 0 ) + retval = subatomic_paidinfull(mp,pay,msgjson,senderpub); + else + { + if ( mp->bobflag != 0 && mp->status == SUBATOMIC_OPENED ) + { + txid = jbits256(msgjson,"alicepayment"); + printf("%u bob waits for %s.%s to be in mempool (%.8f -> %s)\n",mp->origid,mp->rel.name,bits256_str(str,txid),dstr(mp->rel.satoshis),subatomic_zonly(&mp->rel) == 0 ? mp->bob.recvaddr : mp->bob.recvZaddr); + hexstr = jstr(msgjson,"alicetx"); + if ( (rawtx= subatomic_txidwait(&mp->rel,txid,hexstr,SUBATOMIC_TIMEOUT,senderpub)) != 0 ) + { + if ( subatomic_verifypayment(&mp->rel,rawtx,mp->rel.satoshis,subatomic_zonly(&mp->rel) == 0 ? mp->bob.recvaddr : mp->bob.recvZaddr,txid) >= 0 ) + mp->gotpayment = 1; + free_json(rawtx); + } + if ( mp->gotpayment != 0 ) + { + retval = subatomic_payment(mp,pay,msgjson,senderpub); + jaddbits256(msgjson,"bobpayment",mp->bobpayment); + if ( mp->rel.iszaddr == 0 ) + { + sprintf(str,"%u",mp->origid); + if ( (retjson= dpow_broadcast(SUBATOMIC_PRIORITY,bits256_str(str,mp->bobpayment),(char *)"completed",str,DPOW_pubkeystr,"","")) != 0 ) + free_json(retjson); + } + printf("%u SWAP COMPLETE <<<<<<<<<<<<<<<<\n",mp->origid); + if ( (fp= fopen("SUBATOMIC.proof","rb+")) == 0 ) + fp = fopen("SUBATOMIC.proof","wb"); + if ( fp != 0 ) + { + char *jsonstr = jprint(msgjson,0); + fseek(fp,0,SEEK_END); + fwrite(jsonstr,1,strlen(jsonstr),fp); + fputc('\n',fp); + fflush(fp); + free(jsonstr); + } + } else printf("%u SWAP INCOMPLETE: %s\n",mp->origid,jprint(msgjson,0)); + } + } + } + return(retval); +} + +int32_t subatomic_incomingfullypaid(uint32_t inboxid,char *senderpub,cJSON *msgjson,struct msginfo *origmp) +{ + struct msginfo *mp; cJSON *closed; int32_t retval = 0; + mp = subatomic_tracker(juint(msgjson,"origid")); + if ( subatomic_orderbook_mpset(mp,mp->base.name) != 0 && (closed= subatomic_mpjson(mp)) != 0 ) + { + printf("%u iambob.%d (%s/%s) incomingfullypaid status.%d\n",mp->origid,mp->bobflag,mp->base.name,mp->rel.name,mp->status); + // error check msgjson vs M + if ( mp->bobflag == 0 && mp->status == SUBATOMIC_PAIDINFULL ) + retval = subatomic_closed(mp,closed,msgjson,senderpub); + else if ( mp->bobflag != 0 && mp->status == SUBATOMIC_PAYMENT ) + retval = subatomic_paidinfull(mp,closed,msgjson,senderpub); + } + return(retval); +} + +int32_t subatomic_incomingclosed(uint32_t inboxid,char *senderpub,cJSON *msgjson,struct msginfo *origmp) +{ + struct msginfo *mp; cJSON *closed; int32_t retval = 0; + mp = subatomic_tracker(juint(msgjson,"origid")); + if ( subatomic_orderbook_mpset(mp,mp->base.name) != 0 && (closed= subatomic_mpjson(mp)) != 0 ) + { + printf("%u iambob.%d (%s/%s) incomingclose status.%d\n",mp->origid,mp->bobflag,mp->base.name,mp->rel.name,mp->status); + if ( mp->bobflag != 0 ) + dpow_cancel(mp->origid); + if ( mp->status < SUBATOMIC_CLOSED ) + { + retval = subatomic_closed(mp,closed,msgjson,senderpub); + subatomic_status(mp,SUBATOMIC_CLOSED); + } + retval = 1; + } + return(retval); +} + +int32_t subatomic_ismine(int32_t bobflag,cJSON *json,char *basename,char *relname) +{ + char *base,*rel; + if ( (base= jstr(json,"base")) != 0 && (rel= jstr(json,"rel")) != 0 ) + { + if ( strcmp(base,basename) == 0 && strcmp(rel,relname) == 0 ) + return(1); + if ( bobflag != 0 ) + { + if ( strcmp(basename,"#allfiles") == 0 && base[0] == '#' ) + return(1); + fprintf(stderr,"skip ismine (%s/%s) vs (%s/%s)\n",basename,relname,base,rel); + } + } + return(0); +} + +void subatomic_tokensregister(int32_t priority) +{ + char *token_name,*tokenid,existing[65]; cJSON *tokens,*token; int32_t i,numtokens; + if ( SUBATOMIC_json != 0 && (tokens= jarray(&numtokens,SUBATOMIC_json,"tokens")) != 0 ) + { + for (i=0; i 0 ) + { + for (j=0; j %s, %u %llu %u\n",mp->bobflag,mp->base.name,mp->rel.name,mp->origid,(long long)mp->rel.satoshis,mp->openrequestid); + while ( 1 ) + { + if ( msgs == 0 ) + { + sleep(1); + fflush(stdout); + if ( mp->bobflag != 0 ) + { + dpow_pubkeyregister(SUBATOMIC_PRIORITY); + subatomic_tokensregister(SUBATOMIC_PRIORITY); + subatomic_filesregister(SUBATOMIC_PRIORITY); + } + } + msgs = 0; + for (iter=0; iter<(int32_t)(sizeof(tagBs)/sizeof(*tagBs)); iter++) + { + tagB = tagBs[iter]; + if ( (ptrs= dpow_inboxcheck(&n,&stopats[iter],tagB)) != 0 ) + { + for (i=0; ijsonstr)) != 0 ) + { + if ( jint(inboxjson,"tobob") != mp->bobflag ) + continue; + if ( subatomic_ismine(mp->bobflag,inboxjson,mp->base.name,mp->rel.name) != 0 ) + { + if ( strcmp(tagB,"openrequest") == 0 && mp->bobflag != 0 ) + subatomic_bob_gotopenrequest(ptr->shorthash,ptr->senderpub,inboxjson,mp->base.name,mp->rel.name); + else if ( strcmp(tagB,"approved") == 0 ) + mask |= subatomic_channelapproved(ptr->shorthash,ptr->senderpub,inboxjson,mp) << 0; + else if ( strcmp(tagB,"opened") == 0 ) + mask |= subatomic_incomingopened(ptr->shorthash,ptr->senderpub,inboxjson,mp) << 1; + else if ( strcmp(tagB,"payment") == 0 ) + mask |= subatomic_incomingpayment(ptr->shorthash,ptr->senderpub,inboxjson,mp) << 2; + else if ( strcmp(tagB,"paid") == 0 ) + mask |= subatomic_incomingfullypaid(ptr->shorthash,ptr->senderpub,inboxjson,mp) << 3; + else if ( strcmp(tagB,"closed") == 0 ) + mask |= subatomic_incomingclosed(ptr->shorthash,ptr->senderpub,inboxjson,mp) * 0x1f; + else fprintf(stderr,"iambob.%d unknown unexpected tagB.(%s)\n",mp->bobflag,tagB); + } + free_json(inboxjson); + } else fprintf(stderr,"subatomic iambob.%d loop got unparseable(%s)\n",mp->bobflag,ptr->jsonstr); + free(ptr); + ptrs[i] = 0; + } + } + free(ptrs); + } + } + if ( mp->bobflag == 0 && (mask & 0x1f) == 0x1f ) + { + printf("alice %u %llu %u finished\n",mp->origid,(long long)mp->rel.satoshis,mp->openrequestid); + break; + } + } +} + +int32_t main(int32_t argc,char **argv) +{ + char *fname = "subatomic.json"; + int32_t i,height; char *coin,*kcli,*subatomic,*hashstr,*acname=(char *)""; cJSON *retjson; bits256 blockhash; char checkstr[65],str[65],str2[65],tmpstr[32]; long fsize; struct msginfo M; + memset(&M,0,sizeof(M)); + srand((int32_t)time(NULL)); + if ( (subatomic= filestr(&fsize,fname)) == 0 ) + { + fprintf(stderr,"cant load %s file\n",fname); + exit(-1); + } + if ( (SUBATOMIC_json= cJSON_Parse(subatomic)) == 0 ) + { + fprintf(stderr,"cant parse subatomic.json file (%s)\n",subatomic); + exit(-1); + } + free(subatomic); + if ( argc >= 4 ) + { + if ( dpow_pubkey() < 0 ) + { + fprintf(stderr,"couldnt set pubkey for DEX\n"); + return(-1); + } + coin = (char *)argv[1]; + if ( argv[2][0] != 0 ) + REFCOIN_CLI = (char *)argv[2]; + else + { + if ( strcmp(coin,"KMD") != 0 ) + { + acname = coin; + } + } + hashstr = (char *)argv[3]; + strcpy(M.rel.coin,subatomic_checkname(tmpstr,&M,1,coin)); + strcpy(M.rel.name,coin); + if ( argc == 4 && strlen(hashstr) == 64 ) // for blocknotify usage, seems not needed + { + height = get_coinheight(coin,acname,&blockhash); + bits256_str(checkstr,blockhash); + if ( strcmp(checkstr,hashstr) == 0 ) + { + fprintf(stderr,"%s: (%s) %s height.%d\n",coin,REFCOIN_CLI!=0?REFCOIN_CLI:"",checkstr,height); + if ( (retjson= dpow_ntzdata(coin,SUBATOMIC_PRIORITY,height,blockhash)) != 0 ) + free_json(retjson); + } else fprintf(stderr,"coin.%s (%s) %s vs %s, height.%d\n",coin,REFCOIN_CLI!=0?REFCOIN_CLI:"",checkstr,hashstr,height); + if ( strcmp("BTC",coin) != 0 ) + { + bits256 prevntzhash,ntzhash; int32_t prevntzheight,ntzheight; uint32_t ntztime,prevntztime; char hexstr[81]; cJSON *retjson2; + prevntzhash = dpow_ntzhash(coin,&prevntzheight,&prevntztime); + if ( (retjson= get_getinfo(coin,acname)) != 0 ) + { + ntzheight = juint(retjson,"notarized"); + ntzhash = jbits256(retjson,"notarizedhash"); + if ( ntzheight > prevntzheight ) + { + get_coinmerkleroot(coin,acname,ntzhash,&ntztime); + fprintf(stderr,"NOTARIZATION %s.%d %s t.%u\n",coin,ntzheight,bits256_str(str,ntzhash),ntztime); + bits256_str(hexstr,ntzhash); + sprintf(&hexstr[64],"%08x",ntzheight); + sprintf(&hexstr[72],"%08x",ntztime); + hexstr[80] = 0; + if ( (retjson2= dpow_broadcast(SUBATOMIC_PRIORITY,hexstr,coin,"notarizations",DPOW_pubkeystr,"","")) != 0 ) + free_json(retjson2); + } + else if ( ntzheight == prevntzheight && memcmp(&prevntzhash,&ntzhash,32) != 0 ) + fprintf(stderr,"NTZ ERROR %s.%d %s != %s\n",coin,ntzheight,bits256_str(str,ntzhash),bits256_str(str2,prevntzhash)); + free_json(retjson); + } + } + } + else if ( argc == 5 && atol(hashstr) > 10000 ) + { + char checkstr[32]; uint64_t mult = 1; + M.origid = (uint32_t)atol(hashstr); + sprintf(checkstr,"%u",M.origid); + if ( strcmp(checkstr,hashstr) == 0 ) // alice + { + M.rel.satoshis = (uint64_t)(atof(argv[4])*SATOSHIDEN+0.0000000049999); + for (i=0; M.rel.name[i]!=0; i++) + if ( M.rel.name[i] == '.' ) + { + mult = SATOSHIDEN; + break; + } + if ( subatomic_getbalance(&M.rel) < M.rel.satoshis/mult ) + { + fprintf(stderr,"not enough balance %s %.8f for %.8f\n",M.rel.coin,dstr(subatomic_getbalance(&M.rel)),dstr(M.rel.satoshis/mult)); + return(-1); + } + fprintf(stderr,"subatomic_channel_alice (%s/%s) %s %u with %.8f %llu\n",M.rel.name,M.rel.coin,hashstr,M.origid,atof(argv[4]),(long long)M.rel.satoshis); + dpow_pubkeyregister(SUBATOMIC_PRIORITY); + M.openrequestid = subatomic_alice_openrequest(&M); + if ( M.openrequestid != 0 ) + subatomic_loop(&M); + } else fprintf(stderr,"checkstr mismatch %s %s != %s\n",coin,hashstr,checkstr); + } + else + { + M.bobflag = 1; + strcpy(M.base.name,hashstr); + strcpy(M.base.coin,subatomic_checkname(tmpstr,&M,0,hashstr)); + subatomic_loop(&M); // while ( 1 ) loop for each relcoin -> basecoin + } + } + return(SUBATOMIC_retval); +} + diff --git a/src/cc/dapps/subatomic.json b/src/cc/dapps/subatomic.json new file mode 100644 index 000000000..7420c712c --- /dev/null +++ b/src/cc/dapps/subatomic.json @@ -0,0 +1,26 @@ +{ +"authorized": [ + {"chmex":"030754bffcf6dfcb34a20c486ff5a5be5546b9cc16fba9692165272b3f8e98c4af" }, + {"SHossain":"03c8657bd57b6ceb14514a10e99fe8a0cec5a9bc24592df7f66f050e670e4f6bac" }, + {"satinder":"03732f8ef851ff234c74d0df575c2c5b159e2bab3faca4ec52b3f217d5cda5361d" }, + {"ml777":"02453d028c74cb9551e1aaf35113383b6ecbd9f06ff23a4ab1a953429b9763e345" }, + {"tonylhub":"0218e0f435d4544404c25a7759b7f7174d821215085ef936218c5569d975af468b" }, + {"gthub":"036c7de9a5090fbad78b9eea41549ccacc07bd0e9e7f8d290c88f470f3569e1a35" }, + {"zkTrader":"026c6b0b35ec0adc2f8a5c648da1fce634f798c69d5e9fe518400447e88398b830" }, + {"nutellalicka":"03aee08860e0340f0f490a3ef3718d6676882f2d63d4f536dfebb1d348b82c79ee" }, + {"gcharang":"02d3431950c2f0f9654217b6ce3d44468d3a9ca7255741767fdeee7c5ec6b47567" }, + {"jl777":"02b27de3ee5335518b06f69f4fbabb029cfc737613b100996841d5532b324a5a61" } +], +"tokens":[ + {"RICK.demo":"2b1feef719ecb526b07416dd432bce603ac6dc8bfe794cddf105cb52f6aae3cd"} +], +"files":[ + {"filename":"komodod","prices":[{"KMD":0.1}, {"PIRATE":1}]} +], +"externalcoins":[ + { "BTC":"bitcoin-cli" }, + { "CHIPS":"chips-cli" }, + { "VRSC":"verus" } +] +} + From 19ddbe12802c690b5eada1627dd58b9707d839d4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 30 Apr 2020 06:57:21 -0400 Subject: [PATCH 103/220] Update subatomic json --- src/cc/dapps/subatomic.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cc/dapps/subatomic.json b/src/cc/dapps/subatomic.json index 7420c712c..7832fdb9e 100644 --- a/src/cc/dapps/subatomic.json +++ b/src/cc/dapps/subatomic.json @@ -15,12 +15,13 @@ {"RICK.demo":"2b1feef719ecb526b07416dd432bce603ac6dc8bfe794cddf105cb52f6aae3cd"} ], "files":[ - {"filename":"komodod","prices":[{"KMD":0.1}, {"PIRATE":1}]} + {"filename":"hushd","prices":[{"HUSH":0.1}, {"PIRATE":1}]} ], "externalcoins":[ { "BTC":"bitcoin-cli" }, + { "KMD":"komodod-cli" }, { "CHIPS":"chips-cli" }, - { "VRSC":"verus" } + { "PIRATE":"pirate-cli" } ] } From 70bd156655a3b92d9e6d3924b8227a0dd8e1d869 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 30 Apr 2020 07:04:52 -0400 Subject: [PATCH 104/220] Add dapp header to make subatomic happy --- src/cc/dapps/dappinc.h | 1599 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1599 insertions(+) create mode 100644 src/cc/dapps/dappinc.h diff --git a/src/cc/dapps/dappinc.h b/src/cc/dapps/dappinc.h new file mode 100644 index 000000000..3c71dfdec --- /dev/null +++ b/src/cc/dapps/dappinc.h @@ -0,0 +1,1599 @@ +/****************************************************************************** + * Copyright © 2014-2020 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include +#include +#include +#include +#include "cJSON.c" + +bits256 zeroid; + +int32_t unstringbits(char *buf,uint64_t bits) +{ + int32_t i; + for (i=0; i<8; i++,bits>>=8) + if ( (buf[i]= (char)(bits & 0xff)) == 0 ) + break; + buf[i] = 0; + return(i); +} + +uint64_t stringbits(char *str) +{ + uint64_t bits = 0; + if ( str == 0 ) + return(0); + int32_t i,n = (int32_t)strlen(str); + if ( n > 8 ) + n = 8; + for (i=n-1; i>=0; i--) + bits = (bits << 8) | (str[i] & 0xff); + //printf("(%s) -> %llx %llu\n",str,(long long)bits,(long long)bits); + return(bits); +} + +char hexbyte(int32_t c) +{ + c &= 0xf; + if ( c < 10 ) + return('0'+c); + else if ( c < 16 ) + return('a'+c-10); + else return(0); +} + +int32_t _unhex(char c) +{ + if ( c >= '0' && c <= '9' ) + return(c - '0'); + else if ( c >= 'a' && c <= 'f' ) + return(c - 'a' + 10); + else if ( c >= 'A' && c <= 'F' ) + return(c - 'A' + 10); + return(-1); +} + +int32_t is_hexstr(char *str,int32_t n) +{ + int32_t i; + if ( str == 0 || str[0] == 0 ) + return(0); + for (i=0; str[i]!=0; i++) + { + if ( n > 0 && i >= n ) + break; + if ( _unhex(str[i]) < 0 ) + break; + } + if ( n == 0 ) + return(i); + return(i == n); +} + +int32_t unhex(char c) +{ + int32_t hex; + if ( (hex= _unhex(c)) < 0 ) + { + //printf("unhex: illegal hexchar.(%c)\n",c); + } + return(hex); +} + +unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); } + +int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex) +{ + int32_t adjust,i = 0; + //printf("decode.(%s)\n",hex); + if ( is_hexstr(hex,n) <= 0 ) + { + memset(bytes,0,n); + return(n); + } + if ( hex[n-1] == '\n' || hex[n-1] == '\r' ) + hex[--n] = 0; + if ( hex[n-1] == '\n' || hex[n-1] == '\r' ) + hex[--n] = 0; + if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) ) + { + if ( n > 0 ) + { + bytes[0] = unhex(hex[0]); + printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex)); + } + bytes++; + hex++; + adjust = 1; + } else adjust = 0; + if ( n > 0 ) + { + for (i=0; i>4) & 0xf); + hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf); + //printf("i.%d (%02x) [%c%c]\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1]); + } + hexbytes[len*2] = 0; + //printf("len.%ld\n",len*2+1); + return((int32_t)len*2+1); +} + +long _stripwhite(char *buf,int accept) +{ + int32_t i,j,c; + if ( buf == 0 || buf[0] == 0 ) + return(0); + for (i=j=0; buf[i]!=0; i++) + { + buf[j] = c = buf[i]; + if ( c == accept || (c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != '\b') ) + j++; + } + buf[j] = 0; + return(j); +} + +char *clonestr(char *str) +{ + char *clone; + if ( str == 0 || str[0]==0) + { + printf("warning cloning nullstr.%p\n",str); + //#ifdef __APPLE__ + // while ( 1 ) sleep(1); + //#endif + str = (char *)""; + } + clone = (char *)malloc(strlen(str)+16); + strcpy(clone,str); + return(clone); +} + +int32_t safecopy(char *dest,char *src,long len) +{ + int32_t i = -1; + if ( src != 0 && dest != 0 && src != dest ) + { + if ( dest != 0 ) + memset(dest,0,len); + for (i=0; i0; i--) + str[i] = str[i-1]; + str[0] = '/'; + str[n+1] = 0; + }*/ +#endif + return(str); +#endif +} + +void *loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep) +{ + FILE *fp; + long filesize,buflen = *allocsizep; + uint8_t *buf = *bufp; + *lenp = 0; + if ( (fp= fopen(portable_path(fname),"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + filesize = ftell(fp); + if ( filesize == 0 ) + { + fclose(fp); + *lenp = 0; + //printf("loadfile null size.(%s)\n",fname); + return(0); + } + if ( filesize > buflen ) + { + *allocsizep = filesize; + *bufp = buf = (uint8_t *)realloc(buf,(long)*allocsizep+64); + } + rewind(fp); + if ( buf == 0 ) + printf("Null buf ???\n"); + else + { + if ( fread(buf,1,(long)filesize,fp) != (unsigned long)filesize ) + printf("error reading filesize.%ld\n",(long)filesize); + buf[filesize] = 0; + } + fclose(fp); + *lenp = filesize; + //printf("loaded.(%s)\n",buf); + } //else printf("OS_loadfile couldnt load.(%s)\n",fname); + return(buf); +} + +void *filestr(long *allocsizep,char *_fname) +{ + long filesize = 0; char *fname,*buf = 0; void *retptr; + *allocsizep = 0; + fname = malloc(strlen(_fname)+1); + strcpy(fname,_fname); + retptr = loadfile(fname,(uint8_t **)&buf,&filesize,allocsizep); + free(fname); + return(retptr); +} + +char *send_curl(char *url,char *fname) +{ + long fsize; char curlstr[1024]; + sprintf(curlstr,"curl --url \"%s\" > %s",url,fname); + system(curlstr); + return(filestr(&fsize,fname)); +} + +cJSON *get_urljson(char *url,char *fname) +{ + char *jsonstr; cJSON *json = 0; + if ( (jsonstr= send_curl(url,fname)) != 0 ) + { + //printf("(%s) -> (%s)\n",url,jsonstr); + json = cJSON_Parse(jsonstr); + free(jsonstr); + } + return(json); +} + +////////////////////////////////////////////// +// start of dapp +////////////////////////////////////////////// +int md_unlink(char *file) +{ +#ifdef _WIN32 + _chmod(file, 0600); + return( _unlink(file) ); +#else + return(unlink(file)); +#endif +} + +char *REFCOIN_CLI,DPOW_pubkeystr[67],DPOW_secpkeystr[67],DPOW_handle[67],DPOW_recvaddr[64],DPOW_recvZaddr[128]; + +cJSON *get_komodocli(char *refcoin,char **retstrp,char *acname,char *method,char *arg0,char *arg1,char *arg2,char *arg3,char *arg4,char *arg5,char *arg6) +{ + long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[32768]; + sprintf(fname,"/tmp/notarizer_%s_%d",method,(rand() >> 17) % 10000); + //if ( (acname == 0 || acname[0] == 0) && strcmp(refcoin,"KMD") != 0 ) + // acname = refcoin; + if ( acname[0] != 0 ) + { + if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 && strcmp(refcoin,acname) != 0 ) + printf("unexpected: refcoin.(%s) acname.(%s)\n",refcoin,acname); + sprintf(cmdstr,"komodo-cli -ac_name=%s %s %s %s %s %s %s %s %s > %s\n",acname,method,arg0,arg1,arg2,arg3,arg4,arg5,arg6,fname); + } + else if ( strcmp(refcoin,"KMD") == 0 ) + sprintf(cmdstr,"komodo-cli %s %s %s %s %s %s %s %s > %s\n",method,arg0,arg1,arg2,arg3,arg4,arg5,arg6,fname); + else if ( REFCOIN_CLI != 0 && REFCOIN_CLI[0] != 0 ) + { + sprintf(cmdstr,"%s %s %s %s %s %s %s %s %s > %s\n",REFCOIN_CLI,method,arg0,arg1,arg2,arg3,arg4,arg5,arg6,fname); + //printf("ref.(%s) REFCOIN_CLI (%s)\n",refcoin,cmdstr); + } +//fprintf(stderr,"system(%s)\n",cmdstr); + system(cmdstr); + *retstrp = 0; + if ( (jsonstr= filestr(&fsize,fname)) != 0 ) + { + jsonstr[strlen(jsonstr)-1]='\0'; + //fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr); + if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 ) + *retstrp = jsonstr; + else free(jsonstr); + md_unlink(fname); + } //else fprintf(stderr,"system(%s) -> NULL\n",cmdstr); + return(retjson); +} + +cJSON *subatomic_cli(char *clistr,char **retstrp,char *method,char *arg0,char *arg1,char *arg2,char *arg3,char *arg4,char *arg5,char *arg6) +{ + long fsize; cJSON *retjson = 0; char cmdstr[32768],*jsonstr,fname[32768]; + sprintf(fname,"/tmp/subatomic_%s_%d",method,(rand() >> 17) % 10000); + sprintf(cmdstr,"%s %s %s %s %s %s %s %s %s > %s\n",clistr,method,arg0,arg1,arg2,arg3,arg4,arg5,arg6,fname); +//fprintf(stderr,"system(%s)\n",cmdstr); + system(cmdstr); + *retstrp = 0; + if ( (jsonstr= filestr(&fsize,fname)) != 0 ) + { + jsonstr[strlen(jsonstr)-1]='\0'; + //fprintf(stderr,"%s -> jsonstr.(%s)\n",cmdstr,jsonstr); + if ( (jsonstr[0] != '{' && jsonstr[0] != '[') || (retjson= cJSON_Parse(jsonstr)) == 0 ) + *retstrp = jsonstr; + else free(jsonstr); + md_unlink(fname); + } //else fprintf(stderr,"system(%s) -> NULL\n",cmdstr); + return(retjson); +} + +bits256 komodobroadcast(char *refcoin,char *acname,cJSON *hexjson) +{ + char *hexstr,*retstr,str[65]; cJSON *retjson; bits256 txid; + memset(txid.bytes,0,sizeof(txid)); + if ( (hexstr= jstr(hexjson,"hex")) != 0 ) + { + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendrawtransaction",hexstr,"","","","","","")) != 0 ) + { + //fprintf(stderr,"broadcast.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + if ( strlen(retstr) >= 64 ) + { + retstr[64] = 0; + decode_hex(txid.bytes,32,retstr); + } + fprintf(stderr,"broadcast %s txid.(%s)\n",strlen(acname)>0?acname:refcoin,bits256_str(str,txid)); + free(retstr); + } + } + return(txid); +} + +bits256 sendtoaddress(char *refcoin,char *acname,char *destaddr,int64_t satoshis,char *oprethexstr) +{ + char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid; + memset(txid.bytes,0,sizeof(txid)); + sprintf(numstr,"%.8f",(double)satoshis/SATOSHIDEN); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"sendtoaddress",destaddr,numstr,"false","","",oprethexstr,"")) != 0 ) + { + fprintf(stderr,"unexpected sendrawtransaction json.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + if ( strlen(retstr) >= 64 ) + { + retstr[64] = 0; + decode_hex(txid.bytes,32,retstr); + } + fprintf(stderr,"sendtoaddress %s %.8f txid.(%s)\n",destaddr,(double)satoshis/SATOSHIDEN,bits256_str(str,txid)); + free(retstr); + } + return(txid); +} + +bits256 tokentransfer(char *refcoin,char *acname,char *tokenid,char *destpub,int64_t units) +{ + char numstr[32],*retstr,str[65]; cJSON *retjson; bits256 txid; + memset(txid.bytes,0,sizeof(txid)); + sprintf(numstr,"%llu",(long long)units); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"tokentransfer",tokenid,destpub,numstr,"","","","")) != 0 ) + { + txid = komodobroadcast(refcoin,acname,retjson); + fprintf(stderr,"tokentransfer returned (%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"tokentransfer.(%s) error.(%s)\n",acname,retstr); + free(retstr); + } + return(txid); +} + +char *get_tokenaddress(char *refcoin,char *acname,char *tokenaddr) +{ + char *retstr,*str; cJSON *retjson; + tokenaddr[0] = 0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"tokenaddress","","","","","","","")) != 0 ) + { + if ( (str= jstr(retjson,"myCCAddress(Tokens)")) != 0 ) + { + strcpy(tokenaddr,str); + fprintf(stderr,"tokenaddress returned (%s)\n",tokenaddr); + free_json(retjson); + return(tokenaddr); + } + free_json(retjson); + } + else if ( retstr != 0 ) + { + //fprintf(stderr,"tokentransfer.(%s) error.(%s)\n",acname,retstr); + free(retstr); + } + return(0); +} + +int64_t get_tokenbalance(char *refcoin,char *acname,char *tokenid) +{ + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"tokenbalance",tokenid,"","","","","","")) != 0 ) + { + amount = j64bits(retjson,"balance"); + fprintf(stderr,"tokenbalance %llu\n",(long long)amount); + free_json(retjson); + } + else if ( retstr != 0 ) + { + //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); + free(retstr); + } + return (amount); +} + +cJSON *get_decodescript(char *refcoin,char *acname,char *script) +{ + cJSON *retjson; char *retstr; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"decodescript",script,"","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_decodescript.(%s) error.(%s)\n",acname,retstr); + free(retstr); + } + return(0); +} + +char *get_createmultisig2(char *refcoin,char *acname,char *msigaddr,char *redeemscript,char *pubkeyA,char *pubkeyB) +{ + //char para 2 '["02c3af47b51a506b08b4ededb156cb4c3f9db9e0ac7ad27b8623c08a056fdcc220", "038e61fbface549a850862f12ed99b7cbeef5c2bd2d8f1daddb34809416f0259e1"]' + cJSON *retjson; char *retstr,*str,params[256]; int32_t height=0; + msigaddr[0] = 0; + redeemscript[0] = 0; + sprintf(params,"'[\"%s\", \"%s\"]'",pubkeyA,pubkeyB); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"createmultisig","2",params,"","","","","")) != 0 ) + { + if ( (str= jstr(retjson,"address")) != 0 ) + strcpy(msigaddr,str); + if ( (str= jstr(retjson,"redeemScript")) != 0 ) + strcpy(redeemscript,str); + free_json(retjson); + if ( msigaddr[0] != 0 && redeemscript[0] != 0 ) + return(msigaddr); + else return(0); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"%s get_createmultisig2.(%s) error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +int32_t get_coinheight(char *refcoin,char *acname,bits256 *blockhashp) +{ + cJSON *retjson; char *retstr; int32_t height=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockchaininfo","","","","","","","")) != 0 ) + { + height = jint(retjson,"blocks"); + *blockhashp = jbits256(retjson,"bestblockhash"); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"%s get_coinheight.(%s) error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(height); +} + +bits256 get_coinblockhash(char *refcoin,char *acname,int32_t height) +{ + cJSON *retjson; char *retstr,heightstr[32]; bits256 hash; + memset(hash.bytes,0,sizeof(hash)); + sprintf(heightstr,"%d",height); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockhash",heightstr,"","","","","","")) != 0 ) + { + fprintf(stderr,"unexpected blockhash json.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + if ( strlen(retstr) >= 64 ) + { + retstr[64] = 0; + decode_hex(hash.bytes,32,retstr); + } + free(retstr); + } + return(hash); +} + +bits256 get_coinmerkleroot(char *refcoin,char *acname,bits256 blockhash,uint32_t *blocktimep) +{ + cJSON *retjson; char *retstr,str[65]; bits256 merkleroot; + memset(merkleroot.bytes,0,sizeof(merkleroot)); + *blocktimep = 0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getblockheader",bits256_str(str,blockhash),"","","","","","")) != 0 ) + { + merkleroot = jbits256(retjson,"merkleroot"); + *blocktimep = juint(retjson,"time"); + //fprintf(stderr,"got merkleroot.(%s)\n",bits256_str(str,merkleroot)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"%s %s get_coinmerkleroot error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(merkleroot); +} + +uint32_t get_heighttime(char *refcoin,char *acname,int32_t height) +{ + bits256 blockhash; uint32_t blocktime; + blockhash = get_coinblockhash(refcoin,acname,height); + get_coinmerkleroot(refcoin,acname,blockhash,&blocktime); + return(blocktime); +} + +int32_t get_coinheader(char *refcoin,char *acname,bits256 *blockhashp,bits256 *merklerootp,int32_t prevheight) +{ + int32_t height = 0; char str[65]; bits256 bhash; uint32_t blocktime; + if ( prevheight == 0 ) + height = get_coinheight(refcoin,acname,&bhash) - 20; + else height = prevheight + 1; + if ( height > 0 ) + { + *blockhashp = get_coinblockhash(refcoin,acname,height); + if ( bits256_nonz(*blockhashp) != 0 ) + { + *merklerootp = get_coinmerkleroot(refcoin,acname,*blockhashp,&blocktime); + if ( bits256_nonz(*merklerootp) != 0 ) + return(height); + } + } + memset(blockhashp,0,sizeof(*blockhashp)); + memset(merklerootp,0,sizeof(*merklerootp)); + return(0); +} + +cJSON *get_rawmempool(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawmempool","","","","","","","")) != 0 ) + { + //printf("mempool.(%s)\n",jprint(retjson,0)); + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_rawmempool.(%s) error.(%s)\n",acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *get_addressutxos(char *refcoin,char *acname,char *coinaddr) +{ + cJSON *retjson; char *retstr,jsonbuf[256]; + if ( refcoin[0] != 0 && strcmp(refcoin,"KMD") != 0 ) + printf("warning: assumes %s has addressindex enabled\n",refcoin); + sprintf(jsonbuf,"{\\\"addresses\\\":[\\\"%s\\\"]}",coinaddr); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getaddressutxos",jsonbuf,"","","","","","")) != 0 ) + { + //printf("addressutxos.(%s)\n",jprint(retjson,0)); + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_addressutxos.(%s) error.(%s)\n",acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *get_rawtransaction(char *refcoin,char *acname,bits256 txid) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getrawtransaction",bits256_str(str,txid),"1","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_rawtransaction.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *get_z_viewtransaction(char *refcoin,char *acname,bits256 txid) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_viewtransaction",bits256_str(str,txid),"","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_z_viewtransaction.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *get_listunspent(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"listunspent","","","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_listunspent.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *get_getinfo(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getinfo","","","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"get_getinfo.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *z_listunspent(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listunspent","","","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_listunspent.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *z_listoperationids(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr,str[65]; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_listoperationids","","","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_listoperationids.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *z_getoperationstatus(char *refcoin,char *acname,char *opid) +{ + cJSON *retjson; char *retstr,str[65],params[512]; + sprintf(params,"'[\"%s\"]'",opid); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationstatus",params,"","","","","","")) != 0 ) + { + //printf("got status (%s)\n",jprint(retjson,0)); + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_getoperationstatus.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +cJSON *z_getoperationresult(char *refcoin,char *acname,char *opid) +{ + cJSON *retjson; char *retstr,str[65],params[512]; + sprintf(params,"'[\"%s\"]'",opid); + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getoperationresult",params,"","","","","","")) != 0 ) + { + return(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_getoperationresult.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return(0); +} + +int32_t validateaddress(char *refcoin,char *acname,char *depositaddr, char* compare) +{ + cJSON *retjson; char *retstr; int32_t res=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"validateaddress",depositaddr,"","","","","","")) != 0 ) + { + if (is_cJSON_True(jobj(retjson,compare)) != 0 ) res=1; + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return (res); +} + +int32_t z_validateaddress(char *refcoin,char *acname,char *depositaddr, char *compare) +{ + cJSON *retjson; char *retstr; int32_t res=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_validateaddress",depositaddr,"","","","","","")) != 0 ) + { + if (is_cJSON_True(jobj(retjson,compare)) != 0 ) + res=1; + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_validateaddress.(%s) %s error.(%s)\n",refcoin,acname,retstr); + free(retstr); + } + return (res); +} + +int64_t get_getbalance(char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getbalance","","","","","","","")) != 0 ) + { + fprintf(stderr,"get_getbalance.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + } + else if ( retstr != 0 ) + { + amount = atof(retstr) * SATOSHIDEN; + sprintf(cmpstr,"%.8f",dstr(amount)); + if ( strcmp(retstr,cmpstr) != 0 ) + amount++; + //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); + free(retstr); + } + return (amount); +} + +int64_t z_getbalance(char *refcoin,char *acname,char *coinaddr) +{ + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getbalance",coinaddr,"","","","","","")) != 0 ) + { + fprintf(stderr,"z_getbalance.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + } + else if ( retstr != 0 ) + { + amount = atof(retstr) * SATOSHIDEN; + sprintf(cmpstr,"%.8f",dstr(amount)); + if ( strcmp(retstr,cmpstr) != 0 ) + amount++; + //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); + free(retstr); + } + return (amount); +} + +int32_t z_exportkey(char *privkey,char *refcoin,char *acname,char *zaddr) +{ + cJSON *retjson; char *retstr,cmpstr[64]; int64_t amount=0; + privkey[0] = 0; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_exportkey",zaddr,"","","","","","")) != 0 ) + { + fprintf(stderr,"z_exportkey.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + return(-1); + } + else if ( retstr != 0 ) + { + //printf("retstr %s -> %.8f\n",retstr,dstr(amount)); + strcpy(privkey,retstr); + free(retstr); + return(0); + } + return(-1); +} + +int32_t getnewaddress(char *coinaddr,char *refcoin,char *acname) +{ + cJSON *retjson; char *retstr; int64_t amount=0; int32_t retval = -1; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"getnewaddress","","","","","","","")) != 0 ) + { + fprintf(stderr,"getnewaddress.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + } + else if ( retstr != 0 ) + { + strcpy(coinaddr,retstr); + free(retstr); + retval = 0; + } + return(retval); +} + +int32_t z_getnewaddress(char *coinaddr,char *refcoin,char *acname,char *typestr) +{ + cJSON *retjson; char *retstr; int64_t amount=0; int32_t retval = -1; + if ( (retjson= get_komodocli(refcoin,&retstr,acname,"z_getnewaddress",typestr,"","","","","","")) != 0 ) + { + fprintf(stderr,"z_getnewaddress.(%s) %s returned json!\n",refcoin,acname); + free_json(retjson); + } + else if ( retstr != 0 ) + { + strcpy(coinaddr,retstr); + free(retstr); + retval = 0; + } + return(retval); +} + +int64_t find_onetime_amount(char *coinstr,char *coinaddr) +{ + cJSON *array,*item; int32_t i,n; char *addr; int64_t amount = 0; + coinaddr[0] = 0; + if ( (array= get_listunspent(coinstr,"")) != 0 ) + { + //printf("got listunspent.(%s)\n",jprint(array,0)); + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i %s\n",coinstr,acname,srcaddr,params); + if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_sendmany",addr,params,"","","","","")) != 0 ) + { + printf("unexpected json z_sendmany.(%s)\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_sendmany.(%s) -> opid.(%s)\n",coinstr,retstr); + strcpy(opidstr,retstr); + free(retstr); + retval = 0; + } + return(retval); +} + +int32_t z_mergetoaddress(char *opidstr,char *coinstr,char *acname,char *destaddr) +{ + cJSON *retjson; char *retstr,addr[128],*opstr; int32_t retval = -1; + sprintf(addr,"[\\\"ANY_SPROUT\\\"]"); + if ( (retjson= get_komodocli(coinstr,&retstr,acname,"z_mergetoaddress",addr,destaddr,"","","","","")) != 0 ) + { + if ( (opstr= jstr(retjson,"opid")) != 0 ) + strcpy(opidstr,opstr); + retval = jint(retjson,"remainingNotes"); + fprintf(stderr,"%s\n",jprint(retjson,0)); + free_json(retjson); + } + else if ( retstr != 0 ) + { + fprintf(stderr,"z_mergetoaddress.(%s) -> opid.(%s)\n",coinstr,retstr); + strcpy(opidstr,retstr); + free(retstr); + } + return(retval); +} + +int32_t empty_mempool(char *coinstr,char *acname) +{ + cJSON *array; int32_t n; + if ( (array= get_rawmempool(coinstr,acname)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + return(0); + free_json(array); + return(1); + } + return(-1); +} + +cJSON *getinputarray(int64_t *totalp,cJSON *unspents,int64_t required) +{ + cJSON *vin,*item,*vins = cJSON_CreateArray(); int32_t i,n,v; int64_t satoshis; bits256 txid; + *totalp = 0; + if ( (n= cJSON_GetArraySize(unspents)) > 0 ) + { + for (i=0; i= required ) + break; + } + } + } + return(vins); +} + +int32_t tx_has_voutaddress(char *refcoin,char *acname,bits256 txid,char *coinaddr) +{ + cJSON *txobj,*vouts,*vout,*vins,*vin,*sobj,*addresses; char *addr,str[65]; int32_t i,j,n,numarray,retval = 0, hasvout=0; + if ( (txobj= get_rawtransaction(refcoin,acname,txid)) != 0 ) + { + if ( (vouts= jarray(&numarray,txobj,"vout")) != 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i 0 ) + { + for (j=0; j 0 && strcmp(vinaddr,cmpaddr) == 0 ) + return(0); + printf("mismatched vinaddr.(%s) vs %s\n",vinaddr,cmpaddr); + } + } + return(-1); +} + +int32_t txid_in_vins(char *refcoin,bits256 txid,bits256 cmptxid) +{ + cJSON *txjson,*vins,*vin; int32_t numvins,v,vinvout; bits256 vintxid; char str[65]; + if ( (txjson= get_rawtransaction(refcoin,"",txid)) != 0 ) + { + if ( (vins= jarray(&numvins,txjson,"vin")) != 0 ) + { + for (v=0; v n.%d retval.%d\n",tagA,tagB,pubkeystr,n,retval); + } + free_json(retjson); + } + return(retval); +} + +int32_t dpow_hasmessage(char *payload,char *tagA,char *tagB,char *pubkeystr) +{ + cJSON *retjson,*item,*array; char *retstr,*pstr; int32_t i,n,retval = 0; + if ( (retjson= get_komodocli((char *)"",&retstr,DEXP2P_CHAIN,"DEX_list","0","0",tagA,tagB,pubkeystr,"","")) != 0 ) + { + if ( (array= jarray(&n,retjson,"matches")) != 0 ) + { + for (i=0; i 0 ) + { + ptrs = calloc(n,sizeof(*ptrs)); + for (i=0; ishorthash = juint(item,"id"); + ptrs[m]->jsonstr = ptr; + strcpy(ptrs[m]->senderpub,senderpub); + m++; + } + } + } + *nump = m; + } + free_json(retjson); + } + return(ptrs); +} + + From 888efff4d1935266416288a50b1630a481966166 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 30 Apr 2020 07:06:47 -0400 Subject: [PATCH 105/220] Add subatomic to dapp makefile --- src/cc/dapps/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cc/dapps/Makefile b/src/cc/dapps/Makefile index 6e7874788..1fea27084 100644 --- a/src/cc/dapps/Makefile +++ b/src/cc/dapps/Makefile @@ -1,6 +1,10 @@ +# Copyright 2020 The Hush Developers # just type make to compile all dapps all: zmigrate oraclefeed +subatomic: + $(CC) subatomic.c -o subatomic -lm + zmigrate: $(CC) zmigrate.c -o zmigrate -lm @@ -9,3 +13,4 @@ oraclefeed: clean: rm zmigrate oraclefeed + From 8a4e72fca2e0b41dc9f6875a40c2ceba048029eb Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 8 May 2020 08:57:34 -0400 Subject: [PATCH 106/220] Remove some sprout code from BuildWitnessCache --- src/wallet/wallet.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 53b3af6a6..546d9a547 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1288,10 +1288,6 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) LogPrintf("Building Witnesses for block %i %.4f complete\n", pblockindex->GetHeight(), pblockindex->GetHeight() / double(height)); } - SproutMerkleTree sproutTree; - sproutRoot = pblockindex->pprev->hashFinalSproutRoot; - pcoinsTip->GetSproutAnchorAt(sproutRoot, sproutTree); - SaplingMerkleTree saplingTree; saplingRoot = pblockindex->pprev->hashFinalSaplingRoot; pcoinsTip->GetSaplingAnchorAt(saplingRoot, saplingTree); From dd5d932f8711c17e66fde407c1cdf2d0ae7aedf1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 11 May 2020 06:34:48 -0400 Subject: [PATCH 107/220] Only print these when -zdebug is turned on --- src/wallet/rpcwallet.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5afd0c4e8..37f67042b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4388,7 +4388,9 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp, const CPubKey& my // Fetch the note that is being spent auto res = pwalletMain->mapSaplingNullifiersToNotes.find(spend.nullifier); if (res == pwalletMain->mapSaplingNullifiersToNotes.end()) { - fprintf(stderr,"Could not find spending note %s", uint256_str(str, spend.nullifier)); + if(fZdebug) { + fprintf(stderr,"Could not find spending note %s\n", uint256_str(str, spend.nullifier)); + } continue; } auto op = res->second; @@ -4442,8 +4444,10 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp, const CPubKey& my pa = recovered->second; isOutgoing = true; } else { - // Unreadable - fprintf(stderr,"Could not recover Sapling note!"); + // Unreadable or unconfirmed? + if(fZdebug) { + fprintf(stderr,"Could not recover Sapling note!\n"); + } continue; } } From 095157d2d97de6da7de24ab168d36b383a6dbda3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 11 May 2020 06:42:01 -0400 Subject: [PATCH 108/220] Remove sprout junk --- src/wallet/wallet.cpp | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 546d9a547..8d56fdfae 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1298,7 +1298,7 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) for (std::pair& wtxItem : mapWallet) { - if (wtxItem.second.mapSproutNoteData.empty() && wtxItem.second.mapSaplingNoteData.empty()) + if (wtxItem.second.mapSaplingNoteData.empty()) continue; if (wtxItem.second.GetDepthInMainChain() > 0) { @@ -3062,38 +3062,11 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) { continue; } - //Check for unspent inputs or spend less than N Blocks ago. (Sprout) - for (auto & pair : pwtx->mapSproutNoteData) { - SproutNoteData nd = pair.second; - if (!nd.nullifier || pwalletMain->GetSproutSpendDepth(*nd.nullifier) <= fDeleteTransactionsAfterNBlocks) { - LogPrint("deletetx","DeleteTx - Unspent sprout input tx %s\n", pwtx->GetHash().ToString()); - deleteTx = false; - continue; - } - } - if (!deleteTx) { txSaveCount++; continue; } - //Check for outputs that no longer have parents in the wallet. Exclude parents that are in the same transaction. (Sprout) - for (int i = 0; i < pwtx->vjoinsplit.size(); i++) { - const JSDescription& jsdesc = pwtx->vjoinsplit[i]; - for (const uint256 &nullifier : jsdesc.nullifiers) { - // JSOutPoint op = pwalletMain->mapSproutNullifiersToNotes[nullifier]; - if (pwalletMain->IsSproutNullifierFromMe(nullifier)) { - const uint256& parentHash = pwalletMain->mapSproutNullifiersToNotes[nullifier].hash; - const CWalletTx* parent = pwalletMain->GetWalletTx(parentHash); - if (parent != NULL && parentHash != wtxid) { - LogPrint("deletetx","DeleteTx - Parent of sprout tx %s found\n", pwtx->GetHash().ToString()); - deleteTx = false; - continue; - } - } - } - } - if (!deleteTx) { txSaveCount++; continue; From 2324e8ca4b5e6dbd34a51e9e415493742e285464 Mon Sep 17 00:00:00 2001 From: ssadler Date: Mon, 27 Apr 2020 16:10:30 -0300 Subject: [PATCH 109/220] fix fingerprint encoding --- src/cryptoconditions/src/cryptoconditions.c | 20 +++++++++++------- src/cryptoconditions/src/internal.h | 2 +- .../tests/test_failure_modes.py | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/cryptoconditions/src/cryptoconditions.c b/src/cryptoconditions/src/cryptoconditions.c index 74949affc..f7acde1aa 100644 --- a/src/cryptoconditions/src/cryptoconditions.c +++ b/src/cryptoconditions/src/cryptoconditions.c @@ -117,14 +117,15 @@ uint32_t fromAsnSubtypes(const ConditionTypes_t types) { size_t cc_conditionBinary(const CC *cond, unsigned char *buf) { Condition_t *asn = calloc(1, sizeof(Condition_t)); - asnCondition(cond, asn); + bool r = asnCondition(cond, asn); + size_t out = 0; + if (!r) goto end; asn_enc_rval_t rc = der_encode_to_buffer(&asn_DEF_Condition, asn, buf, 1000); - if (rc.encoded == -1) { - fprintf(stderr, "CONDITION NOT ENCODED\n"); - return 0; - } + if (rc.encoded == -1) goto end; + out = rc.encoded; +end: ASN_STRUCT_FREE(asn_DEF_Condition, asn); - return rc.encoded; + return out; } @@ -140,17 +141,22 @@ size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t length) { } -void asnCondition(const CC *cond, Condition_t *asn) { +bool asnCondition(const CC *cond, Condition_t *asn) { asn->present = cc_isAnon(cond) ? cond->conditionType->asnType : cond->type->asnType; // This may look a little weird - we dont have a reference here to the correct // union choice for the condition type, so we just assign everything to the threshold // type. This works out nicely since the union choices have the same binary interface. + CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256; choice->cost = cc_getCost(cond); choice->fingerprint.buf = cond->type->fingerprint(cond); + if (choice->fingerprint.buf == 0) { + return 0; + } choice->fingerprint.size = 32; choice->subtypes = asnSubtypes(cond->type->getSubtypes(cond)); + return 1; } diff --git a/src/cryptoconditions/src/internal.h b/src/cryptoconditions/src/internal.h index 790e28962..e2525cbe4 100644 --- a/src/cryptoconditions/src/internal.h +++ b/src/cryptoconditions/src/internal.h @@ -65,7 +65,7 @@ extern int CCTypeRegistryLength; */ uint32_t fromAsnSubtypes(ConditionTypes_t types); CC *mkAnon(const Condition_t *asnCond); -void asnCondition(const CC *cond, Condition_t *asn); +bool asnCondition(const CC *cond, Condition_t *asn); Condition_t *asnConditionNew(const CC *cond); Fulfillment_t *asnFulfillmentNew(const CC *cond); struct CC *fulfillmentToCC(Fulfillment_t *ffill); diff --git a/src/cryptoconditions/tests/test_failure_modes.py b/src/cryptoconditions/tests/test_failure_modes.py index 59b0b3f24..435e20c88 100644 --- a/src/cryptoconditions/tests/test_failure_modes.py +++ b/src/cryptoconditions/tests/test_failure_modes.py @@ -82,4 +82,25 @@ def test_malleability_checked(): assert not cc_rfb(b'\xa2\x13\xa0\x0f\xa0\x06\x80\x04abcd\xa0\x05\x80\x03abc\xa1\x00') +def test_large_threshold(): + conds = [{ + 'type': "secp256k1-sha-256", + "publicKey": "02D5D969305535AC29A77079C11D4F0DD40661CF96E04E974A5E8D7E374EE225AA" + }] + + for i in range(250): + conds.append({ + "type": "eval-sha-256", + "code": "VEVTVAE" + }) + + r = jsonRPC("encodeCondition", { + "type": "threshold-sha-256", + "subfulfillments": conds, + "threshold": 251 + }) + assert 'error' not in r, r + + + so.cc_conditionUri.restype = ctypes.c_char_p From eabcce62f7ddc89d4a6b322e89c8bf3e831e25e6 Mon Sep 17 00:00:00 2001 From: ssadler Date: Thu, 7 May 2020 22:32:59 -0300 Subject: [PATCH 110/220] return void where possible and pass references to indicate that a NULL result is impossible --- src/cryptoconditions/src/anon.c | 5 +---- src/cryptoconditions/src/cryptoconditions.c | 16 ++++++---------- src/cryptoconditions/src/ed25519.c | 5 ++--- src/cryptoconditions/src/eval.c | 9 +++------ .../src/include/secp256k1/src/ecmult_const.h | 2 +- src/cryptoconditions/src/internal.h | 6 +++--- src/cryptoconditions/src/prefix.c | 7 +++---- src/cryptoconditions/src/preimage.c | 7 ++----- src/cryptoconditions/src/secp256k1.c | 5 ++--- src/cryptoconditions/src/threshold.c | 6 ++---- src/cryptoconditions/src/utils.c | 6 ++---- 11 files changed, 27 insertions(+), 47 deletions(-) diff --git a/src/cryptoconditions/src/anon.c b/src/cryptoconditions/src/anon.c index 55d7a3b7f..6a4de4b0b 100644 --- a/src/cryptoconditions/src/anon.c +++ b/src/cryptoconditions/src/anon.c @@ -53,11 +53,8 @@ static void anonToJSON(const CC *cond, cJSON *params) { } -static unsigned char *anonFingerprint(const CC *cond) { - unsigned char *out = calloc(1, 32); - //fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint); +static void anonFingerprint(const CC *cond, uint8_t *out) { memcpy(out, cond->fingerprint, 32); - return out; } diff --git a/src/cryptoconditions/src/cryptoconditions.c b/src/cryptoconditions/src/cryptoconditions.c index f7acde1aa..303b9aa41 100644 --- a/src/cryptoconditions/src/cryptoconditions.c +++ b/src/cryptoconditions/src/cryptoconditions.c @@ -65,8 +65,8 @@ void appendUriSubtypes(uint32_t mask, unsigned char *buf) { char *cc_conditionUri(const CC *cond) { - unsigned char *fp = cond->type->fingerprint(cond); - if (!fp) return NULL; + unsigned char *fp = calloc(1, 32); + cond->type->fingerprint(cond, fp); unsigned char *encoded = base64_encode(fp, 32); @@ -117,9 +117,8 @@ uint32_t fromAsnSubtypes(const ConditionTypes_t types) { size_t cc_conditionBinary(const CC *cond, unsigned char *buf) { Condition_t *asn = calloc(1, sizeof(Condition_t)); - bool r = asnCondition(cond, asn); + asnCondition(cond, asn); size_t out = 0; - if (!r) goto end; asn_enc_rval_t rc = der_encode_to_buffer(&asn_DEF_Condition, asn, buf, 1000); if (rc.encoded == -1) goto end; out = rc.encoded; @@ -141,7 +140,7 @@ size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t length) { } -bool asnCondition(const CC *cond, Condition_t *asn) { +void asnCondition(const CC *cond, Condition_t *asn) { asn->present = cc_isAnon(cond) ? cond->conditionType->asnType : cond->type->asnType; // This may look a little weird - we dont have a reference here to the correct @@ -150,13 +149,10 @@ bool asnCondition(const CC *cond, Condition_t *asn) { CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256; choice->cost = cc_getCost(cond); - choice->fingerprint.buf = cond->type->fingerprint(cond); - if (choice->fingerprint.buf == 0) { - return 0; - } choice->fingerprint.size = 32; + choice->fingerprint.buf = calloc(1, 32); + cond->type->fingerprint(cond, choice->fingerprint.buf); choice->subtypes = asnSubtypes(cond->type->getSubtypes(cond)); - return 1; } diff --git a/src/cryptoconditions/src/ed25519.c b/src/cryptoconditions/src/ed25519.c index 8d73d3cf1..e4d090d1e 100644 --- a/src/cryptoconditions/src/ed25519.c +++ b/src/cryptoconditions/src/ed25519.c @@ -25,11 +25,10 @@ struct CCType CC_Ed25519Type; -static unsigned char *ed25519Fingerprint(const CC *cond) { +static void ed25519Fingerprint(const CC *cond, uint8_t *out) { Ed25519FingerprintContents_t *fp = calloc(1, sizeof(Ed25519FingerprintContents_t)); - //fprintf(stderr,"ed25519 fingerprint %p %p\n",fp,cond->publicKey); OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, 32); - return hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp); + hashFingerprintContents(&asn_DEF_Ed25519FingerprintContents, fp, out); } diff --git a/src/cryptoconditions/src/eval.c b/src/cryptoconditions/src/eval.c index 99ff1ebf5..a18d51202 100644 --- a/src/cryptoconditions/src/eval.c +++ b/src/cryptoconditions/src/eval.c @@ -25,11 +25,8 @@ struct CCType CC_EvalType; -static unsigned char *evalFingerprint(const CC *cond) { - unsigned char *hash = calloc(1, 32); - //fprintf(stderr,"evalfingerprint %p %p\n",hash,cond->code); - sha256(cond->code, cond->codeLength, hash); - return hash; +static void evalFingerprint(const CC *cond, uint8_t *out) { + sha256(cond->code, cond->codeLength, out); } @@ -105,7 +102,7 @@ static uint32_t evalSubtypes(const CC *cond) { */ int jsonVerifyEval(CC *cond, void *context) { if (cond->codeLength == 5 && 0 == memcmp(cond->code, "TEST", 4)) { - return cond->code[5]; + return cond->code[4]; } fprintf(stderr, "Cannot verify eval; user function unknown\n"); return 0; diff --git a/src/cryptoconditions/src/include/secp256k1/src/ecmult_const.h b/src/cryptoconditions/src/include/secp256k1/src/ecmult_const.h index bdb9ae43a..5a36ba40b 100644 --- a/src/cryptoconditions/src/include/secp256k1/src/ecmult_const.h +++ b/src/cryptoconditions/src/include/secp256k1/src/ecmult_const.h @@ -36,4 +36,4 @@ static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, cons #endif - +#endif diff --git a/src/cryptoconditions/src/internal.h b/src/cryptoconditions/src/internal.h index e2525cbe4..7cfcaa225 100644 --- a/src/cryptoconditions/src/internal.h +++ b/src/cryptoconditions/src/internal.h @@ -41,7 +41,7 @@ typedef struct CCType { char name[100]; Condition_PR asnType; int (*visitChildren)(CC *cond, CCVisitor visitor); - unsigned char *(*fingerprint)(const CC *cond); + void (*fingerprint)(const CC *cond, uint8_t *fp); unsigned long (*getCost)(const CC *cond); uint32_t (*getSubtypes)(const CC *cond); CC *(*fromJSON)(const cJSON *params, char *err); @@ -65,7 +65,7 @@ extern int CCTypeRegistryLength; */ uint32_t fromAsnSubtypes(ConditionTypes_t types); CC *mkAnon(const Condition_t *asnCond); -bool asnCondition(const CC *cond, Condition_t *asn); +void asnCondition(const CC *cond, Condition_t *asn); Condition_t *asnConditionNew(const CC *cond); Fulfillment_t *asnFulfillmentNew(const CC *cond); struct CC *fulfillmentToCC(Fulfillment_t *ffill); @@ -77,7 +77,7 @@ struct CCType *getTypeByAsnEnum(Condition_PR present); */ unsigned char *base64_encode(const unsigned char *data, size_t input_length); unsigned char *base64_decode(const unsigned char *data_, size_t *output_length); -unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp); +void hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp, uint8_t* out); void dumpStr(unsigned char *str, size_t len); int checkString(const cJSON *value, char *key, char *err); int checkDecodeBase64(const cJSON *value, char *key, char *err, unsigned char **data, size_t *size); diff --git a/src/cryptoconditions/src/prefix.c b/src/cryptoconditions/src/prefix.c index 45c6d8033..67dc6f644 100644 --- a/src/cryptoconditions/src/prefix.c +++ b/src/cryptoconditions/src/prefix.c @@ -37,13 +37,12 @@ static int prefixVisitChildren(CC *cond, CCVisitor visitor) { } -static unsigned char *prefixFingerprint(const CC *cond) { +static void prefixFingerprint(const CC *cond, uint8_t *out) { PrefixFingerprintContents_t *fp = calloc(1, sizeof(PrefixFingerprintContents_t)); - //fprintf(stderr,"prefixfinger %p %p\n",fp,cond->prefix); - asnCondition(cond->subcondition, &fp->subcondition); // TODO: check asnCondition for safety + asnCondition(cond->subcondition, &fp->subcondition); fp->maxMessageLength = cond->maxMessageLength; OCTET_STRING_fromBuf(&fp->prefix, cond->prefix, cond->prefixLength); - return hashFingerprintContents(&asn_DEF_PrefixFingerprintContents, fp); + hashFingerprintContents(&asn_DEF_PrefixFingerprintContents, fp, out); } diff --git a/src/cryptoconditions/src/preimage.c b/src/cryptoconditions/src/preimage.c index 9e7fe12f4..a45e621d4 100644 --- a/src/cryptoconditions/src/preimage.c +++ b/src/cryptoconditions/src/preimage.c @@ -44,11 +44,8 @@ static unsigned long preimageCost(const CC *cond) { } -static unsigned char *preimageFingerprint(const CC *cond) { - unsigned char *hash = calloc(1, 32); - //fprintf(stderr,"preimage %p %p\n",hash,cond->preimage); - sha256(cond->preimage, cond->preimageLength, hash); - return hash; +static void preimageFingerprint(const CC *cond, uint8_t *out) { + sha256(cond->preimage, cond->preimageLength, out); } diff --git a/src/cryptoconditions/src/secp256k1.c b/src/cryptoconditions/src/secp256k1.c index a16115bb8..44ff1f0e2 100644 --- a/src/cryptoconditions/src/secp256k1.c +++ b/src/cryptoconditions/src/secp256k1.c @@ -88,11 +88,10 @@ void initVerify() { } -static unsigned char *secp256k1Fingerprint(const CC *cond) { +static void secp256k1Fingerprint(const CC *cond, uint8_t *out) { Secp256k1FingerprintContents_t *fp = calloc(1, sizeof(Secp256k1FingerprintContents_t)); - //fprintf(stderr,"secpfinger %p %p size %d vs %d\n",fp,cond->publicKey,(int32_t)sizeof(Secp256k1FingerprintContents_t),(int32_t)SECP256K1_PK_SIZE); OCTET_STRING_fromBuf(&fp->publicKey, cond->publicKey, SECP256K1_PK_SIZE); - return hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp); + hashFingerprintContents(&asn_DEF_Secp256k1FingerprintContents, fp, out); } diff --git a/src/cryptoconditions/src/threshold.c b/src/cryptoconditions/src/threshold.c index 9547f4f8c..e94666c3d 100644 --- a/src/cryptoconditions/src/threshold.c +++ b/src/cryptoconditions/src/threshold.c @@ -94,17 +94,15 @@ static int cmpConditionBin(const void *a, const void *b) { } -static unsigned char *thresholdFingerprint(const CC *cond) { - /* Create fingerprint */ +static void thresholdFingerprint(const CC *cond, uint8_t *out) { ThresholdFingerprintContents_t *fp = calloc(1, sizeof(ThresholdFingerprintContents_t)); - //fprintf(stderr,"thresholdfinger %p\n",fp); fp->threshold = cond->threshold; for (int i=0; isize; i++) { Condition_t *asnCond = asnConditionNew(cond->subconditions[i]); asn_set_add(&fp->subconditions2, asnCond); } qsort(fp->subconditions2.list.array, cond->size, sizeof(Condition_t*), cmpConditionBin); - return hashFingerprintContents(&asn_DEF_ThresholdFingerprintContents, fp); + hashFingerprintContents(&asn_DEF_ThresholdFingerprintContents, fp, out); } diff --git a/src/cryptoconditions/src/utils.c b/src/cryptoconditions/src/utils.c index 6a2167119..ebb2bd143 100644 --- a/src/cryptoconditions/src/utils.c +++ b/src/cryptoconditions/src/utils.c @@ -210,7 +210,7 @@ void jsonAddBase64(cJSON *params, char *key, unsigned char *bin, size_t size) { } -unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp) { +void hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp, uint8_t *out) { unsigned char buf[BUF_SIZE]; asn_enc_rval_t rc = der_encode_to_buffer(asnType, fp, buf, BUF_SIZE); ASN_STRUCT_FREE(*asnType, fp); @@ -218,9 +218,7 @@ unsigned char *hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp) fprintf(stderr, "Encoding fingerprint failed\n"); return 0; } - unsigned char *hash = calloc(1,32); - sha256(buf, rc.encoded, hash); - return hash; + sha256(buf, rc.encoded, out); } From f3a4f773687ee6e29eff4801e9880f6c4282827d Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 19 May 2020 10:03:53 +0200 Subject: [PATCH 111/220] port expired transaction notify from Zcash. Issue #110 --- src/init.cpp | 11 +++++++++++ src/main.cpp | 6 +++++- src/txmempool.cpp | 5 ++++- src/txmempool.h | 2 +- src/ui_interface.h | 3 +++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index ac15db192..fd0303786 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -399,6 +399,7 @@ std::string HelpMessage(HelpMessageMode mode) #ifndef _WIN32 strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), "komodod.pid")); #endif + strUsage += HelpMessageOpt("-txexpirynotify=", _("Execute command when transaction expires (%s in cmd is replaced by transaction id)")); strUsage += HelpMessageOpt("-prune=", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); @@ -618,6 +619,14 @@ static void BlockNotifyCallback(const uint256& hashNewTip) boost::thread t(runCommand, strCmd); // thread runs free } +static void TxExpiryNotifyCallback(const uint256& txid) +{ + std::string strCmd = GetArg("-txexpirynotify", ""); + + boost::replace_all(strCmd, "%s", txid.GetHex()); + boost::thread t(runCommand, strCmd); // thread runs free +} + struct CImportingNow { CImportingNow() { @@ -2114,6 +2123,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); + if (mapArgs.count("-txexpirynotify")) + uiInterface.NotifyTxExpiration.connect(TxExpiryNotifyCallback); if ( KOMODO_REWIND >= 0 ) { uiInterface.InitMessage(_("Activating best chain...")); diff --git a/src/main.cpp b/src/main.cpp index 17b89a76b..3426facd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4210,7 +4210,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * mempool.removeForBlock(pblock->vtx, pindexNew->GetHeight(), txConflicted, !IsInitialBlockDownload()); // Remove transactions that expire at new block height from mempool - mempool.removeExpired(pindexNew->GetHeight()); + auto ids = mempool.removeExpired(pindexNew->GetHeight()); + + for (auto id : ids) { + uiInterface.NotifyTxExpiration(id); + } // Update chainActive & related variables. UpdateTip(pindexNew); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 8a99a99e6..307be723e 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -513,7 +513,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag); extern char ASSETCHAINS_SYMBOL[]; -void CTxMemPool::removeExpired(unsigned int nBlockHeight) +std::vector CTxMemPool::removeExpired(unsigned int nBlockHeight) { CBlockIndex *tipindex; // Remove expired txs from the mempool @@ -528,11 +528,14 @@ void CTxMemPool::removeExpired(unsigned int nBlockHeight) transactionsToRemove.push_back(tx); } } + std::vector ids; for (const CTransaction& tx : transactionsToRemove) { list removed; remove(tx, removed, true); + ids.push_back(tx.GetHash()); LogPrint("mempool", "Removing expired txid: %s\n", tx.GetHash().ToString()); } + return ids; } /** diff --git a/src/txmempool.h b/src/txmempool.h index f8aa0e9a7..59eeb0d98 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -218,7 +218,7 @@ public: void removeWithAnchor(const uint256 &invalidRoot, ShieldedType type); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); - void removeExpired(unsigned int nBlockHeight); + std::vector removeExpired(unsigned int nBlockHeight); void removeForBlock(const std::vector& vtx, unsigned int nBlockHeight, std::list& conflicts, bool fCurrentEstimate = true); void removeWithoutBranchId(uint32_t nMemPoolBranchId); diff --git a/src/ui_interface.h b/src/ui_interface.h index ee0fd9113..59a549a9d 100644 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -98,6 +98,9 @@ public: /** New block has been accepted */ boost::signals2::signal NotifyBlockTip; + + /** Transaction expired */ + boost::signals2::signal NotifyTxExpiration; }; extern CClientUIInterface uiInterface; From 6e4be99c21fb0c14d0475321a11cf136b6b32d1a Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Tue, 19 May 2020 10:20:28 +0200 Subject: [PATCH 112/220] Add dpow season 4 pubkeys Issue #109 --- src/komodo_defs.h | 71 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 34b1cc364..fa22a49ba 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -47,7 +47,7 @@ // 7113400 = 5x current KMD blockheight. // to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays. -#define NUM_KMD_SEASONS 4 +#define NUM_KMD_SEASONS 5 #define NUM_KMD_NOTARIES 64 // $ ./contrib/block_time.pl 166250 @@ -329,7 +329,74 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"gt_AR", "0307c1cf89bd8ed4db1b09a0a98cf5f746fc77df3803ecc8611cf9455ec0ce6960" }, {"patchkez_SH", "03d7c187689bf829ca076a30bbf36d2e67bb74e16a3290d8a55df21d6cb15c80c1" }, {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" } - } + }, + { + // Season 4 + { "alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, + { "alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, + { "strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405" }, + { "titomane_SH", "020014ad4eedf6b1aeb0ad3b101a58d0a2fc570719e46530fd98d4e585f63eb4ae" }, + { "fullmoon_AR", "03b251095e747f759505ec745a4bbff9a768b8dce1f65137300b7c21efec01a07a" }, + { "phba2061_EU", "03a9492d2a1601d0d98cfe94d8adf9689d1bb0e600088127a4f6ca937761fb1c66" }, + { "fullmoon_NA", "03931c1d654a99658998ce0ddae108d825943a821d1cddd85e948ac1d483f68fb6" }, + { "fullmoon_SH", "03c2a1ed9ddb7bb8344328946017b9d8d1357b898957dd6aaa8c190ae26740b9ff" }, + { "madmax_AR", "022be5a2829fa0291f9a51ff7aeceef702eef581f2611887c195e29da49092e6de" }, + { "titomane_EU", "0285cf1fdba761daf6f1f611c32d319cd58214972ef822793008b69dde239443dd" }, + { "cipi_NA", "022c6825a24792cc3b010b1531521eba9b5e2662d640ed700fd96167df37e75239" }, + { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, + { "decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, + { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, + { "madmax_NA", "02997b7ab21b86bbea558ae79acc35d62c9cedf441578f78112f986d72e8eece08" }, + { "chainzilla_SH", "02288ba6dc57936b59d60345e397d62f5d7e7d975f34ed5c2f2e23288325661563" }, + { "peer2cloud_AR", "0250e7e43a3535731b051d1bcc7dc88fbb5163c3fe41c5dee72bd973bcc4dca9f2" }, + { "pirate_EU", "0231c0f50a06655c3d2edf8d7e722d290195d49c78d50de7786b9d196e8820c848" }, + { "webworker01_NA", "02dfd5f3cef1142879a7250752feb91ddd722c497fb98c7377c0fcc5ccc201bd55" }, + { "zatjum_SH", "036066fd638b10e555597623e97e032b28b4d1fa5a13c2b0c80c420dbddad236c2" }, + { "titomane_AR", "0268203a4c80047edcd66385c22e764ea5fb8bc42edae389a438156e7dca9a8251" }, + { "chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d" }, + { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, + { "patchkez_SH", "02cabd6c5fc0b5476c7a01e9d7b907e9f0a051d7f4f731959955d3f6b18ee9a242" }, + { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, + { "etszombi_EU", "0341adbf238f33a33cc895633db996c3ad01275313ac6641e046a3db0b27f1c880" }, + { "pirate_NA", "02207f27a13625a0b8caef6a7bb9de613ff16e4a5f232da8d7c235c7c5bad72ffe" }, + { "metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, + { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, + { "chainmakers_NA", "029415a1609c33dfe4a1016877ba35f9265d25d737649f307048efe96e76512877" }, + { "mihailo_EU", "037f9563f30c609b19fd435a19b8bde7d6db703012ba1aba72e9f42a87366d1941" }, + { "tonyl_AR", "0299684d7291abf90975fa493bf53212cf1456c374aa36f83cc94daece89350ae9" }, + { "alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8" }, + { "pungocloud_SH", "025b97d8c23effaca6fa7efacce20bf54df73081b63004a0fe22f3f98fece5669f" }, + { "node9_EU", "029ffa793b5c3248f8ea3da47fa3cf1810dada5af032ecd0e37bab5b92dd63b34e" }, + { "smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac" }, + { "nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b" }, + { "gcharang_SH", "02ec4172eab854a0d8cd32bc691c83e93975a3df5a4a453a866736c56e025dc359" }, + { "cipi_EU", "02f2b6defff1c544202f66e47cfd6909c54d67c7c39b9c2a99f137dbaf6d0bd8fa" }, + { "etszombi_AR", "0329944b0ac65b6760787ede042a2fde0be9fca1d80dd756bc0ee0b98d389b7682" }, + { "pbca26_NA", "0387e0fb6f2ca951154c87e16c6cbf93a69862bb165c1a96bcd8722b3af24fe533" }, + { "mylo_SH", "03b58f57822e90fe105e6efb63fd8666033ea503d6cc165b1e479bbd8c2ba033e8" }, + { "swisscertifiers_EU", "03ebcc71b42d88994b8b2134bcde6cb269bd7e71a9dd7616371d9294ec1c1902c5" }, + { "marmarachain_AR", "035bbd81a098172592fe97f50a0ce13cbbf80e55cc7862eccdbd7310fab8a90c4c" }, + { "karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d" }, + { "phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, + { "oszy_EU", "03d1ffd680491b98a3ec5541715681d1a45293c8efb1722c32392a1d792622596a" }, + { "chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005" }, + { "dragonhound_NA", "0227e5cad3731e381df157de189527aac8eb50d82a13ce2bd81153984ebc749515" }, + { "strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a" }, + { "madmax_EU", "02ea0cf4d6d151d0528b07efa79cc7403d77cb9195e2e6c8374f5074b9a787e287" }, + { "dudezmobi_AR", "027ecd974ff2a27a37ee69956cd2e6bb31a608116206f3e31ef186823420182450" }, + { "daemonfox_NA", "022d6f4885f53cbd668ad7d03d4f8e830c233f74e3a918da1ed247edfc71820b3d" }, + { "nutellalicka_SH", "02f4b1e71bc865a79c05fe333952b97cb040d8925d13e83925e170188b3011269b" }, + { "starfleet_EU", "025c7275bd750936862b47793f1f0bb3cbed60fb75a48e7da016e557925fe375eb" }, + { "mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4" }, + { "greer_NA", "03e0995615d7d3cf1107effa6bdb1133e0876cf1768e923aa533a4e2ee675ec383" }, + { "mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043" }, + { "decker_EU", "03777777caebce56e17ca3aae4e16374335b156f1dd62ee3c7f8799c6b885f5560" }, + { "dappvader_SH", "02962e2e5af746632016bc7b24d444f7c90141a5f42ce54e361b302cf455d90e6a" }, + { "alright_DEV", "02b73a589d61691efa2ada15c006d27bc18493fea867ce6c14db3d3d28751f8ce3" }, + { "artemii235_DEV", "03bb616b12430bdd0483653de18733597a4fd416623c7065c0e21fe9d96460add1" }, + { "tonyl_DEV", "02d5f7fd6e25d34ab2f3318d60cdb89ff3a812ec5d0212c4c113bb12d12616cfdc" }, + { "decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" } + } }; #define SETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] |= (1 << ((bitoffset) & 7))) From b879f536e98fb99f4347dcfea6892b611756b765 Mon Sep 17 00:00:00 2001 From: ca333 Date: Sat, 14 Mar 2020 23:18:16 +0100 Subject: [PATCH 113/220] debug.log spam prevention --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 3426facd7..20d4a0355 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1224,9 +1224,9 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde if (IsExpiredTx(tx, nHeight)) { // Don't increase banscore if the transaction only just expired int expiredDosLevel = IsExpiredTx(tx, nHeight - 1) ? (dosLevel > 10 ? dosLevel : 10) : 0; - string strHex = EncodeHexTx(tx); + //string strHex = EncodeHexTx(tx); //fprintf(stderr, "transaction exipred.%s\n",strHex.c_str()); - return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction %s is expired, expiry block %i vs current block %i\n txhex.%s",tx.GetHash().ToString(),tx.nExpiryHeight,nHeight,strHex), REJECT_INVALID, "tx-overwinter-expired"); + return state.DoS(expiredDosLevel, error("ContextualCheckTransaction(): transaction %s is expired, expiry block %i vs current block %i\n",tx.GetHash().ToString(),tx.nExpiryHeight,nHeight), REJECT_INVALID, "tx-overwinter-expired"); } } From 3199c01328989ccca6641d7014dfbc80ba2ddd4e Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Sun, 26 Jan 2020 07:34:49 +0300 Subject: [PATCH 114/220] =?UTF-8?q?CVE-2018=E2=80=9320586=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - https://medium.com/@lukedashjr/cve-2018-20586-disclosure-ff3e1ab9a21f - https://github.com/bitcoin/bitcoin/pull/14618/files --- src/httpserver.cpp | 11 ++++++++--- src/utilstrencodings.cpp | 3 ++- src/utilstrencodings.h | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index e1d235665..603e1e6ae 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -11,6 +11,7 @@ #include "rpc/protocol.h" // For HTTP status codes #include "sync.h" #include "ui_interface.h" +#include "utilstrencodings.h" #include #include @@ -251,21 +252,25 @@ static void http_request_cb(struct evhttp_request* req, void* arg) { std::unique_ptr hreq(new HTTPRequest(req)); - LogPrint("http", "Received a %s request for %s from %s\n", - RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString()); - // Early address-based allow check if (!ClientAllowed(hreq->GetPeer())) { + LogPrint("http", "HTTP request from %s rejected: Client network is not allowed RPC access\n", + hreq->GetPeer().ToString()); hreq->WriteReply(HTTP_FORBIDDEN); return; } // Early reject unknown HTTP methods if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) { + LogPrint("http", "HTTP request from %s rejected: Unknown HTTP request method\n", + hreq->GetPeer().ToString()); hreq->WriteReply(HTTP_BADMETHOD); return; } + LogPrint("http", "Received a %s request for %s from %s\n", + RequestMethodString(hreq->GetRequestMethod()), SanitizeString(hreq->GetURI(), SAFE_CHARS_URI).substr(0, 100), hreq->GetPeer().ToString()); + // Find registered handler for prefix std::string strURI = hreq->GetURI(); std::string path; diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index d4bba72ee..132ae82ab 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -20,7 +20,8 @@ static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO static const string SAFE_CHARS[] = { CHARS_ALPHA_NUM + " .,;_/:?@()", // SAFE_CHARS_DEFAULT - CHARS_ALPHA_NUM + " .,;_?@" // SAFE_CHARS_UA_COMMENT + CHARS_ALPHA_NUM + " .,;_?@", // SAFE_CHARS_UA_COMMENT + CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%" // SAFE_CHARS_URI }; string SanitizeString(const string& str, int rule) diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index 37a07ea06..2d851093f 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -26,7 +26,8 @@ enum SafeChars { SAFE_CHARS_DEFAULT, //!< The full set of allowed chars - SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset + SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset + SAFE_CHARS_URI //!< Chars allowed in URIs (RFC 3986) }; std::string SanitizeFilename(const std::string& str); From bde1f3c632556fdfa4ac210fa0b7994a76c5a911 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Mon, 27 Jan 2020 05:00:24 +0300 Subject: [PATCH 115/220] limit blockchain progress to a max of 1.000000 Issue: https://github.com/zcash/zcash/issues/3161 Fix commit: https://github.com/zcash/zcash/pull/4176/commits/b3594b52739c96105a3f6976924a9075b1c5bbe2 --- src/checkpoints.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 7fd94e4e7..026475f88 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -74,7 +74,7 @@ namespace Checkpoints { fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor; } - return fWorkBefore / (fWorkBefore + fWorkAfter); + return std::min(fWorkBefore / (fWorkBefore + fWorkAfter), 1.0); } int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data) From c7d96194d6edb348febaea95b829032a504168b8 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Thu, 19 Mar 2020 01:55:56 +0300 Subject: [PATCH 116/220] [test] proper removing of txes that violates interest validation from mempool In CreateNewBlock of miner https://github.com/KomodoPlatform/komodo/blob/master/src/miner.cpp#L331 we have a condition that prevents miners to include certain txes in block if tx violates komodo_validate_interest check. so, if such txes will exist in mempool and in some reason they was not miner earlier, if they have nExpiryHeight = 0 - they NEVER will be included in block by miners. Also, code in CTxMemPool::removeExpired that should remove such txes from mempool didn't do it due to mistake. As a result these txes stucks in mempool. No one can mine it, bcz no one can include it in block, and no one get success to remove it from mempool. Look on old code: ``` (ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(...) ) < 0 ``` But should be: ``` (ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(...) < 0 ) ``` Bcz we should compare with 0 result of komodo_validate_interest, but we had different behaviour, due to typo. --- src/txmempool.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 307be723e..ca0ed7f51 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -523,8 +523,12 @@ std::vector CTxMemPool::removeExpired(unsigned int nBlockHeight) { const CTransaction& tx = it->GetTx(); tipindex = chainActive.LastTip(); - if (IsExpiredTx(tx, nBlockHeight) || (ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(tx,tipindex->GetHeight()+1,tipindex->GetMedianTimePast() + 777,0)) < 0) + + bool fInterestNotValidated = ASSETCHAINS_SYMBOL[0] == 0 && tipindex != 0 && komodo_validate_interest(tx,tipindex->GetHeight()+1,tipindex->GetMedianTimePast() + 777,0) < 0; + if (IsExpiredTx(tx, nBlockHeight) || fInterestNotValidated) { + if (fInterestNotValidated && tipindex != 0) + LogPrintf("Removing interest violate txid.%s nHeight.%d nTime.%u vs locktime.%u\n",tx.GetHash().ToString(),tipindex->GetHeight()+1,tipindex->GetMedianTimePast() + 777,tx.nLockTime); transactionsToRemove.push_back(tx); } } From 2c60f2ffaeec2a9a8e1960de672bad4f2d965b53 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Tue, 25 Feb 2020 17:56:17 +0300 Subject: [PATCH 117/220] disable assertion when -debug arg is passed --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 8d3c5d4c4..a91fa9527 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -340,7 +340,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 if (!mempool.mapTx.count(txin.prevout.hash)) { LogPrintf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); + // if (fDebug) assert("mempool transaction missing input" == 0); fMissingInputs = true; if (porphan) vOrphan.pop_back(); From c0834c3cb7bca48b2b9f701c2e2000aa3f2ed919 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 01:55:00 -0400 Subject: [PATCH 118/220] S4 dpow notaries --- src/komodo_defs.h | 130 +++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index fa22a49ba..6d867b229 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -331,71 +331,71 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" } }, { - // Season 4 - { "alien_AR", "03911a60395801082194b6834244fa78a3c30ff3e888667498e157b4aa80b0a65f" }, - { "alien_EU", "03bb749e337b9074465fa28e757b5aa92cb1f0fea1a39589bca91a602834d443cd" }, - { "strob_NA", "02a1c0bd40b294f06d3e44a52d1b2746c260c475c725e9351f1312e49e01c9a405" }, - { "titomane_SH", "020014ad4eedf6b1aeb0ad3b101a58d0a2fc570719e46530fd98d4e585f63eb4ae" }, - { "fullmoon_AR", "03b251095e747f759505ec745a4bbff9a768b8dce1f65137300b7c21efec01a07a" }, - { "phba2061_EU", "03a9492d2a1601d0d98cfe94d8adf9689d1bb0e600088127a4f6ca937761fb1c66" }, - { "fullmoon_NA", "03931c1d654a99658998ce0ddae108d825943a821d1cddd85e948ac1d483f68fb6" }, - { "fullmoon_SH", "03c2a1ed9ddb7bb8344328946017b9d8d1357b898957dd6aaa8c190ae26740b9ff" }, - { "madmax_AR", "022be5a2829fa0291f9a51ff7aeceef702eef581f2611887c195e29da49092e6de" }, - { "titomane_EU", "0285cf1fdba761daf6f1f611c32d319cd58214972ef822793008b69dde239443dd" }, - { "cipi_NA", "022c6825a24792cc3b010b1531521eba9b5e2662d640ed700fd96167df37e75239" }, - { "indenodes_SH", "0334e6e1ec8285c4b85bd6dae67e17d67d1f20e7328efad17ce6fd24ae97cdd65e" }, - { "decker_AR", "03ffdf1a116300a78729608d9930742cd349f11a9d64fcc336b8f18592dd9c91bc" }, - { "indenodes_EU", "0221387ff95c44cb52b86552e3ec118a3c311ca65b75bf807c6c07eaeb1be8303c" }, - { "madmax_NA", "02997b7ab21b86bbea558ae79acc35d62c9cedf441578f78112f986d72e8eece08" }, - { "chainzilla_SH", "02288ba6dc57936b59d60345e397d62f5d7e7d975f34ed5c2f2e23288325661563" }, - { "peer2cloud_AR", "0250e7e43a3535731b051d1bcc7dc88fbb5163c3fe41c5dee72bd973bcc4dca9f2" }, - { "pirate_EU", "0231c0f50a06655c3d2edf8d7e722d290195d49c78d50de7786b9d196e8820c848" }, - { "webworker01_NA", "02dfd5f3cef1142879a7250752feb91ddd722c497fb98c7377c0fcc5ccc201bd55" }, - { "zatjum_SH", "036066fd638b10e555597623e97e032b28b4d1fa5a13c2b0c80c420dbddad236c2" }, - { "titomane_AR", "0268203a4c80047edcd66385c22e764ea5fb8bc42edae389a438156e7dca9a8251" }, - { "chmex_EU", "025b7209ba37df8d9695a23ea706ea2594863ab09055ca6bf485855937f3321d1d" }, - { "indenodes_NA", "02698c6f1c9e43b66e82dbb163e8df0e5a2f62f3a7a882ca387d82f86e0b3fa988" }, - { "patchkez_SH", "02cabd6c5fc0b5476c7a01e9d7b907e9f0a051d7f4f731959955d3f6b18ee9a242" }, - { "metaphilibert_AR", "02adad675fae12b25fdd0f57250b0caf7f795c43f346153a31fe3e72e7db1d6ac6" }, - { "etszombi_EU", "0341adbf238f33a33cc895633db996c3ad01275313ac6641e046a3db0b27f1c880" }, - { "pirate_NA", "02207f27a13625a0b8caef6a7bb9de613ff16e4a5f232da8d7c235c7c5bad72ffe" }, - { "metaphilibert_SH", "0284af1a5ef01503e6316a2ca4abf8423a794e9fc17ac6846f042b6f4adedc3309" }, - { "indenodes_AR", "02ec0fa5a40f47fd4a38ea5c89e375ad0b6ddf4807c99733c9c3dc15fb978ee147" }, - { "chainmakers_NA", "029415a1609c33dfe4a1016877ba35f9265d25d737649f307048efe96e76512877" }, - { "mihailo_EU", "037f9563f30c609b19fd435a19b8bde7d6db703012ba1aba72e9f42a87366d1941" }, - { "tonyl_AR", "0299684d7291abf90975fa493bf53212cf1456c374aa36f83cc94daece89350ae9" }, - { "alien_NA", "03bea1ac333b95c8669ec091907ea8713cae26f74b9e886e13593400e21c4d30a8" }, - { "pungocloud_SH", "025b97d8c23effaca6fa7efacce20bf54df73081b63004a0fe22f3f98fece5669f" }, - { "node9_EU", "029ffa793b5c3248f8ea3da47fa3cf1810dada5af032ecd0e37bab5b92dd63b34e" }, - { "smdmitry_AR", "022a2a45979a6631a25e4c96469423de720a2f4c849548957c35a35c91041ee7ac" }, - { "nodeone_NA", "03f9dd0484e81174fd50775cb9099691c7d140ff00c0f088847e38dc87da67eb9b" }, - { "gcharang_SH", "02ec4172eab854a0d8cd32bc691c83e93975a3df5a4a453a866736c56e025dc359" }, - { "cipi_EU", "02f2b6defff1c544202f66e47cfd6909c54d67c7c39b9c2a99f137dbaf6d0bd8fa" }, - { "etszombi_AR", "0329944b0ac65b6760787ede042a2fde0be9fca1d80dd756bc0ee0b98d389b7682" }, - { "pbca26_NA", "0387e0fb6f2ca951154c87e16c6cbf93a69862bb165c1a96bcd8722b3af24fe533" }, - { "mylo_SH", "03b58f57822e90fe105e6efb63fd8666033ea503d6cc165b1e479bbd8c2ba033e8" }, - { "swisscertifiers_EU", "03ebcc71b42d88994b8b2134bcde6cb269bd7e71a9dd7616371d9294ec1c1902c5" }, - { "marmarachain_AR", "035bbd81a098172592fe97f50a0ce13cbbf80e55cc7862eccdbd7310fab8a90c4c" }, - { "karasugoi_NA", "0262cf2559703464151153c12e00c4b67a969e39b330301fdcaa6667d7eb02c57d" }, - { "phm87_SH", "021773a38db1bc3ede7f28142f901a161c7b7737875edbb40082a201c55dcf0add" }, - { "oszy_EU", "03d1ffd680491b98a3ec5541715681d1a45293c8efb1722c32392a1d792622596a" }, - { "chmex_AR", "036c856ea778ea105b93c0be187004d4e51161eda32888aa307b8f72d490884005" }, - { "dragonhound_NA", "0227e5cad3731e381df157de189527aac8eb50d82a13ce2bd81153984ebc749515" }, - { "strob_SH", "025ceac4256cef83ca4b110f837a71d70a5a977ecfdf807335e00bc78b560d451a" }, - { "madmax_EU", "02ea0cf4d6d151d0528b07efa79cc7403d77cb9195e2e6c8374f5074b9a787e287" }, - { "dudezmobi_AR", "027ecd974ff2a27a37ee69956cd2e6bb31a608116206f3e31ef186823420182450" }, - { "daemonfox_NA", "022d6f4885f53cbd668ad7d03d4f8e830c233f74e3a918da1ed247edfc71820b3d" }, - { "nutellalicka_SH", "02f4b1e71bc865a79c05fe333952b97cb040d8925d13e83925e170188b3011269b" }, - { "starfleet_EU", "025c7275bd750936862b47793f1f0bb3cbed60fb75a48e7da016e557925fe375eb" }, - { "mrlynch_AR", "031987dc82b087cd53e23df5480e265a5928e9243e0e11849fa12359739d8b18a4" }, - { "greer_NA", "03e0995615d7d3cf1107effa6bdb1133e0876cf1768e923aa533a4e2ee675ec383" }, - { "mcrypt_SH", "025faab3cc2e83bf7dad6a9463cbff86c08800e937942126f258cf219bc2320043" }, - { "decker_EU", "03777777caebce56e17ca3aae4e16374335b156f1dd62ee3c7f8799c6b885f5560" }, - { "dappvader_SH", "02962e2e5af746632016bc7b24d444f7c90141a5f42ce54e361b302cf455d90e6a" }, - { "alright_DEV", "02b73a589d61691efa2ada15c006d27bc18493fea867ce6c14db3d3d28751f8ce3" }, - { "artemii235_DEV", "03bb616b12430bdd0483653de18733597a4fd416623c7065c0e21fe9d96460add1" }, - { "tonyl_DEV", "02d5f7fd6e25d34ab2f3318d60cdb89ff3a812ec5d0212c4c113bb12d12616cfdc" }, - { "decker_DEV", "028eea44a09674dda00d88ffd199a09c9b75ba9782382cc8f1e97c0fd565fe5707" } + // Season 4 https://github.com/KomodoPlatform/dPoW/blob/s4/iguana/3rd_party + {"alien_AR", "024f20c096b085308e21893383f44b4faf1cdedea9ad53cc7d7e7fbfa0c30c1e71" }, + {"alien_EU", "022b85908191788f409506ebcf96a892f3274f352864c3ed566c5a16de63953236" }, + {"alien_NA", "022f62b56ddfd07c9860921c701285ac39bb3ac8f6f083d1b59c8f4943be3de162" }, + {"alright_DEV", "03b6f9493658bdd102503585a08ae642b49d6a68fb69ac3626f9737cd7581abdfa" }, + {"artemii235_DEV", "037a20916d2e9ea575300ac9d729507c23a606b9a200c8e913d7c9832f912a1fa7" }, + {"chainmakers_NA", "028803e07bcc521fde264b7191a944f9b3612e8ee4e24a99bcd903f6976240839a" }, + {"chainzilla_SH", "0311dde03c2dd654ce78323b718ed3ad73a464d1bde97820f3395f54788b5420dd" }, + {"chmex_AR", "030cd487e10fbf142e0e8d582e702ecb775f378569c3cb5acd0ff97b6b12803588" }, + {"chmex_EU", "030bf7bd7ad0515c33b5d5d9a91e0729baf801b9002f80495ae535ea1cebb352cb" }, + {"cipi_EU", "026f4f66385daaf8313ef30ffe4988e7db497132682dca185a70763d93e1417d9d" }, + {"cipi_NA", "03f4e69edcb4fa3b2095cb8cb1ca010f4ec4972eac5d8822397e5c8d87aa21a739" }, + {"daemonfox_NA", "023c7584b1006d4a62a4b4c9c1ede390a3789316547897d5ed49ff9385a3acb411" }, + {"dappvader_SH", "025199bc04bcb8a17976d9fe8bc87763a6150c2727321aa59bf34a2b49f2f3a0ce" }, + {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" }, + {"decker_DEV", "02fca8ee50e49f480de275745618db7b0b3680b0bdcce7dcae7d2e0fd5c3345744" }, + {"decker_EU", "027777775b89ff548c3be54fb0c9455437d87f38bfce83bdef113899881b219c9e" }, + {"dragonhound_NA", "029912212d370ee0fb4d38eefd8bfcd8ab04e2c3b0354020789c29ddf2a35c72d6" }, + {"dudezmobi_AR", "033c121d3f8d450174674a73f3b7f140b2717a7d51ea19ee597e2e8e8f9d5ed87f" }, + {"etszombi_AR", "03bfcbca83f11e622fa4eed9a1fa25dba377981ea3b22e3d0a4015f9a932af9272" }, + {"etszombi_EU", "03a5c083c78ba397970f20b544a01c13e7ed36ca8a5ae26d5fe7bd38b92b6a0c94" }, + {"fullmoon_AR", "03639bc56d3fecf856f17759a441c5893668e7c2d460f3d216798a413cd6766bb2" }, + {"fullmoon_NA", "03e388bcc579ac2675f8fadfa921eec186dcea8d2b43de1eed6caba23d5a962b74" }, + {"fullmoon_SH", "03a5cfda2b097c808834ccdd805828c811b519611feabdfe6b3644312e53f6748f" }, + {"gcharang_SH", "02a654037d12cdd609f4fad48e15ec54538e03f61fdae1acb855f16ebacac6bd73" }, + {"greer_NA", "0262da6aaa0b295b8e2f120035924758a4a630f899316dc63ee15ef03e9b7b2b23" }, + {"indenodes_AR", "0242778789986d614f75bcf629081651b851a12ab1cc10c73995b27b90febb75a2" }, + {"indenodes_EU", "03a416533cace0814455a1bb1cd7861ce825a543c6f6284a432c4c8d8875b7ace9" }, + {"indenodes_NA", "02b3908eda4078f0e9b6704451cdc24d418e899c0f515fab338d7494da6f0a647b" }, + {"indenodes_SH", "031d1584cf0eb4a2d314465e49e2677226b1615c3718013b8d6b4854c15676a58c" }, + {"karasugoi_NA", "02f803e6f159824a181cc5d709f3d1e7ff65f19e1899920724aeb4e3d2d869f911" }, + {"madmax_AR", "027afddbcf690230dd8d435ec16a7bfb0083e6b77030f763437f291dfc40a579d0" }, + {"madmax_EU", "0397ec3a4ad84b3009566d260c89f1c4404e86e5d044964747c9371277e38f5995" }, + {"madmax_NA", "036d3afebe1eab09f4c38c3ee6a4659ad390f3df92787c11437a58c59a29e408e6" }, + {"marmarachain_AR", "028690ca1e3afdf8a38b421f6a41f5ff407afc96d5a7a6a488330aae26c8b086bb" }, + {"mcrypt_SH", "027a4ca7b11d3456ff558c08bb04483a89c7f383448461fd0b6b3b07424aabe9a4" }, + {"metaphilibert_AR", "0239e34ad22957bbf4c8df824401f237b2afe8d40f7a645ecd43e8f27dde1ab0da" }, + {"metaphilibert_SH", "03b21ff042bf1730b28bde43f44c064578b41996117ac7634b567c3773089e3be3" }, + {"mihailo_EU", "036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252" }, + {"mrlynch_AR", "03e67440141f53a08684c329ebc852b018e41f905da88e52aa4a6dc5aa4b12447a" }, + {"mylo_SH", "026d5f29d09ff3f33e14db4811606249b2438c6bcf964876714f81d1f2d952acde" }, + {"node9_EU", "0392e4c9400e69f28c6b9e89d586da69d5a6af7702f1045eaa6ebc1996f0496e1f" }, + {"nodeone_NA", "0310a249c6c2dcc29f2135715138a9ddb8e01c0eab701cbd0b96d9cec660dbdc58" }, + {"nutellalicka_SH", "0284c4d3cb97dd8a32d10fb32b1855ae18cf845dad542e3b8937ca0e998fb54ecc" }, + {"oszy_EU", "03c53bd421de4a29ce68c8cc83f802e1181e77c08f8f16684490d61452ea8d023a" }, + {"patchkez_SH", "028c08db6e7242681f50db6c234fe3d6e12fb1a915350311be26373bac0d457d49" }, + {"pbca26_NA", "03c18431bb6bc95672f640f19998a196becd2851d5dcba4795fe8d85b7d77eab81" }, + {"peer2cloud_AR", "0243958faf9ae4d43b598b859ddc595c170c4cf50f8e4517d660ae5bc72aeb821b" }, + {"phba2061_EU", "03369187ce134bd7793ee34af7756fe1ab27202e09306491cdd5d8ad2c71697937" }, + {"phm87_SH", "03889a10f9df2caef57220628515693cf25316fe1b0693b0241419e75d0d0e66ed" }, + {"pirate_EU", "0240011b95cde819f298fe0f507b2260c9fecdab784924076d4d1e54c522103cb1" }, + {"pirate_NA", "02ad7ef25d2dd461e361120cd3efe7cbce5e9512c361e9185aac33dd303d758613" }, + {"pungocloud_SH", "02641c36ae6747b88150a463a1fe65cf7a9d1c00a64387c73f296f0b64e77c7d3f" }, + {"smdmitry_AR", "0397b7584cb29717b721c0c587d4462477efc1f36a56921f133c9d17b0cd7f278a" }, + {"starfleet_EU", "03c6e047218f34644ccba67e317b9da5d28e68bbbb6b9973aef1281d2bafa46496" }, + {"strob_NA", "02285bf2f9e96068ecac14bc6f770e394927b4da9f5ba833eaa9468b5d47f203a3" }, + {"strob_SH", "0213751a1c59d3489ca85b3d62a3d606dcef7f0428aa021c1978ea16fb38a2fad6" }, + {"swisscertifiers_EU", "02e7722ebba9f8b5ebfb4e87d4fa58cc75aef677535b9cfc060c7d9471aacd9c9e" }, + {"titomane_AR", "03958bd8d13fe6946b8d0d0fbbc3861c72542560d0276e80a4c6b5fe55bc758b81" }, + {"titomane_EU", "02276090e483db1a01a802456b10831b3b6e0a6ad3ece9b2a01f4aad0e480c8edc" }, + {"titomane_SH", "02abf206bafc8048dbdc042b8eb6b1e356ea5dbe149eae3532b4811d4905e5cf01" }, + {"tonyl_AR", "0229e499e3f2e065ced402ceb8aaf3d5ab8bd3793aa074305e9fa30772ce604908" }, + {"tonyl_DEV", "0258b77d7dcfc6c2628b0b6b438951a6e74201fb2cd180a795e4c37fcf8e78a678" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"zatjum_SH", "0241c5660ca540780be66603b1791127a1261d56abbcb7562c297eec8e4fc078fb" } } }; From ff0ce2b69a16bf2fa7c39bf2bafec0a2199c53d6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 02:08:21 -0400 Subject: [PATCH 119/220] Fix warning --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 20d4a0355..c75f51a28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1327,7 +1327,7 @@ bool ContextualCheckTransaction(int32_t slowflag,const CBlock *block, CBlockInde )) { librustzcash_sapling_verification_ctx_free(ctx); - fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%d\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); + fprintf(stderr,"%s: Invalid sapling binding sig! tx=%s valueBalance=%li, bindingSig.size=%li\n", __func__, tx.GetHash().ToString().c_str(), tx.valueBalance, tx.bindingSig.size() ); return state.DoS(100, error("ContextualCheckTransaction(): Sapling binding signature invalid"), REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid"); } From 9c5a4e682e67b08153a998072a8f20d69fd60f3f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 23:10:05 -0400 Subject: [PATCH 120/220] desprout --- src/wallet/wallet.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8d56fdfae..4422cde7b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2105,27 +2105,6 @@ void CWallet::GetSproutNoteWitnesses(std::vector notes, std::vector>& witnesses, uint256 &final_anchor) { - LOCK(cs_wallet); - witnesses.resize(notes.size()); - boost::optional rt; - int i = 0; - for (JSOutPoint note : notes) { - if (mapWallet.count(note.hash) && - mapWallet[note.hash].mapSproutNoteData.count(note) && - mapWallet[note.hash].mapSproutNoteData[note].witnesses.size() > 0) { - witnesses[i] = mapWallet[note.hash].mapSproutNoteData[note].witnesses.front(); - if (!rt) { - rt = witnesses[i]->root(); - } else { - assert(*rt == witnesses[i]->root()); - } - } - i++; - } - // All returned witnesses have the same anchor - if (rt) { - final_anchor = *rt; - } } void CWallet::GetSaplingNoteWitnesses(std::vector notes, From e35b7e21b3cf64acbd671edd8d2ca7e12cdd5952 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 23:13:15 -0400 Subject: [PATCH 121/220] Less typing is nice --- build.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..2ae8514c3 --- /dev/null +++ b/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# Copyright (c) 2019-2020 The Hush developers + +set -eu -o pipefail +./zcutil/build.sh $@ From 1010c7e8e453032710519d741d578bbace3586d7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 23:32:41 -0400 Subject: [PATCH 122/220] Throw a logic error instead of asserting when we see weird witness shenanigans --- src/wallet/wallet.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4422cde7b..3145bbd88 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2123,7 +2123,12 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, if (!rt) { rt = witnesses[i]->root(); } else { - assert(*rt == witnesses[i]->root()); + if(*rt == witnesses[i]->root()) { + // Something is fucky + std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root:" << rt.GetHash(); + throw std::logic_error(err); + } + } } i++; From d265f782e77e8e262dc668372a32d4f79af9ef45 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 23:35:11 -0400 Subject: [PATCH 123/220] desprout --- src/wallet/wallet.cpp | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3145bbd88..558f2020a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -234,25 +234,7 @@ bool CWallet::AddSaplingIncomingViewingKey( // Add spending key to keystore and persist to disk bool CWallet::AddSproutZKey(const libzcash::SproutSpendingKey &key) { - AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata - auto addr = key.address(); - - if (!CCryptoKeyStore::AddSproutSpendingKey(key)) - return false; - - // check if we need to remove from viewing keys - if (HaveSproutViewingKey(addr)) - RemoveSproutViewingKey(key.viewing_key()); - - if (!fFileBacked) - return true; - - if (!IsCrypted()) { - return CWalletDB(strWalletFile).WriteZKey(addr, - key, - mapSproutZKeyMetadata[addr]); - } - return true; + return false; } CPubKey CWallet::GenerateNewKey() @@ -2344,13 +2326,6 @@ bool CWallet::IsFromMe(const CTransaction& tx) const if (GetDebit(tx, ISMINE_ALL) > 0) { return true; } - for (const JSDescription& jsdesc : tx.vjoinsplit) { - for (const uint256& nullifier : jsdesc.nullifiers) { - if (IsSproutNullifierFromMe(nullifier)) { - return true; - } - } - } for (const SpendDescription &spend : tx.vShieldedSpend) { if (IsSaplingNullifierFromMe(spend.nullifier)) { return true; @@ -2488,18 +2463,6 @@ bool CWallet::LoadCryptedHDSeed(const uint256& seedFp, const std::vector nd : noteData) { - if (nd.first.js < vjoinsplit.size() && - nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) { - // Store the address and nullifier for the Note - mapSproutNoteData[nd.first] = nd.second; - } else { - // If FindMySproutNotes() was used to obtain noteData, - // this should never happen - throw std::logic_error("CWalletTx::SetSproutNoteData(): Invalid note"); - } - } } void CWalletTx::SetSaplingNoteData(mapSaplingNoteData_t ¬eData) From ab0576a72e80c3ba2f9c0411ec69ca98d30504ee Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 29 May 2020 23:47:28 -0400 Subject: [PATCH 124/220] desprout --- src/wallet/wallet.cpp | 76 +------------------------------------------ src/wallet/wallet.h | 11 ------- 2 files changed, 1 insertion(+), 86 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 558f2020a..a455cc2fe 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -117,22 +117,7 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const // Generate a new spending key and return its public payment address libzcash::SproutPaymentAddress CWallet::GenerateNewSproutZKey() { - AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata - - auto k = SproutSpendingKey::random(); - auto addr = k.address(); - - // Check for collision, even though it is unlikely to ever occur - if (CCryptoKeyStore::HaveSproutSpendingKey(addr)) - throw std::runtime_error("CWallet::GenerateNewSproutZKey(): Collision detected"); - - // Create new metadata - int64_t nCreationTime = GetTime(); - mapSproutZKeyMetadata[addr] = CKeyMetadata(nCreationTime); - - if (!AddSproutZKey(k)) - throw std::runtime_error("CWallet::GenerateNewSproutZKey(): AddSproutZKey failed"); - return addr; + throw std::runtime_error("unsupported"); } // Generate a new Sapling spending key and return its public payment address @@ -313,24 +298,6 @@ bool CWallet::AddCryptedSproutSpendingKey( const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { - if (!CCryptoKeyStore::AddCryptedSproutSpendingKey(address, rk, vchCryptedSecret)) - return false; - if (!fFileBacked) - return true; - { - LOCK(cs_wallet); - if (pwalletdbEncryption) { - return pwalletdbEncryption->WriteCryptedZKey(address, - rk, - vchCryptedSecret, - mapSproutZKeyMetadata[address]); - } else { - return CWalletDB(strWalletFile).WriteCryptedZKey(address, - rk, - vchCryptedSecret, - mapSproutZKeyMetadata[address]); - } - } return false; } @@ -415,47 +382,6 @@ bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key) return CCryptoKeyStore::AddSproutSpendingKey(key); } -bool CWallet::AddSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - if (!CCryptoKeyStore::AddSproutViewingKey(vk)) { - return false; - } - nTimeFirstKey = 1; // No birthday information for viewing keys. - if (!fFileBacked) { - return true; - } - return CWalletDB(strWalletFile).WriteSproutViewingKey(vk); -} - -bool CWallet::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - AssertLockHeld(cs_wallet); - if (!CCryptoKeyStore::RemoveSproutViewingKey(vk)) { - return false; - } - if (fFileBacked) { - if (!CWalletDB(strWalletFile).EraseSproutViewingKey(vk)) { - return false; - } - } - - return true; -} - -bool CWallet::LoadSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - return CCryptoKeyStore::AddSproutViewingKey(vk); -} - -bool CWallet::AddCScript(const CScript& redeemScript) -{ - if (!CCryptoKeyStore::AddCScript(redeemScript)) - return false; - if (!fFileBacked) - return true; - return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); -} - bool CWallet::LoadCScript(const CScript& redeemScript) { /* A sanity check was added in pull #3843 to avoid adding redeemScripts diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 205a49008..1c46f3f98 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1111,17 +1111,6 @@ public: bool LoadZKeyMetadata(const libzcash::SproutPaymentAddress &addr, const CKeyMetadata &meta); //! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet) bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); - //! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h) - bool AddCryptedSproutSpendingKey( - const libzcash::SproutPaymentAddress &address, - const libzcash::ReceivingKey &rk, - const std::vector &vchCryptedSecret); - - //! Adds a Sprout viewing key to the store, and saves it to disk. - bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk); - bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk); - //! Adds a Sprout viewing key to the store, without saving it to disk (used by LoadWallet) - bool LoadSproutViewingKey(const libzcash::SproutViewingKey &dest); /** * Sapling ZKeys From eec2dd51fba8ee8db30055fc55786df9fc3829f2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 30 May 2020 00:44:20 -0400 Subject: [PATCH 125/220] wallet desprout --- src/wallet/wallet.cpp | 291 +----------------------------------------- src/wallet/wallet.h | 37 ------ 2 files changed, 4 insertions(+), 324 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a455cc2fe..d0d82a0e8 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -114,11 +114,6 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const return &(it->second); } -// Generate a new spending key and return its public payment address -libzcash::SproutPaymentAddress CWallet::GenerateNewSproutZKey() -{ - throw std::runtime_error("unsupported"); -} // Generate a new Sapling spending key and return its public payment address SaplingPaymentAddress CWallet::GenerateNewSaplingZKey() @@ -216,12 +211,6 @@ bool CWallet::AddSaplingIncomingViewingKey( } -// Add spending key to keystore and persist to disk -bool CWallet::AddSproutZKey(const libzcash::SproutSpendingKey &key) -{ - return false; -} - CPubKey CWallet::GenerateNewKey() { AssertLockHeld(cs_wallet); // mapKeyMetadata @@ -292,15 +281,6 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, return false; } - -bool CWallet::AddCryptedSproutSpendingKey( - const libzcash::SproutPaymentAddress &address, - const libzcash::ReceivingKey &rk, - const std::vector &vchCryptedSecret) -{ - return false; -} - bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, const libzcash::SaplingPaymentAddress &defaultAddr) @@ -589,29 +569,6 @@ std::set> CWallet::GetNullifiersFor return nullifierSet; } -bool CWallet::IsNoteSproutChange( - const std::set> & nullifierSet, - const PaymentAddress & address, - const JSOutPoint & jsop) -{ - // A Note is marked as "change" if the address that received it - // also spent Notes in the same transaction. This will catch, - // for instance: - // - Change created by spending fractions of Notes (because - // z_sendmany sends change to the originating z-address). - // - "Chaining Notes" used to connect JoinSplits together. - // - Notes created by consolidation transactions (e.g. using - // z_mergetoaddress). - // - Notes sent from one address to itself. - for (const JSDescription & jsd : mapWallet[jsop.hash].vjoinsplit) { - for (const uint256 & nullifier : jsd.nullifiers) { - if (nullifierSet.count(std::make_pair(address, nullifier))) { - return true; - } - } - } - return false; -} bool CWallet::IsNoteSaplingChange(const std::set> & nullifierSet, const libzcash::PaymentAddress & address, @@ -849,38 +806,6 @@ unsigned int CWallet::GetSpendDepth(const uint256& hash, unsigned int n) const return 0; } -/** - * Note is spent if any non-conflicted transaction - * spends it: - */ -bool CWallet::IsSproutSpent(const uint256& nullifier) const { - pair range; - range = mapTxSproutNullifiers.equal_range(nullifier); - - for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) { - const uint256& wtxid = it->second; - std::map::const_iterator mit = mapWallet.find(wtxid); - if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) { - return true; // Spent - } - } - return false; -} - -unsigned int CWallet::GetSproutSpendDepth(const uint256& nullifier) const { - pair range; - range = mapTxSproutNullifiers.equal_range(nullifier); - - for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) { - const uint256& wtxid = it->second; - std::map::const_iterator mit = mapWallet.find(wtxid); - if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) { - return mit->second.GetDepthInMainChain(); // Spent - } - } - return 0; -} - bool CWallet::IsSaplingSpent(const uint256& nullifier) const { pair range; range = mapTxSaplingNullifiers.equal_range(nullifier); @@ -918,15 +843,6 @@ void CWallet::AddToTransparentSpends(const COutPoint& outpoint, const uint256& w SyncMetaData(range); } -void CWallet::AddToSproutSpends(const uint256& nullifier, const uint256& wtxid) -{ - mapTxSproutNullifiers.insert(make_pair(nullifier, wtxid)); - - pair range; - range = mapTxSproutNullifiers.equal_range(nullifier); - SyncMetaData(range); -} - void CWallet::AddToSaplingSpends(const uint256& nullifier, const uint256& wtxid) { mapTxSaplingNullifiers.insert(make_pair(nullifier, wtxid)); @@ -946,11 +862,6 @@ void CWallet::AddToSpends(const uint256& wtxid) for (const CTxIn& txin : thisTx.vin) { AddToTransparentSpends(txin.prevout, wtxid); } - for (const JSDescription& jsdesc : thisTx.vjoinsplit) { - for (const uint256& nullifier : jsdesc.nullifiers) { - AddToSproutSpends(nullifier, wtxid); - } - } for (const SpendDescription &spend : thisTx.vShieldedSpend) { AddToSaplingSpends(spend.nullifier, wtxid); } @@ -1006,21 +917,6 @@ void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex) extern int32_t KOMODO_REWIND; for (std::pair& wtxItem : mapWallet) { - //Sprout - for (auto& item : wtxItem.second.mapSproutNoteData) { - auto* nd = &(item.second); - if (nd->nullifier && pwalletMain->GetSproutSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { - // Only decrement witnesses that are not above the current height - if (nd->witnessHeight <= pindex->GetHeight()) { - if (nd->witnesses.size() > 1) { - // indexHeight is the height of the block being removed, so - // the new witness cache height is one below it. - nd->witnesses.pop_front(); - nd->witnessHeight = pindex->GetHeight() - 1; - } - } - } - } //Sapling for (auto& item : wtxItem.second.mapSaplingNoteData) { auto* nd = &(item.second); @@ -1048,14 +944,6 @@ void ClearSingleNoteWitnessCache(NoteData* nd) nd->witnessRootValidated = false; } -int CWallet::SproutWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight) -{ - if (GetSproutSpendDepth(nullifier) <= WITNESS_CACHE_SIZE) { - nMinimumHeight = min(nWitnessHeight, nMinimumHeight); - } - return nMinimumHeight; -} - int CWallet::SaplingWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight) { if (GetSaplingSpendDepth(nullifier) <= WITNESS_CACHE_SIZE) { @@ -1396,22 +1284,6 @@ bool CWallet::UpdateNullifierNoteMap() ZCNoteDecryption dec; for (std::pair& wtxItem : mapWallet) { - for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { - if (!item.second.nullifier) { - if (GetNoteDecryptor(item.second.address, dec)) { - auto i = item.first.js; - auto hSig = wtxItem.second.vjoinsplit[i].h_sig( - *pzcashParams, wtxItem.second.joinSplitPubKey); - item.second.nullifier = GetSproutNoteNullifier( - wtxItem.second.vjoinsplit[i], - item.second.address, - dec, - hSig, - item.first.n); - } - } - } - // TODO: Sapling. This method is only called from RPC walletpassphrase, which is currently unsupported // as RPC encryptwallet is hidden behind two flags: -developerencryptwallet -experimentalfeatures @@ -1422,7 +1294,7 @@ bool CWallet::UpdateNullifierNoteMap() } /** - * Update mapSproutNullifiersToNotes and mapSaplingNullifiersToNotes + * Update mapSaplingNullifiersToNotes * with the cached nullifiers in this tx. */ void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx) @@ -1438,48 +1310,6 @@ void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx) } } -/** - * Update mapSproutNullifiersToNotes, computing the nullifier from a cached witness if necessary. - */ -void CWallet::UpdateSproutNullifierNoteMapWithTx(CWalletTx& wtx) { - LOCK(cs_wallet); - - ZCNoteDecryption dec; - for (mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) { - SproutNoteData nd = item.second; - - if (nd.witnesses.empty()) { - // If there are no witnesses, erase the nullifier and associated mapping. - if (nd.nullifier) { - mapSproutNullifiersToNotes.erase(nd.nullifier.get()); - } - nd.nullifier = boost::none; - } - else { - if (GetNoteDecryptor(nd.address, dec)) { - auto i = item.first.js; - auto hSig = wtx.vjoinsplit[i].h_sig( - *pzcashParams, wtx.joinSplitPubKey); - auto optNullifier = GetSproutNoteNullifier( - wtx.vjoinsplit[i], - item.second.address, - dec, - hSig, - item.first.n); - - if (!optNullifier) { - // This should not happen. If it does, maybe the position has been corrupted or miscalculated? - assert(false); - } - - uint256 nullifier = optNullifier.get(); - mapSproutNullifiersToNotes[nullifier] = item.first; - item.second.nullifier = nullifier; - } - } - } -} - /** * Update mapSaplingNullifiersToNotes, computing the nullifier from a cached witness if necessary. */ @@ -1577,6 +1407,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD int64_t latestEntry = 0; { // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future + // TODO: this is 2 blocktimes, which will become 150? int64_t latestTolerated = latestNow + 300; std::list acentries; TxItems txOrdered = OrderedTxItems(acentries); @@ -1670,21 +1501,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx) { - bool unchangedSproutFlag = (wtxIn.mapSproutNoteData.empty() || wtxIn.mapSproutNoteData == wtx.mapSproutNoteData); - if (!unchangedSproutFlag) { - auto tmp = wtxIn.mapSproutNoteData; - // Ensure we keep any cached witnesses we may already have - for (const std::pair nd : wtx.mapSproutNoteData) { - if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) { - tmp.at(nd.first).witnesses.assign( - nd.second.witnesses.cbegin(), nd.second.witnesses.cend()); - } - tmp.at(nd.first).witnessHeight = nd.second.witnessHeight; - } - // Now copy over the updated note data - wtx.mapSproutNoteData = tmp; - } - bool unchangedSaplingFlag = (wtxIn.mapSaplingNoteData.empty() || wtxIn.mapSaplingNoteData == wtx.mapSaplingNoteData); if (!unchangedSaplingFlag) { auto tmp = wtxIn.mapSaplingNoteData; @@ -1702,7 +1518,7 @@ bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx) wtx.mapSaplingNoteData = tmp; } - return !unchangedSproutFlag || !unchangedSaplingFlag; + return !unchangedSaplingFlag; } /** @@ -1719,7 +1535,6 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl return false; bool fExisted = mapWallet.count(tx.GetHash()) != 0; if (fExisted && !fUpdate) return false; - auto sproutNoteData = FindMySproutNotes(tx); auto saplingNoteDataAndAddressesToAdd = FindMySaplingNotes(tx); auto saplingNoteData = saplingNoteDataAndAddressesToAdd.first; auto addressesToAdd = saplingNoteDataAndAddressesToAdd.second; @@ -1743,7 +1558,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl fprintf(stderr, " %s\n", wladdr.c_str()); } } - if (fExisted || IsMine(tx) || IsFromMe(tx) || sproutNoteData.size() > 0 || saplingNoteData.size() > 0) + if (fExisted || IsMine(tx) || IsFromMe(tx) || saplingNoteData.size() > 0) { // wallet filter for notary nodes. Enables by setting -whitelistaddress= as startup param or in conf file (works same as -addnode byut with R-address's) if ( !tx.IsCoinBase() && !vWhiteListAddress.empty() && !NotaryAddress.empty() ) @@ -1775,10 +1590,6 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl CWalletTx wtx(this,tx); - if (sproutNoteData.size() > 0) { - wtx.SetSproutNoteData(sproutNoteData); - } - if (saplingNoteData.size() > 0) { wtx.SetSaplingNoteData(saplingNoteData); } @@ -1850,82 +1661,6 @@ void CWallet::RescanWallet() } -/** - * Returns a nullifier if the SpendingKey is available - * Throws std::runtime_error if the decryptor doesn't match this note - */ -boost::optional CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc, - const libzcash::SproutPaymentAddress &address, - const ZCNoteDecryption &dec, - const uint256 &hSig, - uint8_t n) const -{ - boost::optional ret; - auto note_pt = libzcash::SproutNotePlaintext::decrypt( - dec, - jsdesc.ciphertexts[n], - jsdesc.ephemeralKey, - hSig, - (unsigned char) n); - auto note = note_pt.note(address); - // SpendingKeys are only available if: - // - We have them (this isn't a viewing key) - // - The wallet is unlocked - libzcash::SproutSpendingKey key; - if (GetSproutSpendingKey(address, key)) { - ret = note.nullifier(key); - } - return ret; -} - -/** - * Finds all output notes in the given transaction that have been sent to - * PaymentAddresses in this wallet. - * - * It should never be necessary to call this method with a CWalletTx, because - * the result of FindMySproutNotes (for the addresses available at the time) will - * already have been cached in CWalletTx.mapSproutNoteData. - */ -mapSproutNoteData_t CWallet::FindMySproutNotes(const CTransaction &tx) const -{ - LOCK(cs_SpendingKeyStore); - uint256 hash = tx.GetHash(); - - mapSproutNoteData_t noteData; - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey); - for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) { - for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) { - try { - auto address = item.first; - JSOutPoint jsoutpt {hash, i, j}; - auto nullifier = GetSproutNoteNullifier( - tx.vjoinsplit[i], - address, - item.second, - hSig, j); - if (nullifier) { - SproutNoteData nd {address, *nullifier}; - noteData.insert(std::make_pair(jsoutpt, nd)); - } else { - SproutNoteData nd {address}; - noteData.insert(std::make_pair(jsoutpt, nd)); - } - break; - } catch (const note_decryption_failed &err) { - // Couldn't decrypt with this decryptor - } catch (const std::exception &exc) { - // Unexpected failure - LogPrintf("FindMySproutNotes(): Unexpected error while testing decrypt:\n"); - LogPrintf("%s\n", exc.what()); - } - } - } - } - return noteData; -} - - /** * Finds all output notes in the given transaction that have been sent to * SaplingPaymentAddresses in this wallet. @@ -1985,18 +1720,6 @@ std::pair CWallet::FindMySap return std::make_pair(noteData, viewingKeysToAdd); } -bool CWallet::IsSproutNullifierFromMe(const uint256& nullifier) const -{ - { - LOCK(cs_wallet); - if (mapSproutNullifiersToNotes.count(nullifier) && - mapWallet.count(mapSproutNullifiersToNotes.at(nullifier).hash)) { - return true; - } - } - return false; -} - bool CWallet::IsSaplingNullifierFromMe(const uint256& nullifier) const { { @@ -2009,12 +1732,6 @@ bool CWallet::IsSaplingNullifierFromMe(const uint256& nullifier) const return false; } -void CWallet::GetSproutNoteWitnesses(std::vector notes, - std::vector>& witnesses, - uint256 &final_anchor) -{ -} - void CWallet::GetSaplingNoteWitnesses(std::vector notes, std::vector>& witnesses, uint256 &final_anchor) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1c46f3f98..d82e100ed 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -589,11 +589,8 @@ public: MarkDirty(); } - void SetSproutNoteData(mapSproutNoteData_t ¬eData); void SetSaplingNoteData(mapSaplingNoteData_t ¬eData); - std::pair DecryptSproutNote( - JSOutPoint jsop) const; boost::optional> DecryptSaplingNote(SaplingOutPoint op) const; @@ -801,14 +798,12 @@ private: * detect and report conflicts (double-spends). */ typedef TxSpendMap TxNullifiers; - TxNullifiers mapTxSproutNullifiers; TxNullifiers mapTxSaplingNullifiers; std::vector pendingSaplingConsolidationTxs; AsyncRPCOperationId saplingConsolidationOperationId; void AddToTransparentSpends(const COutPoint& outpoint, const uint256& wtxid); - void AddToSproutSpends(const uint256& nullifier, const uint256& wtxid); void AddToSaplingSpends(const uint256& nullifier, const uint256& wtxid); void AddToSpends(const uint256& wtxid); @@ -915,7 +910,6 @@ public: std::set setKeyPool; std::map mapKeyMetadata; - std::map mapSproutZKeyMetadata; std::map mapSaplingZKeyMetadata; typedef std::map MasterKeyMap; @@ -1033,8 +1027,6 @@ public: bool IsSpent(const uint256& hash, unsigned int n) const; unsigned int GetSpendDepth(const uint256& hash, unsigned int n) const; - bool IsSproutSpent(const uint256& nullifier) const; - unsigned int GetSproutSpendDepth(const uint256& nullifier) const; bool IsSaplingSpent(const uint256& nullifier) const; unsigned int GetSaplingSpendDepth(const uint256& nullifier) const; @@ -1047,8 +1039,6 @@ public: bool IsLockedNote(const JSOutPoint& outpt) const; void LockNote(const JSOutPoint& output); void UnlockNote(const JSOutPoint& output); - void UnlockAllSproutNotes(); - std::vector ListLockedSproutNotes(); bool IsLockedNote(const SaplingOutPoint& output) const; void LockNote(const SaplingOutPoint& output); @@ -1098,20 +1088,6 @@ public: void GetKeyBirthTimes(std::map &mapKeyBirth) const; - /** - * Sprout ZKeys - */ - //! Generates a new Sprout zaddr - libzcash::SproutPaymentAddress GenerateNewSproutZKey(); - //! Adds spending key to the store, and saves it to disk - bool AddSproutZKey(const libzcash::SproutSpendingKey &key); - //! Adds spending key to the store, without saving it to disk (used by LoadWallet) - bool LoadZKey(const libzcash::SproutSpendingKey &key); - //! Load spending key metadata (used by LoadWallet) - bool LoadZKeyMetadata(const libzcash::SproutPaymentAddress &addr, const CKeyMetadata &meta); - //! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet) - bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); - /** * Sapling ZKeys */ @@ -1160,7 +1136,6 @@ public: void MarkDirty(); bool UpdateNullifierNoteMap(); void UpdateNullifierNoteMapWithTx(const CWalletTx& wtx); - void UpdateSproutNullifierNoteMapWithTx(CWalletTx& wtx); void UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx); void UpdateNullifierNoteMapForBlock(const CBlock* pblock); bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); @@ -1208,21 +1183,9 @@ public: std::set GetAccountAddresses(const std::string& strAccount) const; - boost::optional GetSproutNoteNullifier( - const JSDescription& jsdesc, - const libzcash::SproutPaymentAddress& address, - const ZCNoteDecryption& dec, - const uint256& hSig, - uint8_t n) const; - mapSproutNoteData_t FindMySproutNotes(const CTransaction& tx) const; std::pair FindMySaplingNotes(const CTransaction& tx) const; - bool IsSproutNullifierFromMe(const uint256& nullifier) const; bool IsSaplingNullifierFromMe(const uint256& nullifier) const; - void GetSproutNoteWitnesses( - std::vector notes, - std::vector>& witnesses, - uint256 &final_anchor); void GetSaplingNoteWitnesses( std::vector notes, std::vector>& witnesses, From c27264eb0ff0f4c29c828146f5dd3d704df256a8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 1 Jun 2020 01:42:19 -0400 Subject: [PATCH 126/220] desprout --- .../asyncrpcoperation_mergetoaddress.cpp | 336 +----------------- src/zcbenchmarks.cpp | 177 --------- 2 files changed, 2 insertions(+), 511 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 2e77195f3..488e7f5b7 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -430,6 +430,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() */ + UniValue obj(UniValue::VOBJ); + /** * SCENARIO #1 * @@ -438,7 +440,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * There are no zaddrs or joinsplits involved. */ if (isPureTaddrOnlyTx) { - UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); sign_send_raw_transaction(obj); return true; @@ -447,335 +448,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * END SCENARIO #1 */ - - // Prepare raw transaction to handle JoinSplits - CMutableTransaction mtx(tx_); - crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); - mtx.joinSplitPubKey = joinSplitPubKey_; - tx_ = CTransaction(mtx); - std::string hexMemo = std::get<1>(recipient_); - - - /** - * SCENARIO #2 - * - * taddrs -> zaddr - * - * We only need a single JoinSplit. - */ - if (sproutNoteInputs_.empty() && isToZaddr_) { - // Create JoinSplit to target z-addr. - MergeToAddressJSInfo info; - info.vpub_old = sendAmount; - info.vpub_new = 0; - - JSOutput jso = JSOutput(boost::get(toPaymentAddress_), sendAmount); - if (hexMemo.size() > 0) { - jso.memo = get_memo_from_hex_string(hexMemo); - } - info.vjsout.push_back(jso); - - UniValue obj(UniValue::VOBJ); - obj = perform_joinsplit(info); - sign_send_raw_transaction(obj); - return true; - } - /** - * END SCENARIO #2 - */ - - - // Copy zinputs to more flexible containers - std::deque zInputsDeque; - for (const auto& o : sproutNoteInputs_) { - zInputsDeque.push_back(o); - } - - // When spending notes, take a snapshot of note witnesses and anchors as the treestate will - // change upon arrival of new blocks which contain joinsplit transactions. This is likely - // to happen as creating a chained joinsplit transaction can take longer than the block interval. - { - LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto t : sproutNoteInputs_) { - JSOutPoint jso = std::get<0>(t); - std::vector vOutPoints = {jso}; - uint256 inputAnchor; - std::vector> vInputWitnesses; - pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); - jsopWitnessAnchorMap[jso.ToString()] = MergeToAddressWitnessAnchorData{vInputWitnesses[0], inputAnchor}; - } - } - - /** - * SCENARIO #3 - * - * zaddrs -> zaddr - * taddrs -> - * - * zaddrs -> - * taddrs -> taddr - * - * Send to zaddr by chaining JoinSplits together and immediately consuming any change - * Send to taddr by creating dummy z outputs and accumulating value in a change note - * which is used to set vpub_new in the last chained joinsplit. - */ - UniValue obj(UniValue::VOBJ); - CAmount jsChange = 0; // this is updated after each joinsplit - int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 - bool vpubOldProcessed = false; // updated when vpub_old for taddr inputs is set in first joinsplit - bool vpubNewProcessed = false; // updated when vpub_new for miner fee and taddr outputs is set in last joinsplit - - // At this point, we are guaranteed to have at least one input note. - // Use address of first input note as the temporary change address. - SproutSpendingKey changeKey = std::get<3>(zInputsDeque.front()); - SproutPaymentAddress changeAddress = changeKey.address(); - - CAmount vpubOldTarget = 0; - CAmount vpubNewTarget = 0; - if (isToTaddr_) { - vpubNewTarget = z_inputs_total; - } else { - if (utxoInputs_.empty()) { - vpubNewTarget = minersFee; - } else { - vpubOldTarget = t_inputs_total - minersFee; - } - } - - // Keep track of treestate within this transaction - boost::unordered_map intermediates; - std::vector previousCommitments; - - while (!vpubNewProcessed) { - MergeToAddressJSInfo info; - info.vpub_old = 0; - info.vpub_new = 0; - - // Set vpub_old in the first joinsplit - if (!vpubOldProcessed) { - if (t_inputs_total < vpubOldTarget) { - throw JSONRPCError(RPC_WALLET_ERROR, - strprintf("Insufficient transparent funds for vpub_old %s (miners fee %s, taddr inputs %s)", - FormatMoney(vpubOldTarget), FormatMoney(minersFee), FormatMoney(t_inputs_total))); - } - info.vpub_old += vpubOldTarget; // funds flowing from public pool - vpubOldProcessed = true; - } - - CAmount jsInputValue = 0; - uint256 jsAnchor; - std::vector> witnesses; - - JSDescription prevJoinSplit; - - // Keep track of previous JoinSplit and its commitments - if (tx_.vjoinsplit.size() > 0) { - prevJoinSplit = tx_.vjoinsplit.back(); - } - - // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange == 0 && tx_.vjoinsplit.size() > 0) { - intermediates.clear(); - previousCommitments.clear(); - } - - // - // Consume change as the first input of the JoinSplit. - // - if (jsChange > 0) { - LOCK2(cs_main, pwalletMain->cs_wallet); - - // Update tree state with previous joinsplit - SproutMerkleTree tree; - auto it = intermediates.find(prevJoinSplit.anchor); - if (it != intermediates.end()) { - tree = it->second; - } else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); - } - - assert(changeOutputIndex != -1); - boost::optional changeWitness; - int n = 0; - for (const uint256& commitment : prevJoinSplit.commitments) { - tree.append(commitment); - previousCommitments.push_back(commitment); - if (!changeWitness && changeOutputIndex == n++) { - changeWitness = tree.witness(); - } else if (changeWitness) { - changeWitness.get().append(commitment); - } - } - if (changeWitness) { - witnesses.push_back(changeWitness); - } - jsAnchor = tree.root(); - intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) - - // Decrypt the change note's ciphertext to retrieve some data we need - ZCNoteDecryption decryptor(changeKey.receiving_key()); - auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); - try { - SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( - decryptor, - prevJoinSplit.ciphertexts[changeOutputIndex], - prevJoinSplit.ephemeralKey, - hSig, - (unsigned char)changeOutputIndex); - - SproutNote note = plaintext.note(changeAddress); - info.notes.push_back(note); - info.zkeys.push_back(changeKey); - - jsInputValue += plaintext.value(); - - LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", - getId(), - FormatMoney(plaintext.value())); - - } catch (const std::exception& e) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); - } - } - - - // - // Consume spendable non-change notes - // - std::vector vInputNotes; - std::vector vInputZKeys; - std::vector vOutPoints; - std::vector> vInputWitnesses; - uint256 inputAnchor; - int numInputsNeeded = (jsChange > 0) ? 1 : 0; - while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { - MergeToAddressInputSproutNote t = zInputsDeque.front(); - JSOutPoint jso = std::get<0>(t); - SproutNote note = std::get<1>(t); - CAmount noteFunds = std::get<2>(t); - SproutSpendingKey zkey = std::get<3>(t); - zInputsDeque.pop_front(); - - MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()]; - vInputWitnesses.push_back(wad.witness); - if (inputAnchor.IsNull()) { - inputAnchor = wad.anchor; - } else if (inputAnchor != wad.anchor) { - throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); - } - - vOutPoints.push_back(jso); - vInputNotes.push_back(note); - vInputZKeys.push_back(zkey); - - jsInputValue += noteFunds; - - int wtxHeight = -1; - int wtxDepth = -1; - { - LOCK2(cs_main, pwalletMain->cs_wallet); - const CWalletTx& wtx = pwalletMain->mapWallet[jso.hash]; - // Zero confirmation notes belong to transactions which have not yet been mined - if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); - } - wtxHeight = komodo_blockheight(wtx.hashBlock); - wtxDepth = wtx.GetDepthInMainChain(); - } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", - getId(), - jso.hash.ToString().substr(0, 10), - jso.js, - int(jso.n), // uint8_t - FormatMoney(noteFunds), - wtxHeight, - wtxDepth); - } - - // Add history of previous commitments to witness - if (vInputNotes.size() > 0) { - if (vInputWitnesses.size() == 0) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); - } - - for (auto& optionalWitness : vInputWitnesses) { - if (!optionalWitness) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); - } - SproutWitness w = *optionalWitness; // could use .get(); - if (jsChange > 0) { - for (const uint256& commitment : previousCommitments) { - w.append(commitment); - } - if (jsAnchor != w.root()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for spendable note does not have same anchor as change input"); - } - } - witnesses.push_back(w); - } - - // The jsAnchor is null if this JoinSplit is at the start of a new chain - if (jsAnchor.IsNull()) { - jsAnchor = inputAnchor; - } - - // Add spendable notes as inputs - std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); - std::copy(vInputZKeys.begin(), vInputZKeys.end(), std::back_inserter(info.zkeys)); - } - - // Accumulate change - jsChange = jsInputValue + info.vpub_old; - - // Set vpub_new in the last joinsplit (when there are no more notes to spend) - if (zInputsDeque.empty()) { - assert(!vpubNewProcessed); - if (jsInputValue < vpubNewTarget) { - throw JSONRPCError(RPC_WALLET_ERROR, - strprintf("Insufficient funds for vpub_new %s (miners fee %s, taddr inputs %s)", - FormatMoney(vpubNewTarget), FormatMoney(minersFee), FormatMoney(t_inputs_total))); - } - info.vpub_new += vpubNewTarget; // funds flowing back to public pool - vpubNewProcessed = true; - jsChange -= vpubNewTarget; - // If we are merging to a t-addr, there should be no change - if (isToTaddr_) assert(jsChange == 0); - } - - // create dummy output - info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new - - // create output for any change - if (jsChange > 0) { - std::string outputType = "change"; - auto jso = JSOutput(changeAddress, jsChange); - // If this is the final output, set the target and memo - if (isToZaddr_ && vpubNewProcessed) { - outputType = "target"; - jso.addr = boost::get(toPaymentAddress_); - if (!hexMemo.empty()) { - jso.memo = get_memo_from_hex_string(hexMemo); - } - } - info.vjsout.push_back(jso); - - LogPrint("zrpcunsafe", "%s: generating note for %s (amount=%s)\n", - getId(), - outputType, - FormatMoney(jsChange)); - } - - obj = perform_joinsplit(info, witnesses, jsAnchor); - - if (jsChange > 0) { - changeOutputIndex = mta_find_output(obj, 1); - } - } - - // Sanity check in case changes to code block above exits loop by invoking 'break' - assert(zInputsDeque.size() == 0); - assert(vpubNewProcessed); - sign_send_raw_transaction(obj); return true; } @@ -866,10 +538,6 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf { std::vector> witnesses; uint256 anchor; - { - LOCK(cs_main); - pwalletMain->GetSproutNoteWitnesses(outPoints, witnesses, anchor); - } return perform_joinsplit(info, witnesses, anchor); } diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 2f79e454b..9af3c184a 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -93,29 +93,6 @@ double benchmark_sleep() return timer_stop(tv_start); } -double benchmark_create_joinsplit() -{ - uint256 joinSplitPubKey; - - /* Get the anchor of an empty commitment tree. */ - uint256 anchor = SproutMerkleTree().root(); - - struct timeval tv_start; - timer_start(tv_start); - JSDescription jsdesc(*pzcashParams, - joinSplitPubKey, - anchor, - {JSInput(), JSInput()}, - {JSOutput(), JSOutput()}, - 0, - 0); - double ret = timer_stop(tv_start); - - auto verifier = libzcash::ProofVerifier::Strict(); - assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey)); - return ret; -} - std::vector benchmark_create_joinsplit_threaded(int nThreads) { std::vector ret; @@ -263,160 +240,6 @@ double benchmark_large_tx(size_t nInputs) return timer_stop(tv_start); } -double benchmark_try_decrypt_notes(size_t nAddrs) -{ - CWallet wallet; - for (int i = 0; i < nAddrs; i++) { - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - } - - auto sk = libzcash::SproutSpendingKey::random(); - auto tx = GetValidReceive(*pzcashParams, sk, 10, true); - - struct timeval tv_start; - timer_start(tv_start); - auto nd = wallet.FindMySproutNotes(tx); - return timer_stop(tv_start); -} - -double benchmark_increment_note_witnesses(size_t nTxs) -{ - CWallet wallet; - SproutMerkleTree sproutTree; - SaplingMerkleTree saplingTree; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - // First block - CBlock block1; - for (int i = 0; i < nTxs; i++) { - auto wtx = GetValidReceive(*pzcashParams, sk, 10, true); - auto note = GetNote(*pzcashParams, sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - block1.vtx.push_back(wtx); - } - CBlockIndex index1(block1); - index1.SetHeight(1); - - // Increment to get transactions witnessed - wallet.ChainTip(&index1, &block1, std::make_pair(sproutTree, saplingTree)); - - // Second block - CBlock block2; - block2.hashPrevBlock = block1.GetHash(); - { - auto wtx = GetValidReceive(*pzcashParams, sk, 10, true); - auto note = GetNote(*pzcashParams, sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - block2.vtx.push_back(wtx); - } - CBlockIndex index2(block2); - index2.SetHeight(2); - - struct timeval tv_start; - timer_start(tv_start); - wallet.ChainTip(&index2, &block2, std::make_pair(sproutTree, saplingTree)); - return timer_stop(tv_start); -} - -// Fake the input of a given block -class FakeCoinsViewDB : public CCoinsViewDB { - uint256 hash; - SproutMerkleTree t; - -public: - FakeCoinsViewDB(std::string dbName, uint256& hash) : CCoinsViewDB(dbName, 100, false, false), hash(hash) {} - - bool GetAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { - if (rt == t.root()) { - tree = t; - return true; - } - return false; - } - - bool GetNullifier(const uint256 &nf, ShieldedType type) const { - return false; - } - - uint256 GetBestBlock() const { - return hash; - } - - uint256 GetBestAnchor() const { - return t.root(); - } - - bool BatchWrite(CCoinsMap &mapCoins, - const uint256 &hashBlock, - const uint256 &hashAnchor, - CAnchorsSproutMap &mapSproutAnchors, - CNullifiersMap &mapSproutNullifiers, - CNullifiersMap& mapSaplingNullifiers) { - return false; - } - - bool GetStats(CCoinsStats &stats) const { - return false; - } -}; - -double benchmark_connectblock_slow() -{ - // Test for issue 2017-05-01.a - SelectParams(CBaseChainParams::MAIN); - CBlock block; - FILE* fp = fopen((GetDataDir() / "benchmark/block-107134.dat").string().c_str(), "rb"); - if (!fp) throw new std::runtime_error("Failed to open block data file"); - CAutoFile blkFile(fp, SER_DISK, CLIENT_VERSION); - blkFile >> block; - blkFile.fclose(); - - // Fake its inputs - auto hashPrev = uint256S("00000000159a41f468e22135942a567781c3f3dc7ad62257993eb3c69c3f95ef"); - FakeCoinsViewDB fakeDB("benchmark/block-107134-inputs", hashPrev); - CCoinsViewCache view(&fakeDB); - - // Fake the chain - CBlockIndex index(block); - index.SetHeight(107134); - CBlockIndex indexPrev; - indexPrev.phashBlock = &hashPrev; - indexPrev.SetHeight(index.GetHeight() - 1); - index.pprev = &indexPrev; - mapBlockIndex.insert(std::make_pair(hashPrev, &indexPrev)); - - CValidationState state; - struct timeval tv_start; - timer_start(tv_start); - assert(ConnectBlock(block, state, &index, view, true)); - auto duration = timer_stop(tv_start); - - // Undo alterations to global state - mapBlockIndex.erase(hashPrev); - SelectParamsFromCommandLine(); - - return duration; -} - extern UniValue getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue sendtoaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); From 00bf3255eb4c39586288a4ddd95855986ce2252d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 1 Jun 2020 10:54:50 -0400 Subject: [PATCH 127/220] desprout --- .../asyncrpcoperation_mergetoaddress.cpp | 7 +- src/wallet/asyncrpcoperation_sendmany.cpp | 631 +----------------- 2 files changed, 4 insertions(+), 634 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 488e7f5b7..4dace19bb 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -429,9 +429,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * END SCENARIO #0 */ - - UniValue obj(UniValue::VOBJ); - /** * SCENARIO #1 * @@ -440,6 +437,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * There are no zaddrs or joinsplits involved. */ if (isPureTaddrOnlyTx) { + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); sign_send_raw_transaction(obj); return true; @@ -448,8 +446,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * END SCENARIO #1 */ - sign_send_raw_transaction(obj); - return true; + return false; } diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index db7f7bd66..a1ecb296d 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2016 The Zcash developers // Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -566,430 +566,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { * END SCENARIO #0 */ - - // Grab the current consensus branch ID - { - LOCK(cs_main); - consensusBranchId_ = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - } - - /** - * SCENARIO #1 - * - * taddr -> taddrs - * - * There are no zaddrs or joinsplits involved. - */ - if (isPureTaddrOnlyTx) { - add_taddr_outputs_to_tx(); - - CAmount funds = selectedUTXOAmount; - CAmount fundsSpent = t_outputs_total + minersFee; - CAmount change = funds - fundsSpent; - - if (change > 0) { - add_taddr_change_output_to_tx(0,change); - - LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", - getId(), - FormatMoney(change) - ); - } - - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); - sign_send_raw_transaction(obj); - return true; - } - /** - * END SCENARIO #1 - */ - - - // Prepare raw transaction to handle JoinSplits - CMutableTransaction mtx(tx_); - crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); - mtx.joinSplitPubKey = joinSplitPubKey_; - //if ((uint32_t)chainActive.LastTip()->nTime < ASSETCHAINS_STAKED_HF_TIMESTAMP) - if ( !hush_hardfork_active((uint32_t)chainActive.LastTip()->nTime) ) - mtx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 - else - mtx.nLockTime = (uint32_t)chainActive.Tip()->GetMedianTimePast(); - - tx_ = CTransaction(mtx); - - // Copy zinputs and zoutputs to more flexible containers - std::deque zInputsDeque; // zInputsDeque stores minimum numbers of notes for target amount - CAmount tmp = 0; - for (auto o : z_sprout_inputs_) { - zInputsDeque.push_back(o); - tmp += std::get<2>(o); - if (tmp >= targetAmount) { - break; - } - } - std::deque zOutputsDeque; - for (auto o : z_outputs_) { - zOutputsDeque.push_back(o); - } - - // When spending notes, take a snapshot of note witnesses and anchors as the treestate will - // change upon arrival of new blocks which contain joinsplit transactions. This is likely - // to happen as creating a chained joinsplit transaction can take longer than the block interval. - if (z_sprout_inputs_.size() > 0) { - LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto t : z_sprout_inputs_) { - JSOutPoint jso = std::get<0>(t); - std::vector vOutPoints = { jso }; - uint256 inputAnchor; - std::vector> vInputWitnesses; - pwalletMain->GetSproutNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); - jsopWitnessAnchorMap[ jso.ToString() ] = WitnessAnchorData{ vInputWitnesses[0], inputAnchor }; - } - } - - - /** - * SCENARIO #2 - * - * taddr -> taddrs - * -> zaddrs - * - * Note: Consensus rule states that coinbase utxos can only be sent to a zaddr. TODO: Do they? - * Local wallet rule does not allow any change when sending coinbase utxos - * since there is currently no way to specify a change address and we don't - * want users accidentally sending excess funds to a recipient. - */ - if (isfromtaddr_) { - add_taddr_outputs_to_tx(); - - CAmount funds = selectedUTXOAmount; - CAmount fundsSpent = t_outputs_total + minersFee + z_outputs_total; - CAmount change = funds - fundsSpent; - - if (change > 0) { - if (selectedUTXOCoinbase) { - assert(isSingleZaddrOutput); - throw JSONRPCError(RPC_WALLET_ERROR, strprintf( - "Change %s not allowed. When shielding coinbase funds, the wallet does not " - "allow any change as there is currently no way to specify a change address " - "in z_sendmany.", FormatMoney(change))); - } else { - CBitcoinAddress ba = CBitcoinAddress(fromtaddr_); - add_taddr_change_output_to_tx(&ba,change); - LogPrint("zrpc", "%s: transparent change in transaction output (amount=%s)\n", - getId(), - FormatMoney(change) - ); - } - } - - // Create joinsplits, where each output represents a zaddr recipient. - UniValue obj(UniValue::VOBJ); - while (zOutputsDeque.size() > 0) { - AsyncJoinSplitInfo info; - info.vpub_old = 0; - info.vpub_new = 0; - int n = 0; - while (n++ 0) { - SendManyRecipient smr = zOutputsDeque.front(); - std::string address = std::get<0>(smr); - CAmount value = std::get<1>(smr); - std::string hexMemo = std::get<2>(smr); - zOutputsDeque.pop_front(); - - PaymentAddress pa = DecodePaymentAddress(address); - JSOutput jso = JSOutput(boost::get(pa), value); - if (hexMemo.size() > 0) { - jso.memo = get_memo_from_hex_string(hexMemo); - } - info.vjsout.push_back(jso); - - // Funds are removed from the value pool and enter the private pool - info.vpub_old += value; - } - obj = perform_joinsplit(info); - } - sign_send_raw_transaction(obj); - return true; - } - /** - * END SCENARIO #2 - */ - - - - /** - * SCENARIO #3 - * - * zaddr -> taddrs - * -> zaddrs - * - * Send to zaddrs by chaining JoinSplits together and immediately consuming any change - * Send to taddrs by creating dummy z outputs and accumulating value in a change note - * which is used to set vpub_new in the last chained joinsplit. - */ - UniValue obj(UniValue::VOBJ); - CAmount jsChange = 0; // this is updated after each joinsplit - int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 - bool vpubNewProcessed = false; // updated when vpub_new for miner fee and taddr outputs is set in last joinsplit - CAmount vpubNewTarget = minersFee; - if (t_outputs_total > 0) { - add_taddr_outputs_to_tx(); - vpubNewTarget += t_outputs_total; - } - - // Keep track of treestate within this transaction - boost::unordered_map intermediates; - std::vector previousCommitments; - - while (!vpubNewProcessed) { - AsyncJoinSplitInfo info; - info.vpub_old = 0; - info.vpub_new = 0; - - CAmount jsInputValue = 0; - uint256 jsAnchor; - std::vector> witnesses; - - JSDescription prevJoinSplit; - - // Keep track of previous JoinSplit and its commitments - if (tx_.vjoinsplit.size() > 0) { - prevJoinSplit = tx_.vjoinsplit.back(); - } - - // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange==0 && tx_.vjoinsplit.size() > 0) { - intermediates.clear(); - previousCommitments.clear(); - } - - // - // Consume change as the first input of the JoinSplit. - // - if (jsChange > 0) { - LOCK2(cs_main, pwalletMain->cs_wallet); - - // Update tree state with previous joinsplit - SproutMerkleTree tree; - auto it = intermediates.find(prevJoinSplit.anchor); - if (it != intermediates.end()) { - tree = it->second; - } else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); - } - - assert(changeOutputIndex != -1); - boost::optional changeWitness; - int n = 0; - for (const uint256& commitment : prevJoinSplit.commitments) { - tree.append(commitment); - previousCommitments.push_back(commitment); - if (!changeWitness && changeOutputIndex == n++) { - changeWitness = tree.witness(); - } else if (changeWitness) { - changeWitness.get().append(commitment); - } - } - if (changeWitness) { - witnesses.push_back(changeWitness); - } - jsAnchor = tree.root(); - intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) - - // Decrypt the change note's ciphertext to retrieve some data we need - ZCNoteDecryption decryptor(boost::get(spendingkey_).receiving_key()); - auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); - try { - SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( - decryptor, - prevJoinSplit.ciphertexts[changeOutputIndex], - prevJoinSplit.ephemeralKey, - hSig, - (unsigned char) changeOutputIndex); - - SproutNote note = plaintext.note(boost::get(frompaymentaddress_)); - info.notes.push_back(note); - - jsInputValue += plaintext.value(); - - LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", - getId(), - FormatMoney(plaintext.value()) - ); - - } catch (const std::exception& e) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); - } - } - - - // - // Consume spendable non-change notes - // - std::vector vInputNotes; - std::vector vOutPoints; - std::vector> vInputWitnesses; - uint256 inputAnchor; - int numInputsNeeded = (jsChange>0) ? 1 : 0; - while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { - SendManyInputJSOP t = zInputsDeque.front(); - JSOutPoint jso = std::get<0>(t); - SproutNote note = std::get<1>(t); - CAmount noteFunds = std::get<2>(t); - zInputsDeque.pop_front(); - - WitnessAnchorData wad = jsopWitnessAnchorMap[ jso.ToString() ]; - vInputWitnesses.push_back(wad.witness); - if (inputAnchor.IsNull()) { - inputAnchor = wad.anchor; - } else if (inputAnchor != wad.anchor) { - throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); - } - - vOutPoints.push_back(jso); - vInputNotes.push_back(note); - - jsInputValue += noteFunds; - - int wtxHeight = -1; - int wtxDepth = -1; - { - LOCK2(cs_main, pwalletMain->cs_wallet); - const CWalletTx& wtx = pwalletMain->mapWallet[jso.hash]; - // Zero-confirmation notes belong to transactions which have not yet been mined - if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); - } - wtxHeight = komodo_blockheight(wtx.hashBlock); - wtxDepth = wtx.GetDepthInMainChain(); - } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", - getId(), - jso.hash.ToString().substr(0, 10), - jso.js, - int(jso.n), // uint8_t - FormatMoney(noteFunds), - wtxHeight, - wtxDepth - ); - } - - // Add history of previous commitments to witness - if (vInputNotes.size() > 0) { - - if (vInputWitnesses.size()==0) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); - } - - for (auto & optionalWitness : vInputWitnesses) { - if (!optionalWitness) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); - } - SproutWitness w = *optionalWitness; // could use .get(); - if (jsChange > 0) { - for (const uint256& commitment : previousCommitments) { - w.append(commitment); - } - if (jsAnchor != w.root()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for spendable note does not have same anchor as change input"); - } - } - witnesses.push_back(w); - } - - // The jsAnchor is null if this JoinSplit is at the start of a new chain - if (jsAnchor.IsNull()) { - jsAnchor = inputAnchor; - } - - // Add spendable notes as inputs - std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); - } - - // Find recipient to transfer funds to - std::string address, hexMemo; - CAmount value = 0; - if (zOutputsDeque.size() > 0) { - SendManyRecipient smr = zOutputsDeque.front(); - address = std::get<0>(smr); - value = std::get<1>(smr); - hexMemo = std::get<2>(smr); - zOutputsDeque.pop_front(); - } - - // Reset change - jsChange = 0; - CAmount outAmount = value; - - // Set vpub_new in the last joinsplit (when there are no more notes to spend or zaddr outputs to satisfy) - if (zOutputsDeque.size() == 0 && zInputsDeque.size() == 0) { - assert(!vpubNewProcessed); - if (jsInputValue < vpubNewTarget) { - throw JSONRPCError(RPC_WALLET_ERROR, - strprintf("Insufficient funds for vpub_new %s (miners fee %s, taddr outputs %s)", - FormatMoney(vpubNewTarget), FormatMoney(minersFee), FormatMoney(t_outputs_total))); - } - outAmount += vpubNewTarget; - info.vpub_new += vpubNewTarget; // funds flowing back to public pool - vpubNewProcessed = true; - jsChange = jsInputValue - outAmount; - assert(jsChange >= 0); - } - else { - // This is not the last joinsplit, so compute change and any amount still due to the recipient - if (jsInputValue > outAmount) { - jsChange = jsInputValue - outAmount; - } else if (outAmount > jsInputValue) { - // Any amount due is owed to the recipient. Let the miners fee get paid first. - CAmount due = outAmount - jsInputValue; - SendManyRecipient r = SendManyRecipient(address, due, hexMemo); - zOutputsDeque.push_front(r); - - // reduce the amount being sent right now to the value of all inputs - value = jsInputValue; - } - } - - // create output for recipient - if (address.empty()) { - assert(value==0); - info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new - } else { - PaymentAddress pa = DecodePaymentAddress(address); - // If we are here, we know we have no Sapling outputs. - JSOutput jso = JSOutput(boost::get(pa), value); - if (hexMemo.size() > 0) { - jso.memo = get_memo_from_hex_string(hexMemo); - } - info.vjsout.push_back(jso); - } - - // create output for any change - if (jsChange>0) { - info.vjsout.push_back(JSOutput(boost::get(frompaymentaddress_), jsChange)); - - LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n", - getId(), - FormatMoney(jsChange) - ); - } - - obj = perform_joinsplit(info, witnesses, jsAnchor); - - if (jsChange > 0) { - changeOutputIndex = find_output(obj, 1); - } - } - - // Sanity check in case changes to code block above exits loop by invoking 'break' - assert(zInputsDeque.size() == 0); - assert(zOutputsDeque.size() == 0); - assert(vpubNewProcessed); - - sign_send_raw_transaction(obj); - return true; + return false; } @@ -1143,19 +720,6 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { saplingEntries.clear(); } - for (CSproutNotePlaintextEntry & entry : sproutEntries) { - z_sprout_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(boost::get(frompaymentaddress_)), CAmount(entry.plaintext.value()))); - std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); - LogPrint("zrpcunsafe", "%s: found unspent Sprout note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", - getId(), - entry.jsop.hash.ToString().substr(0, 10), - entry.jsop.js, - int(entry.jsop.n), // uint8_t - FormatMoney(entry.plaintext.value()), - HexStr(data).substr(0, 10) - ); - } - for (auto entry : saplingEntries) { z_sapling_inputs_.push_back(entry); std::string data(entry.memo.begin(), entry.memo.end()); @@ -1167,15 +731,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { HexStr(data).substr(0, 10)); } - if (z_sprout_inputs_.empty() && z_sapling_inputs_.empty()) { - return false; - } - // sort in descending order, so big notes appear first - std::sort(z_sprout_inputs_.begin(), z_sprout_inputs_.end(), - [](SendManyInputJSOP i, SendManyInputJSOP j) -> bool { - return std::get<2>(i) > std::get<2>(j); - }); std::sort(z_sapling_inputs_.begin(), z_sapling_inputs_.end(), [](SaplingNoteEntry i, SaplingNoteEntry j) -> bool { return i.note.value() > j.note.value(); @@ -1184,189 +740,6 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { return true; } -UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) { - std::vector> witnesses; - uint256 anchor; - { - LOCK(cs_main); - anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor - } - return perform_joinsplit(info, witnesses, anchor); -} - - -UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector & outPoints) { - std::vector> witnesses; - uint256 anchor; - { - LOCK(cs_main); - pwalletMain->GetSproutNoteWitnesses(outPoints, witnesses, anchor); - } - return perform_joinsplit(info, witnesses, anchor); -} - -UniValue AsyncRPCOperation_sendmany::perform_joinsplit( - AsyncJoinSplitInfo & info, - std::vector> witnesses, - uint256 anchor) -{ - if (anchor.IsNull()) { - throw std::runtime_error("anchor is null"); - } - - if (!(witnesses.size() == info.notes.size())) { - throw runtime_error("number of notes and witnesses do not match"); - } - - for (size_t i = 0; i < witnesses.size(); i++) { - if (!witnesses[i]) { - throw runtime_error("joinsplit input could not be found in tree"); - } - info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], boost::get(spendingkey_))); - } - - // Make sure there are two inputs and two outputs - while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { - info.vjsin.push_back(JSInput()); - } - - while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { - info.vjsout.push_back(JSOutput()); - } - - if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { - throw runtime_error("unsupported joinsplit input/output counts"); - } - - CMutableTransaction mtx(tx_); - - LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", - getId(), - tx_.vjoinsplit.size(), - FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), - FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) - ); - - // Generate the proof, this can take over a minute. - std::array inputs - {info.vjsin[0], info.vjsin[1]}; - std::array outputs - {info.vjsout[0], info.vjsout[1]}; - std::array inputMap; - std::array outputMap; - uint256 esk; // payment disclosure - secret - - JSDescription jsdesc = JSDescription::Randomized( - *pzcashParams, - joinSplitPubKey_, - anchor, - inputs, - outputs, - inputMap, - outputMap, - info.vpub_old, - info.vpub_new, - !this->testmode, - &esk); // parameter expects pointer to esk, so pass in address - { - auto verifier = libzcash::ProofVerifier::Strict(); - if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { - throw std::runtime_error("error verifying joinsplit"); - } - } - - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); - - // Add the signature - if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey_ - ) == 0)) - { - throw std::runtime_error("crypto_sign_detached failed"); - } - - // Sanity check - if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - mtx.joinSplitPubKey.begin() - ) == 0)) - { - throw std::runtime_error("crypto_sign_verify_detached failed"); - } - - CTransaction rawTx(mtx); - tx_ = rawTx; - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - - std::string encryptedNote1; - std::string encryptedNote2; - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x00); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[0]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote1 = HexStr(ss2.begin(), ss2.end()); - } - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x01); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[1]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote2 = HexStr(ss2.begin(), ss2.end()); - } - - UniValue arrInputMap(UniValue::VARR); - UniValue arrOutputMap(UniValue::VARR); - for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { - arrInputMap.push_back(static_cast(inputMap[i])); - } - for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - arrOutputMap.push_back(static_cast(outputMap[i])); - } - - - // !!! Payment disclosure START - unsigned char buffer[32] = {0}; - memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer - std::vector vch(&buffer[0], &buffer[0] + 32); - uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; - uint256 placeholder; - for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - uint8_t mapped_index = outputMap[i]; - // placeholder for txid will be filled in later when tx has been finalized and signed. - PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; - JSOutput output = outputs[mapped_index]; - libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output - PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; - paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); - - LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr)); - } - // !!! Payment disclosure END - - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("encryptednote1", encryptedNote1)); - obj.push_back(Pair("encryptednote2", encryptedNote2)); - obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); - obj.push_back(Pair("inputmap", arrInputMap)); - obj.push_back(Pair("outputmap", arrOutputMap)); - return obj; -} - void AsyncRPCOperation_sendmany::add_taddr_outputs_to_tx() { CMutableTransaction rawTx(tx_); From 5be12774f4e61f79969b967f458b52424e1657df Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 2 Jun 2020 02:40:18 -0400 Subject: [PATCH 128/220] desprout --- .../asyncrpcoperation_mergetoaddress.cpp | 186 ----------------- .../asyncrpcoperation_shieldcoinbase.cpp | 189 +----------------- src/wallet/wallet.cpp | 140 +------------ src/wallet/walletdb.cpp | 76 ++----- 4 files changed, 22 insertions(+), 569 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 4dace19bb..ed4efc014 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -518,186 +518,6 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) tx_ = tx; } - -UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info) -{ - std::vector> witnesses; - uint256 anchor; - { - LOCK(cs_main); - anchor = pcoinsTip->GetBestAnchor(SPROUT); // As there are no inputs, ask the wallet for the best anchor - } - return perform_joinsplit(info, witnesses, anchor); -} - - -UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info, std::vector& outPoints) -{ - std::vector> witnesses; - uint256 anchor; - return perform_joinsplit(info, witnesses, anchor); -} - -UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor) -{ - if (anchor.IsNull()) { - throw std::runtime_error("anchor is null"); - } - - if (witnesses.size() != info.notes.size()) { - throw runtime_error("number of notes and witnesses do not match"); - } - - if (info.notes.size() != info.zkeys.size()) { - throw runtime_error("number of notes and spending keys do not match"); - } - - for (size_t i = 0; i < witnesses.size(); i++) { - if (!witnesses[i]) { - throw runtime_error("joinsplit input could not be found in tree"); - } - info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], info.zkeys[i])); - } - - // Make sure there are two inputs and two outputs - while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { - info.vjsin.push_back(JSInput()); - } - - while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { - info.vjsout.push_back(JSOutput()); - } - - if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { - throw runtime_error("unsupported joinsplit input/output counts"); - } - - CMutableTransaction mtx(tx_); - - LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", - getId(), - tx_.vjoinsplit.size(), - FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), - FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); - - // Generate the proof, this can take over a minute. - std::array inputs{info.vjsin[0], info.vjsin[1]}; - std::array outputs{info.vjsout[0], info.vjsout[1]}; - std::array inputMap; - std::array outputMap; - - uint256 esk; // payment disclosure - secret - - JSDescription jsdesc = JSDescription::Randomized( - *pzcashParams, - joinSplitPubKey_, - anchor, - inputs, - outputs, - inputMap, - outputMap, - info.vpub_old, - info.vpub_new, - !this->testmode, - &esk); // parameter expects pointer to esk, so pass in address - { - auto verifier = libzcash::ProofVerifier::Strict(); - if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { - throw std::runtime_error("error verifying joinsplit"); - } - } - - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); - - // Add the signature - if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey_) == 0)) { - throw std::runtime_error("crypto_sign_detached failed"); - } - - // Sanity check - if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - mtx.joinSplitPubKey.begin()) == 0)) { - throw std::runtime_error("crypto_sign_verify_detached failed"); - } - - CTransaction rawTx(mtx); - tx_ = rawTx; - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - - std::string encryptedNote1; - std::string encryptedNote2; - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char)0x00); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[0]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote1 = HexStr(ss2.begin(), ss2.end()); - } - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char)0x01); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[1]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote2 = HexStr(ss2.begin(), ss2.end()); - } - - UniValue arrInputMap(UniValue::VARR); - UniValue arrOutputMap(UniValue::VARR); - for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { - arrInputMap.push_back(static_cast(inputMap[i])); - } - for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - arrOutputMap.push_back(static_cast(outputMap[i])); - } - - - // !!! Payment disclosure START - unsigned char buffer[32] = {0}; - memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer - std::vector vch(&buffer[0], &buffer[0] + 32); - uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; - uint256 placeholder; - for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - uint8_t mapped_index = outputMap[i]; - // placeholder for txid will be filled in later when tx has been finalized and signed. - PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; - JSOutput output = outputs[mapped_index]; - libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output - PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; - paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); - - LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr)); - } - // !!! Payment disclosure END - - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("encryptednote1", encryptedNote1)); - obj.push_back(Pair("encryptednote2", encryptedNote2)); - obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); - obj.push_back(Pair("inputmap", arrInputMap)); - obj.push_back(Pair("outputmap", arrOutputMap)); - return obj; -} - std::array AsyncRPCOperation_mergetoaddress::get_memo_from_hex_string(std::string s) { std::array memo = {{0x00}}; @@ -764,9 +584,6 @@ void AsyncRPCOperation_mergetoaddress::unlock_utxos() { */ void AsyncRPCOperation_mergetoaddress::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto note : sproutNoteInputs_) { - pwalletMain->LockNote(std::get<0>(note)); - } for (auto note : saplingNoteInputs_) { pwalletMain->LockNote(std::get<0>(note)); } @@ -777,9 +594,6 @@ void AsyncRPCOperation_mergetoaddress::lock_notes() { */ void AsyncRPCOperation_mergetoaddress::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto note : sproutNoteInputs_) { - pwalletMain->UnlockNote(std::get<0>(note)); - } for (auto note : saplingNoteInputs_) { pwalletMain->UnlockNote(std::get<0>(note)); } diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 55feb2cbf..5db0ca51b 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -234,37 +235,6 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() { return boost::apply_visitor(ShieldToAddress(this, sendAmount), tozaddr_); } -bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const { - // update the transaction with these inputs - CMutableTransaction rawTx(m_op->tx_); - for (ShieldCoinbaseUTXO & t : m_op->inputs_) { - CTxIn in(COutPoint(t.txid, t.vout)); - if (t.amount >= ASSETCHAINS_TIMELOCKGTE) - in.nSequence = 0xfffffffe; - rawTx.vin.push_back(in); - } - m_op->tx_ = CTransaction(rawTx); - - // Prepare raw transaction to handle JoinSplits - CMutableTransaction mtx(m_op->tx_); - crypto_sign_keypair(m_op->joinSplitPubKey_.begin(), m_op->joinSplitPrivKey_); - mtx.joinSplitPubKey = m_op->joinSplitPubKey_; - m_op->tx_ = CTransaction(mtx); - - // Create joinsplit - UniValue obj(UniValue::VOBJ); - ShieldCoinbaseJSInfo info; - info.vpub_old = sendAmount; - info.vpub_new = 0; - JSOutput jso = JSOutput(zaddr, sendAmount); - info.vjsout.push_back(jso); - obj = m_op->perform_joinsplit(info); - - m_op->sign_send_raw_transaction(obj); - return true; -} - - extern UniValue signrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue sendrawtransaction(const UniValue& params, bool fHelp, const CPubKey& mypk); @@ -406,163 +376,6 @@ void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj) } -UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInfo & info) { - uint32_t consensusBranchId; - uint256 anchor; - { - LOCK(cs_main); - consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - anchor = pcoinsTip->GetBestAnchor(SPROUT); - } - - - if (anchor.IsNull()) { - throw std::runtime_error("anchor is null"); - } - - // Make sure there are two inputs and two outputs - while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { - info.vjsin.push_back(JSInput()); - } - - while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { - info.vjsout.push_back(JSOutput()); - } - - if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { - throw runtime_error("unsupported joinsplit input/output counts"); - } - - CMutableTransaction mtx(tx_); - - LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", - getId(), - tx_.vjoinsplit.size(), - FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), - FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) - ); - - // Generate the proof, this can take over a minute. - std::array inputs - {info.vjsin[0], info.vjsin[1]}; - std::array outputs - {info.vjsout[0], info.vjsout[1]}; - - std::array inputMap; - std::array outputMap; - - uint256 esk; // payment disclosure - secret - - JSDescription jsdesc = JSDescription::Randomized( - *pzcashParams, - joinSplitPubKey_, - anchor, - inputs, - outputs, - inputMap, - outputMap, - info.vpub_old, - info.vpub_new, - !this->testmode, - &esk); // parameter expects pointer to esk, so pass in address - { - auto verifier = libzcash::ProofVerifier::Strict(); - if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { - throw std::runtime_error("error verifying joinsplit"); - } - } - - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey_ - ) == 0)) - { - throw std::runtime_error("crypto_sign_detached failed"); - } - - // Sanity check - if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - mtx.joinSplitPubKey.begin() - ) == 0)) - { - throw std::runtime_error("crypto_sign_verify_detached failed"); - } - - CTransaction rawTx(mtx); - tx_ = rawTx; - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - - std::string encryptedNote1; - std::string encryptedNote2; - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x00); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[0]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote1 = HexStr(ss2.begin(), ss2.end()); - } - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x01); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[1]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - - encryptedNote2 = HexStr(ss2.begin(), ss2.end()); - } - - UniValue arrInputMap(UniValue::VARR); - UniValue arrOutputMap(UniValue::VARR); - for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { - arrInputMap.push_back(static_cast(inputMap[i])); - } - for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - arrOutputMap.push_back(static_cast(outputMap[i])); - } - - // !!! Payment disclosure START - unsigned char buffer[32] = {0}; - memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer - std::vector vch(&buffer[0], &buffer[0] + 32); - uint256 joinSplitPrivKey = uint256(vch); - size_t js_index = tx_.vjoinsplit.size() - 1; - uint256 placeholder; - for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { - uint8_t mapped_index = outputMap[i]; - // placeholder for txid will be filled in later when tx has been finalized and signed. - PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; - JSOutput output = outputs[mapped_index]; - libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output - PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; - paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); - - LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr)); - } - // !!! Payment disclosure END - - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("encryptednote1", encryptedNote1)); - obj.push_back(Pair("encryptednote2", encryptedNote2)); - obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); - obj.push_back(Pair("inputmap", arrInputMap)); - obj.push_back(Pair("outputmap", arrOutputMap)); - return obj; -} - /** * Override getStatus() to append the operation's context object to the default status object. */ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d0d82a0e8..4be804abb 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -314,22 +314,11 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) return true; } -bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta) -{ - AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata - mapSproutZKeyMetadata[addr] = meta; - return true; -} - bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } -bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) -{ - return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret); -} bool CWallet::LoadCryptedSaplingZKey( const libzcash::SaplingExtendedFullViewingKey &extfvk, @@ -357,10 +346,6 @@ bool CWallet::LoadSaplingPaymentAddress( return CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr); } -bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key) -{ - return CCryptoKeyStore::AddSproutSpendingKey(key); -} bool CWallet::LoadCScript(const CScript& redeemScript) { @@ -650,20 +635,6 @@ set CWallet::GetConflicts(const uint256& txid) const result.insert(it->second); } - std::pair range_n; - - for (const JSDescription& jsdesc : wtx.vjoinsplit) { - for (const uint256& nullifier : jsdesc.nullifiers) { - if (mapTxSproutNullifiers.count(nullifier) <= 1) { - continue; // No conflict if zero or one spends - } - range_n = mapTxSproutNullifiers.equal_range(nullifier); - for (TxNullifiers::const_iterator it = range_n.first; it != range_n.second; ++it) { - result.insert(it->second); - } - } - } - std::pair range_o; for (const SpendDescription &spend : wtx.vShieldedSpend) { @@ -1367,7 +1338,6 @@ void CWallet::UpdateNullifierNoteMapForBlock(const CBlock *pblock) { auto hash = tx.GetHash(); bool txIsOurs = mapWallet.count(hash); if (txIsOurs) { - UpdateSproutNullifierNoteMapWithTx(mapWallet[hash]); UpdateSaplingNullifierNoteMapWithTx(mapWallet[hash]); } } @@ -1750,7 +1720,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, } else { if(*rt == witnesses[i]->root()) { // Something is fucky - std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root:" << rt.GetHash(); + std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root!"; throw std::logic_error(err); } @@ -2104,10 +2074,6 @@ bool CWallet::LoadCryptedHDSeed(const uint256& seedFp, const std::vector& listReceived, if (isFromMyTaddr) { CAmount myVpubOld = 0; CAmount myVpubNew = 0; - for (const JSDescription& js : vjoinsplit) { - bool fMyJSDesc = false; - - // Check input side - for (const uint256& nullifier : js.nullifiers) { - if (pwallet->IsSproutNullifierFromMe(nullifier)) { - fMyJSDesc = true; - break; - } - } - - // Check output side - if (!fMyJSDesc) { - for (const std::pair nd : this->mapSproutNoteData) { - if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) { - fMyJSDesc = true; - break; - } - } - } - - if (fMyJSDesc) { - myVpubOld += js.vpub_old; - myVpubNew += js.vpub_new; - } - - if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) { - throw std::runtime_error("CWalletTx::GetAmounts: value out of range"); - } - } // Create an output for the value taken from or added to the transparent value pool by JoinSplits if (myVpubOld > myVpubNew) { @@ -4580,38 +4516,6 @@ void CWallet::ListLockedCoins(std::vector& vOutpts) // Note Locking Operations -void CWallet::LockNote(const JSOutPoint& output) -{ - AssertLockHeld(cs_wallet); // setLockedSproutNotes - setLockedSproutNotes.insert(output); -} - -void CWallet::UnlockNote(const JSOutPoint& output) -{ - AssertLockHeld(cs_wallet); // setLockedSproutNotes - setLockedSproutNotes.erase(output); -} - -void CWallet::UnlockAllSproutNotes() -{ - AssertLockHeld(cs_wallet); // setLockedSproutNotes - setLockedSproutNotes.clear(); -} - -bool CWallet::IsLockedNote(const JSOutPoint& outpt) const -{ - AssertLockHeld(cs_wallet); // setLockedSproutNotes - - return (setLockedSproutNotes.count(outpt) > 0); -} - -std::vector CWallet::ListLockedSproutNotes() -{ - AssertLockHeld(cs_wallet); // setLockedSproutNotes - std::vector vOutpts(setLockedSproutNotes.begin(), setLockedSproutNotes.end()); - return vOutpts; -} - void CWallet::LockNote(const SaplingOutPoint& output) { AssertLockHeld(cs_wallet); @@ -4988,11 +4892,6 @@ void CWallet::GetFilteredNotes( // Shielded key and address generalizations // -bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const -{ - return m_wallet->HaveSproutViewingKey(zaddr); -} - bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; @@ -5004,11 +4903,6 @@ bool IncomingViewingKeyBelongsToWallet::operator()(const libzcash::InvalidEncodi return false; } -bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const -{ - return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr); -} - bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; @@ -5024,11 +4918,6 @@ bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding& return false; } -bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const -{ - return m_wallet->HaveSproutSpendingKey(zaddr); -} - bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; @@ -5044,17 +4933,6 @@ bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::InvalidEncodin return false; } -boost::optional GetSpendingKeyForPaymentAddress::operator()( - const libzcash::SproutPaymentAddress &zaddr) const -{ - libzcash::SproutSpendingKey k; - if (m_wallet->GetSproutSpendingKey(zaddr, k)) { - return libzcash::SpendingKey(k); - } else { - return boost::none; - } -} - boost::optional GetSpendingKeyForPaymentAddress::operator()( const libzcash::SaplingPaymentAddress &zaddr) const { @@ -5073,20 +4951,6 @@ boost::optional GetSpendingKeyForPaymentAddress::operator return libzcash::SpendingKey(); } -SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const { - auto addr = sk.address(); - if (log){ - LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr)); - } - if (m_wallet->HaveSproutSpendingKey(addr)) { - return KeyAlreadyExists; - } else if (m_wallet-> AddSproutZKey(sk)) { - m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime; - return KeyAdded; - } else { - return KeyNotAdded; - } -} SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const { auto fvk = sk.expsk.full_viewing_key(); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 952a76735..1177bbedd 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -124,26 +124,6 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, return true; } -bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, - const libzcash::ReceivingKey &rk, - const std::vector& vchCryptedSecret, - const CKeyMetadata &keyMeta) -{ - const bool fEraseUnencryptedKey = true; - nWalletDBUpdated++; - - if (!Write(std::make_pair(std::string("zkeymeta"), addr), keyMeta)) - return false; - - if (!Write(std::make_pair(std::string("czkey"), addr), std::make_pair(rk, vchCryptedSecret), false)) - return false; - if (fEraseUnencryptedKey) - { - Erase(std::make_pair(std::string("zkey"), addr)); - } - return true; -} - bool CWalletDB::WriteCryptedSaplingZKey( const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector& vchCryptedSecret, @@ -172,16 +152,6 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); } -bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta) -{ - nWalletDBUpdated++; - - if (!Write(std::make_pair(std::string("zkeymeta"), addr), keyMeta)) - return false; - - // pair is: tuple_key("zkey", paymentaddress) --> secretkey - return Write(std::make_pair(std::string("zkey"), addr), key, false); -} bool CWalletDB::WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta) @@ -203,18 +173,6 @@ bool CWalletDB::WriteSaplingPaymentAddress( return Write(std::make_pair(std::string("sapzaddr"), addr), ivk, false); } -bool CWalletDB::WriteSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - nWalletDBUpdated++; - return Write(std::make_pair(std::string("vkey"), vk), '1'); -} - -bool CWalletDB::EraseSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - nWalletDBUpdated++; - return Erase(std::make_pair(std::string("vkey"), vk)); -} - bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { nWalletDBUpdated++; @@ -552,6 +510,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "vkey") { + /* libzcash::SproutViewingKey vk; ssKey >> vk; char fYes; @@ -559,24 +518,27 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, if (fYes == '1') pwallet->LoadSproutViewingKey(vk); - // Viewing keys have no birthday information for now, - // so set the wallet birthday to the beginning of time. + Viewing keys have no birthday information for now, + so set the wallet birthday to the beginning of time. pwallet->nTimeFirstKey = 1; + */ } else if (strType == "zkey") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; libzcash::SproutSpendingKey key; ssValue >> key; - if (!pwallet->LoadZKey(key)) - { - strErr = "Error reading wallet database: LoadZKey failed"; - return false; - } + //if (!pwallet->LoadZKey(key)) + //{ + // strErr = "Error reading wallet database: LoadZKey failed"; + // return false; + //} wss.nZKeys++; + */ } else if (strType == "sapzkey") { @@ -701,12 +663,12 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> vchCryptedSecret; wss.nCKeys++; - if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) - { - strErr = "Error reading wallet database: LoadCryptedZKey failed"; - return false; - } - wss.fIsEncrypted = true; + //if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) + //{ + // strErr = "Error reading wallet database: LoadCryptedZKey failed"; + // return false; + //} + //wss.fIsEncrypted = true; } else if (strType == "csapzkey") { @@ -748,7 +710,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> keyMeta; wss.nZKeyMeta++; - pwallet->LoadZKeyMetadata(addr, keyMeta); + // pwallet->LoadZKeyMetadata(addr, keyMeta); // ignore earliest key creation time as taddr will exist before any zaddr } From 62d438e0de9efca81ca6d0de3cec348fea8edfdf Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 2 Jun 2020 02:52:19 -0400 Subject: [PATCH 129/220] desprout --- src/gtest/test_joinsplit.cpp | 585 ------------------ src/gtest/test_keystore.cpp | 95 --- src/keystore.h | 85 +-- ...asyncrpcoperation_saplingconsolidation.cpp | 4 +- 4 files changed, 6 insertions(+), 763 deletions(-) delete mode 100644 src/gtest/test_joinsplit.cpp diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp deleted file mode 100644 index 8032fc972..000000000 --- a/src/gtest/test_joinsplit.cpp +++ /dev/null @@ -1,585 +0,0 @@ -#include - -#include "utilstrencodings.h" - -#include -#include - -#include "zcash/prf.h" -#include "util.h" -#include "streams.h" -#include "version.h" -#include "serialize.h" -#include "primitives/transaction.h" -#include "zcash/JoinSplit.hpp" -#include "zcash/Note.hpp" -#include "zcash/NoteEncryption.hpp" -#include "zcash/IncrementalMerkleTree.hpp" - -#include - -using namespace libzcash; - -extern ZCJoinSplit* params; - -// Make the Groth proof for a Sprout statement, -// and store the result in a JSDescription object. -JSDescription makeSproutProof( - ZCJoinSplit& js, - const std::array& inputs, - const std::array& outputs, - const uint256& joinSplitPubKey, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt -){ - return JSDescription(js, joinSplitPubKey, rt, inputs, outputs, vpub_old, vpub_new); -} - -bool verifySproutProof( - ZCJoinSplit& js, - const JSDescription& jsdesc, - const uint256& joinSplitPubKey -) -{ - auto verifier = libzcash::ProofVerifier::Strict(); - return jsdesc.Verify(js, verifier, joinSplitPubKey); -} - - -void test_full_api(ZCJoinSplit* js) -{ - // Create verification context. - auto verifier = libzcash::ProofVerifier::Strict(); - - // The recipient's information. - SproutSpendingKey recipient_key = SproutSpendingKey::random(); - SproutPaymentAddress recipient_addr = recipient_key.address(); - - // Create the commitment tree - SproutMerkleTree tree; - - // Set up a JoinSplit description - uint64_t vpub_old = 10; - uint64_t vpub_new = 0; - uint256 joinSplitPubKey = random_uint256(); - uint256 rt = tree.root(); - JSDescription jsdesc; - - { - std::array inputs = { - JSInput(), // dummy input - JSInput() // dummy input - }; - - std::array outputs = { - JSOutput(recipient_addr, 10), - JSOutput() // dummy output - }; - - std::array output_notes; - - // Perform the proofs - jsdesc = makeSproutProof( - *js, - inputs, - outputs, - joinSplitPubKey, - vpub_old, - vpub_new, - rt - ); - } - - // Verify both PHGR and Groth Proof: - ASSERT_TRUE(verifySproutProof(*js, jsdesc, joinSplitPubKey)); - - { - SproutMerkleTree tree; - JSDescription jsdesc2; - // Recipient should decrypt - // Now the recipient should spend the money again - auto h_sig = js->h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey); - ZCNoteDecryption decryptor(recipient_key.receiving_key()); - - auto note_pt = SproutNotePlaintext::decrypt( - decryptor, - jsdesc.ciphertexts[0], - jsdesc.ephemeralKey, - h_sig, - 0 - ); - - auto decrypted_note = note_pt.note(recipient_addr); - - ASSERT_TRUE(decrypted_note.value() == 10); - - // Insert the commitments from the last tx into the tree - tree.append(jsdesc.commitments[0]); - auto witness_recipient = tree.witness(); - tree.append(jsdesc.commitments[1]); - witness_recipient.append(jsdesc.commitments[1]); - vpub_old = 0; - vpub_new = 1; - rt = tree.root(); - auto joinSplitPubKey2 = random_uint256(); - - { - std::array inputs = { - JSInput(), // dummy input - JSInput(witness_recipient, decrypted_note, recipient_key) - }; - - SproutSpendingKey second_recipient = SproutSpendingKey::random(); - SproutPaymentAddress second_addr = second_recipient.address(); - - std::array outputs = { - JSOutput(second_addr, 9), - JSOutput() // dummy output - }; - - std::array output_notes; - - - // Perform the proofs - jsdesc2 = makeSproutProof( - *js, - inputs, - outputs, - joinSplitPubKey2, - vpub_old, - vpub_new, - rt - ); - - } - - - // Verify Groth Proof: - ASSERT_TRUE(verifySproutProof(*js, jsdesc2, joinSplitPubKey2)); - } -} - -// Invokes the API (but does not compute a proof) -// to test exceptions -void invokeAPI( - ZCJoinSplit* js, - const std::array& inputs, - const std::array& outputs, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt -) { - uint256 ephemeralKey; - uint256 randomSeed; - uint256 joinSplitPubKey = random_uint256(); - std::array macs; - std::array nullifiers; - std::array commitments; - std::array ciphertexts; - - std::array output_notes; - - // Groth - SproutProof proof = js->prove( - inputs, - outputs, - output_notes, - ciphertexts, - ephemeralKey, - joinSplitPubKey, - randomSeed, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new, - rt, - false - ); -} - -void invokeAPIFailure( - ZCJoinSplit* js, - const std::array& inputs, - const std::array& outputs, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt, - std::string reason -) -{ - try { - invokeAPI(js, inputs, outputs, vpub_old, vpub_new, rt); - FAIL() << "It worked, when it shouldn't have!"; - } catch(std::invalid_argument const & err) { - EXPECT_EQ(err.what(), reason); - } catch(...) { - FAIL() << "Expected invalid_argument exception."; - } -} - -TEST(joinsplit, h_sig) -{ -/* -// by Taylor Hornby - -import pyblake2 -import binascii - -def hSig(randomSeed, nf1, nf2, joinSplitPubKey): - return pyblake2.blake2b( - data=(randomSeed + nf1 + nf2 + joinSplitPubKey), - digest_size=32, - person=b"ZcashComputehSig" - ).digest() - -INCREASING = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" - -TEST_VECTORS = [ - [b"a" * 32, b"b" * 32, b"c" * 32, b"d" * 32], - [b"\x00" * 32, b"\x00" * 32, b"\x00" * 32, b"\x00" * 32], - [b"\xFF" * 32, b"\xFF" * 32, b"\xFF" * 32, b"\xFF" * 32], - [INCREASING, INCREASING, INCREASING, INCREASING] -] - -for test_input in TEST_VECTORS: - print "---" - print "\"" + binascii.hexlify(test_input[0][::-1]) + "\"" - print "\"" + binascii.hexlify(test_input[1][::-1]) + "\"" - print "\"" + binascii.hexlify(test_input[2][::-1]) + "\"" - print "\"" + binascii.hexlify(test_input[3][::-1]) + "\"" - print "\"" + binascii.hexlify(hSig(test_input[0], test_input[1], test_input[2], test_input[3])[::-1]) + "\"" -*/ - - std::vector> tests = { - { - "6161616161616161616161616161616161616161616161616161616161616161", - "6262626262626262626262626262626262626262626262626262626262626262", - "6363636363636363636363636363636363636363636363636363636363636363", - "6464646464646464646464646464646464646464646464646464646464646464", - "a8cba69f1fa329c055756b4af900f8a00b61e44f4cb8a1824ceb58b90a5b8113" - }, - { - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000000", - "697322276b5dd93b12fb1fcbd2144b2960f24c73aac6c6a0811447be1e7f1e19" - }, - { - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "4961048919f0ca79d49c9378c36a91a8767060001f4212fe6f7d426f3ccf9f32" - }, - { - "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", - "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", - "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", - "1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100", - "b61110ec162693bc3d9ca7fb0eec3afd2e278e2f41394b3ff11d7cb761ad4b27" - } - }; - - BOOST_FOREACH(std::vector& v, tests) { - auto expected = ZCJoinSplit::h_sig( - uint256S(v[0]), - {uint256S(v[1]), uint256S(v[2])}, - uint256S(v[3]) - ); - - EXPECT_EQ(expected, uint256S(v[4])); - } -} - -void increment_note_witnesses( - const uint256& element, - std::vector& witnesses, - SproutMerkleTree& tree -) -{ - tree.append(element); - for (SproutWitness& w : witnesses) { - w.append(element); - } - witnesses.push_back(tree.witness()); -} - -TEST(joinsplit, full_api_test) -{ - { - std::vector witnesses; - SproutMerkleTree tree; - increment_note_witnesses(uint256(), witnesses, tree); - SproutSpendingKey sk = SproutSpendingKey::random(); - SproutPaymentAddress addr = sk.address(); - SproutNote note1(addr.a_pk, 100, random_uint256(), random_uint256()); - increment_note_witnesses(note1.cm(), witnesses, tree); - SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256()); - increment_note_witnesses(note2.cm(), witnesses, tree); - SproutNote note3(addr.a_pk, 2100000000000001, random_uint256(), random_uint256()); - increment_note_witnesses(note3.cm(), witnesses, tree); - SproutNote note4(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); - increment_note_witnesses(note4.cm(), witnesses, tree); - SproutNote note5(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); - increment_note_witnesses(note5.cm(), witnesses, tree); - - // Should work - invokeAPI(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 0, - tree.root()); - - // lhs > MAX_MONEY - invokeAPIFailure(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 2100000000000001, - 0, - tree.root(), - "nonsensical vpub_old value"); - - // rhs > MAX_MONEY - invokeAPIFailure(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 2100000000000001, - tree.root(), - "nonsensical vpub_new value"); - - // input witness for the wrong element - invokeAPIFailure(params, - { - JSInput(witnesses[0], note1, sk), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 100, - tree.root(), - "witness of wrong element for joinsplit input"); - - // input witness doesn't match up with - // real root - invokeAPIFailure(params, - { - JSInput(witnesses[1], note1, sk), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 100, - uint256(), - "joinsplit not anchored to the correct root"); - - // input is in the tree now! this should work - invokeAPI(params, - { - JSInput(witnesses[1], note1, sk), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 100, - tree.root()); - - // Wrong secret key - invokeAPIFailure(params, - { - JSInput(witnesses[1], note1, SproutSpendingKey::random()), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 0, - tree.root(), - "input note not authorized to spend with given key"); - - // Absurd input value - invokeAPIFailure(params, - { - JSInput(witnesses[3], note3, sk), - JSInput() - }, - { - JSOutput(), - JSOutput() - }, - 0, - 0, - tree.root(), - "nonsensical input note value"); - - // Absurd total input value - invokeAPIFailure(params, - { - JSInput(witnesses[4], note4, sk), - JSInput(witnesses[5], note5, sk) - }, - { - JSOutput(), - JSOutput() - }, - 0, - 0, - tree.root(), - "nonsensical left hand size of joinsplit balance"); - - // Absurd output value - invokeAPIFailure(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(addr, 2100000000000001), - JSOutput() - }, - 0, - 0, - tree.root(), - "nonsensical output value"); - - // Absurd total output value - invokeAPIFailure(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(addr, 1900000000000000), - JSOutput(addr, 1900000000000000) - }, - 0, - 0, - tree.root(), - "nonsensical right hand side of joinsplit balance"); - - // Absurd total output value - invokeAPIFailure(params, - { - JSInput(), - JSInput() - }, - { - JSOutput(addr, 1900000000000000), - JSOutput() - }, - 0, - 0, - tree.root(), - "invalid joinsplit balance"); - } - - test_full_api(params); -} - -TEST(joinsplit, note_plaintexts) -{ - uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e")); - uint256 a_pk = PRF_addr_a_pk(a_sk); - uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk); - uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); - SproutPaymentAddress addr_pk(a_pk, pk_enc); - - uint256 h_sig; - - ZCNoteEncryption encryptor(h_sig); - uint256 epk = encryptor.get_epk(); - - SproutNote note(a_pk, - 1945813, - random_uint256(), - random_uint256() - ); - - std::array memo; - - SproutNotePlaintext note_pt(note, memo); - - ZCNoteEncryption::Ciphertext ct = note_pt.encrypt(encryptor, pk_enc); - - ZCNoteDecryption decryptor(sk_enc); - - auto decrypted = SproutNotePlaintext::decrypt(decryptor, ct, epk, h_sig, 0); - auto decrypted_note = decrypted.note(addr_pk); - - ASSERT_TRUE(decrypted_note.a_pk == note.a_pk); - ASSERT_TRUE(decrypted_note.rho == note.rho); - ASSERT_TRUE(decrypted_note.r == note.r); - ASSERT_TRUE(decrypted_note.value() == note.value()); - - ASSERT_TRUE(decrypted.memo() == note_pt.memo()); - - // Check memo() returns by reference, not return by value, for use cases such as: - // std::string data(plaintext.memo().begin(), plaintext.memo().end()); - ASSERT_TRUE(decrypted.memo().data() == decrypted.memo().data()); - - // Check serialization of note plaintext - CDataStream ss(SER_DISK, PROTOCOL_VERSION); - ss << note_pt; - SproutNotePlaintext note_pt2; - ss >> note_pt2; - ASSERT_EQ(note_pt.value(), note.value()); - ASSERT_EQ(note_pt.value(), note_pt2.value()); - ASSERT_EQ(note_pt.memo(), note_pt2.memo()); - ASSERT_EQ(note_pt.rho, note_pt2.rho); - ASSERT_EQ(note_pt.r, note_pt2.r); -} - -TEST(joinsplit, note_class) -{ - uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e")); - uint256 a_pk = PRF_addr_a_pk(a_sk); - uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk); - uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); - SproutPaymentAddress addr_pk(a_pk, pk_enc); - - SproutNote note(a_pk, - 1945813, - random_uint256(), - random_uint256()); - - SproutNote clone = note; - ASSERT_NE(¬e, &clone); - ASSERT_EQ(note.value(), clone.value()); - ASSERT_EQ(note.cm(), clone.cm()); - ASSERT_EQ(note.rho, clone.rho); - ASSERT_EQ(note.r, clone.r); - ASSERT_EQ(note.a_pk, clone.a_pk); -} diff --git a/src/gtest/test_keystore.cpp b/src/gtest/test_keystore.cpp index ccf9cb9ba..a6237a0e4 100644 --- a/src/gtest/test_keystore.cpp +++ b/src/gtest/test_keystore.cpp @@ -95,101 +95,6 @@ TEST(keystore_tests, sapling_keys) { } } -TEST(keystore_tests, store_and_retrieve_spending_key) { - CBasicKeyStore keyStore; - libzcash::SproutSpendingKey skOut; - - std::set addrs; - keyStore.GetSproutPaymentAddresses(addrs); - EXPECT_EQ(0, addrs.size()); - - auto sk = libzcash::SproutSpendingKey::random(); - auto addr = sk.address(); - - // Sanity-check: we can't get a key we haven't added - EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut)); - - keyStore.AddSproutSpendingKey(sk); - EXPECT_TRUE(keyStore.HaveSproutSpendingKey(addr)); - EXPECT_TRUE(keyStore.GetSproutSpendingKey(addr, skOut)); - EXPECT_EQ(sk, skOut); - - keyStore.GetSproutPaymentAddresses(addrs); - EXPECT_EQ(1, addrs.size()); - EXPECT_EQ(1, addrs.count(addr)); -} - -TEST(keystore_tests, store_and_retrieve_note_decryptor) { - CBasicKeyStore keyStore; - ZCNoteDecryption decOut; - - auto sk = libzcash::SproutSpendingKey::random(); - auto addr = sk.address(); - - EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); - - keyStore.AddSproutSpendingKey(sk); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); -} - -TEST(keystore_tests, StoreAndRetrieveViewingKey) { - CBasicKeyStore keyStore; - libzcash::SproutViewingKey vkOut; - libzcash::SproutSpendingKey skOut; - ZCNoteDecryption decOut; - - auto sk = libzcash::SproutSpendingKey::random(); - auto vk = sk.viewing_key(); - auto addr = sk.address(); - - // Sanity-check: we can't get a viewing key we haven't added - EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut)); - - // and we shouldn't have a spending key or decryptor either - EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut)); - EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); - - // and we can't find it in our list of addresses - std::set addresses; - keyStore.GetSproutPaymentAddresses(addresses); - EXPECT_FALSE(addresses.count(addr)); - - keyStore.AddSproutViewingKey(vk); - EXPECT_TRUE(keyStore.HaveSproutViewingKey(addr)); - EXPECT_TRUE(keyStore.GetSproutViewingKey(addr, vkOut)); - EXPECT_EQ(vk, vkOut); - - // We should still not have the spending key... - EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut)); - - // ... but we should have a decryptor - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); - - // ... and we should find it in our list of addresses - addresses.clear(); - keyStore.GetSproutPaymentAddresses(addresses); - EXPECT_TRUE(addresses.count(addr)); - - keyStore.RemoveSproutViewingKey(vk); - EXPECT_FALSE(keyStore.HaveSproutViewingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutViewingKey(addr, vkOut)); - EXPECT_FALSE(keyStore.HaveSproutSpendingKey(addr)); - EXPECT_FALSE(keyStore.GetSproutSpendingKey(addr, skOut)); - addresses.clear(); - keyStore.GetSproutPaymentAddresses(addresses); - EXPECT_FALSE(addresses.count(addr)); - - // We still have a decryptor because those are cached in memory - // (and also we only remove viewing keys when adding a spending key) - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); -} // Sapling TEST(keystore_tests, StoreAndRetrieveSaplingSpendingKey) { diff --git a/src/keystore.h b/src/keystore.h index c2e1f25d9..ac2ccf233 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -70,14 +71,6 @@ public: virtual bool HaveWatchOnly(const CScript &dest) const =0; virtual bool HaveWatchOnly() const =0; - //! Add a spending key to the store. - virtual bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) =0; - - //! Check whether a spending key corresponding to a given payment address is present in the store. - virtual bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const =0; - virtual bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0; - virtual void GetSproutPaymentAddresses(std::set &setAddress) const =0; - //! Add a Sapling spending key to the store. virtual bool AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, @@ -106,21 +99,11 @@ public: libzcash::SaplingIncomingViewingKey& ivkOut) const =0; virtual void GetSaplingPaymentAddresses(std::set &setAddress) const =0; - //! Support for Sprout viewing keys - virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk) =0; - virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) =0; - virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const =0; - virtual bool GetSproutViewingKey( - const libzcash::SproutPaymentAddress &address, - libzcash::SproutViewingKey& vkOut) const =0; }; typedef std::map KeyMap; typedef std::map ScriptMap; typedef std::set WatchOnlySet; -typedef std::map SproutSpendingKeyMap; -typedef std::map SproutViewingKeyMap; -typedef std::map NoteDecryptorMap; // Full viewing key has equivalent functionality to a transparent address // When encrypting wallet, encrypt SaplingSpendingKeyMap, while leaving SaplingFullViewingKeyMap unencrypted @@ -137,9 +120,11 @@ protected: KeyMap mapKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; + /* SproutSpendingKeyMap mapSproutSpendingKeys; SproutViewingKeyMap mapSproutViewingKeys; NoteDecryptorMap mapNoteDecryptors; + */ SaplingSpendingKeyMap mapSaplingSpendingKeys; SaplingFullViewingKeyMap mapSaplingFullViewingKeys; @@ -195,62 +180,6 @@ public: virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; - bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk); - bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const - { - bool result; - { - LOCK(cs_SpendingKeyStore); - result = (mapSproutSpendingKeys.count(address) > 0); - } - return result; - } - bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const - { - { - LOCK(cs_SpendingKeyStore); - SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.find(address); - if (mi != mapSproutSpendingKeys.end()) - { - skOut = mi->second; - return true; - } - } - return false; - } - bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const - { - { - LOCK(cs_SpendingKeyStore); - NoteDecryptorMap::const_iterator mi = mapNoteDecryptors.find(address); - if (mi != mapNoteDecryptors.end()) - { - decOut = mi->second; - return true; - } - } - return false; - } - void GetSproutPaymentAddresses(std::set &setAddress) const - { - setAddress.clear(); - { - LOCK(cs_SpendingKeyStore); - SproutSpendingKeyMap::const_iterator mi = mapSproutSpendingKeys.begin(); - while (mi != mapSproutSpendingKeys.end()) - { - setAddress.insert((*mi).first); - mi++; - } - SproutViewingKeyMap::const_iterator mvi = mapSproutViewingKeys.begin(); - while (mvi != mapSproutViewingKeys.end()) - { - setAddress.insert((*mvi).first); - mvi++; - } - } - } - //! Sapling bool AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, @@ -313,17 +242,11 @@ public: } } - virtual bool AddSproutViewingKey(const libzcash::SproutViewingKey &vk); - virtual bool RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk); - virtual bool HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const; - virtual bool GetSproutViewingKey( - const libzcash::SproutPaymentAddress &address, - libzcash::SproutViewingKey& vkOut) const; }; typedef std::vector > CKeyingMaterial; typedef std::map > > CryptedKeyMap; -typedef std::map > CryptedSproutSpendingKeyMap; +//typedef std::map > CryptedSproutSpendingKeyMap; //! Sapling typedef std::map > CryptedSaplingSpendingKeyMap; diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 8f7078c81..0a57b8948 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Copyright (c) 2019 CryptoForge // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -93,7 +93,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { { LOCK2(cs_main, pwalletMain->cs_wallet); // We set minDepth to 11 to avoid unconfirmed notes and in anticipation of specifying - // an anchor at height N-10 for each Sprout JoinSplit description + // an anchor at height N-10 for each SpendDescription // Consider, should notes be sorted? pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, "", 11); if (fConsolidationMapUsed) { From 2134269e7676b1bac6e0a61c76dde6e01791251c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 3 Jun 2020 00:12:54 -0400 Subject: [PATCH 130/220] desprout --- src/gtest/test_keystore.cpp | 77 ----------------------------------- src/rpc/misc.cpp | 14 +------ src/test/rpc_wallet_tests.cpp | 57 +++++--------------------- src/txdb.cpp | 12 ------ src/wallet/crypter.h | 34 +--------------- src/wallet/rpcdump.cpp | 77 ++++++++++------------------------- 6 files changed, 34 insertions(+), 237 deletions(-) diff --git a/src/gtest/test_keystore.cpp b/src/gtest/test_keystore.cpp index a6237a0e4..a8c984984 100644 --- a/src/gtest/test_keystore.cpp +++ b/src/gtest/test_keystore.cpp @@ -185,9 +185,6 @@ TEST(keystore_tests, StoreAndRetrieveHDSeedInEncryptedStore) { // 3) Test adding a new seed to an already-encrypted key store TestCCryptoKeyStore keyStore2; - // Add a Sprout address so the wallet has something to test when decrypting - ASSERT_TRUE(keyStore2.AddSproutSpendingKey(libzcash::SproutSpendingKey::random())); - ASSERT_TRUE(keyStore2.EncryptKeys(vMasterKey)); ASSERT_TRUE(keyStore2.Unlock(vMasterKey)); @@ -201,78 +198,4 @@ TEST(keystore_tests, StoreAndRetrieveHDSeedInEncryptedStore) { EXPECT_EQ(seed3, seedOut); } -TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) { - TestCCryptoKeyStore keyStore; - uint256 r {GetRandHash()}; - CKeyingMaterial vMasterKey (r.begin(), r.end()); - libzcash::SproutSpendingKey keyOut; - ZCNoteDecryption decOut; - std::set addrs; - - // 1) Test adding a key to an unencrypted key store, then encrypting it - auto sk = libzcash::SproutSpendingKey::random(); - auto addr = sk.address(); - EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); - - keyStore.AddSproutSpendingKey(sk); - ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr)); - ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut)); - ASSERT_EQ(sk, keyOut); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); - - ASSERT_TRUE(keyStore.EncryptKeys(vMasterKey)); - ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr)); - ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr, keyOut)); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); - - // Unlocking with a random key should fail - uint256 r2 {GetRandHash()}; - CKeyingMaterial vRandomKey (r2.begin(), r2.end()); - EXPECT_FALSE(keyStore.Unlock(vRandomKey)); - - // Unlocking with a slightly-modified vMasterKey should fail - CKeyingMaterial vModifiedKey (r.begin(), r.end()); - vModifiedKey[0] += 1; - EXPECT_FALSE(keyStore.Unlock(vModifiedKey)); - - // Unlocking with vMasterKey should succeed - ASSERT_TRUE(keyStore.Unlock(vMasterKey)); - ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr, keyOut)); - ASSERT_EQ(sk, keyOut); - - keyStore.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(1, addrs.size()); - ASSERT_EQ(1, addrs.count(addr)); - - // 2) Test adding a spending key to an already-encrypted key store - auto sk2 = libzcash::SproutSpendingKey::random(); - auto addr2 = sk2.address(); - EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut)); - - keyStore.AddSproutSpendingKey(sk2); - ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2)); - ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut)); - ASSERT_EQ(sk2, keyOut); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); - - ASSERT_TRUE(keyStore.Lock()); - ASSERT_TRUE(keyStore.HaveSproutSpendingKey(addr2)); - ASSERT_FALSE(keyStore.GetSproutSpendingKey(addr2, keyOut)); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); - - ASSERT_TRUE(keyStore.Unlock(vMasterKey)); - ASSERT_TRUE(keyStore.GetSproutSpendingKey(addr2, keyOut)); - ASSERT_EQ(sk2, keyOut); - EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); - - keyStore.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(2, addrs.size()); - ASSERT_EQ(1, addrs.count(addr)); - ASSERT_EQ(1, addrs.count(addr2)); -} #endif diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fc4b39ef0..a0248c2de 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -594,19 +595,6 @@ class DescribePaymentAddressVisitor : public boost::static_visitor public: UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); } - UniValue operator()(const libzcash::SproutPaymentAddress &zaddr) const { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("type", "sprout")); - obj.push_back(Pair("payingkey", zaddr.a_pk.GetHex())); - obj.push_back(Pair("transmissionkey", zaddr.pk_enc.GetHex())); -#ifdef ENABLE_WALLET - if (pwalletMain) { - obj.push_back(Pair("ismine", pwalletMain->HaveSproutSpendingKey(zaddr))); - } -#endif - return obj; - } - UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("type", "sapling")); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 1eaade55b..f68bf8b79 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2013-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php #include "rpc/server.h" #include "rpc/client.h" @@ -341,38 +342,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress) BOOST_CHECK_THROW(CallRPC("z_validateaddress"), runtime_error); BOOST_CHECK_THROW(CallRPC("z_validateaddress toomany args"), runtime_error); - // Wallet should be empty - std::set addrs; - pwalletMain->GetSproutPaymentAddresses(addrs); - BOOST_CHECK(addrs.size()==0); - // This address is not valid, it belongs to another network BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress ztaaga95QAPyp1kSQ1hD2kguCpzyMHjxWZqaYDEkzbvo7uYQYAw2S8X4Kx98AvhhofMtQL8PAXKHuZsmhRcanavKRKmdCzk")); UniValue resultObj = retValue.get_obj(); bool b = find_value(resultObj, "isvalid").get_bool(); BOOST_CHECK_EQUAL(b, false); - // This address is valid, but the spending key is not in this wallet - BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress zcfA19SDAKRYHLoRDoShcoz4nPohqWxuHcqg8WAxsiB2jFrrs6k7oSvst3UZvMYqpMNSRBkxBsnyjjngX5L55FxMzLKach8")); - resultObj = retValue.get_obj(); - b = find_value(resultObj, "isvalid").get_bool(); - BOOST_CHECK_EQUAL(b, true); - BOOST_CHECK_EQUAL(find_value(resultObj, "type").get_str(), "sprout"); - b = find_value(resultObj, "ismine").get_bool(); - BOOST_CHECK_EQUAL(b, false); - - // Let's import a spending key to the wallet and validate its payment address - BOOST_CHECK_NO_THROW(CallRPC("z_importkey SKxoWv77WGwFnUJitQKNEcD636bL4X5Gd6wWmgaA4Q9x8jZBPJXT")); - BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL")); - resultObj = retValue.get_obj(); - b = find_value(resultObj, "isvalid").get_bool(); - BOOST_CHECK_EQUAL(b, true); - BOOST_CHECK_EQUAL(find_value(resultObj, "type").get_str(), "sprout"); - b = find_value(resultObj, "ismine").get_bool(); - BOOST_CHECK_EQUAL(b, true); - BOOST_CHECK_EQUAL(find_value(resultObj, "payingkey").get_str(), "f5bb3c888ccc9831e3f6ba06e7528e26a312eec3acc1823be8918b6a3a5e20ad"); - BOOST_CHECK_EQUAL(find_value(resultObj, "transmissionkey").get_str(), "7a58c7132446564e6b810cf895c20537b3528357dc00150a8e201f491efa9c1a"); - // This Sapling address is not valid, it belongs to another network BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress ztestsapling1knww2nyjc62njkard0jmx7hlsj6twxmxwprn7anvrv4dc2zxanl3nemc0qx2hvplxmd2uau8gyw")); resultObj = retValue.get_obj(); @@ -398,16 +373,6 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) { LOCK2(cs_main, pwalletMain->cs_wallet); - // wallet should be empty - std::set addrs; - pwalletMain->GetSproutPaymentAddresses(addrs); - BOOST_CHECK(addrs.size()==0); - - // wallet should have one key - libzcash::SproutPaymentAddress addr = pwalletMain->GenerateNewSproutZKey(); - pwalletMain->GetSproutPaymentAddresses(addrs); - BOOST_CHECK(addrs.size()==1); - // Set up paths boost::filesystem::path tmppath = boost::filesystem::temp_directory_path(); boost::filesystem::path tmpfilename = boost::filesystem::unique_path("%%%%%%%%"); @@ -429,9 +394,6 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string())); - libzcash::SproutSpendingKey key; - BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, key)); - std::string s1 = EncodePaymentAddress(addr); std::string s2 = EncodeSpendingKey(key); @@ -474,13 +436,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error); // create a random key locally - auto testSpendingKey = libzcash::SproutSpendingKey::random(); + auto testSpendingKey = libzcash::SaplingSpendingKey::random(); auto testPaymentAddress = testSpendingKey.address(); std::string testAddr = EncodePaymentAddress(testPaymentAddress); std::string testKey = EncodeSpendingKey(testSpendingKey); // create test data using the random key - std::string format_str = "# Wallet dump created by Komodo v0.11.2.0.z8-9155cc6-dirty (2016-08-11 11:37:00 -0700)\n" + std::string format_str = "# Wallet dump created by Hush v0.11.2.0.z8-9155cc6-dirty (2016-08-11 11:37:00 -0700)\n" "# * Created on 2016-08-12T21:55:36Z\n" "# * Best block at time of backup was 0 (0de0a3851fef2d433b9b4f51d4342bdd24c5ddd793eb8fba57189f07e9235d52),\n" "# mined on 2009-01-03T18:15:05Z\n" @@ -504,14 +466,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) // wallet should currently be empty std::set addrs; - pwalletMain->GetSproutPaymentAddresses(addrs); + pwalletMain->GetSaplingPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); // import test data from file into wallet BOOST_CHECK_NO_THROW(CallRPC(string("z_importwallet ") + path)); // wallet should now have one zkey - pwalletMain->GetSproutPaymentAddresses(addrs); + pwalletMain->GetSaplingPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==1); // check that we have the spending key for the address @@ -521,10 +483,11 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) auto addr = boost::get(address); BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(addr)); + // Verify the spending key is the same as the test data - libzcash::SproutSpendingKey k; - BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, k)); - BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k)); + //libzcash::SproutSpendingKey k; + //BOOST_CHECK(pwalletMain->GetSproutSpendingKey(addr, k)); + //BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k)); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 46140f546..6fe8bd575 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -67,18 +67,6 @@ CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(Get } -bool CCoinsViewDB::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { - if (rt == SproutMerkleTree::empty_root()) { - SproutMerkleTree new_tree; - tree = new_tree; - return true; - } - - bool read = db.Read(make_pair(DB_SPROUT_ANCHOR, rt), tree); - - return read; -} - bool CCoinsViewDB::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { if (rt == SaplingMerkleTree::empty_root()) { SaplingMerkleTree new_tree; diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index f42a762af..8a7de32b4 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -145,7 +146,7 @@ class CCryptoKeyStore : public CBasicKeyStore private: std::pair> cryptedHDSeed; CryptedKeyMap mapCryptedKeys; - CryptedSproutSpendingKeyMap mapCryptedSproutSpendingKeys; + //CryptedSproutSpendingKeyMap mapCryptedSproutSpendingKeys; CryptedSaplingSpendingKeyMap mapCryptedSaplingSpendingKeys; CKeyingMaterial vMasterKey; @@ -223,37 +224,6 @@ public: mi++; } } - virtual bool AddCryptedSproutSpendingKey( - const libzcash::SproutPaymentAddress &address, - const libzcash::ReceivingKey &rk, - const std::vector &vchCryptedSecret); - bool AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk); - bool HaveSproutSpendingKey(const libzcash::SproutPaymentAddress &address) const - { - { - LOCK(cs_SpendingKeyStore); - if (!IsCrypted()) - return CBasicKeyStore::HaveSproutSpendingKey(address); - return mapCryptedSproutSpendingKeys.count(address) > 0; - } - return false; - } - bool GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const; - void GetSproutPaymentAddresses(std::set &setAddress) const - { - if (!IsCrypted()) - { - CBasicKeyStore::GetSproutPaymentAddresses(setAddress); - return; - } - setAddress.clear(); - CryptedSproutSpendingKeyMap::const_iterator mi = mapCryptedSproutSpendingKeys.begin(); - while (mi != mapCryptedSproutSpendingKeys.end()) - { - setAddress.insert((*mi).first); - mi++; - } - } //! Sapling virtual bool AddCryptedSaplingSpendingKey( const libzcash::SaplingExtendedFullViewingKey &extfvk, diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 44639f663..1499a58b9 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -856,48 +856,27 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp, const CPubKey& m throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key"); } - if (boost::get(&viewingkey) == nullptr) { - if (params.size() < 4) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Missing zaddr for Sapling viewing key."); - } - string strAddress = params[3].get_str(); - auto address = DecodePaymentAddress(strAddress); - if (!IsValidPaymentAddress(address)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); - } + if (params.size() < 4) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Missing zaddr for Sapling viewing key."); + } + string strAddress = params[3].get_str(); + auto address = DecodePaymentAddress(strAddress); + if (!IsValidPaymentAddress(address)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); + } - auto addr = boost::get(address); - auto ivk = boost::get(viewingkey); + auto addr = boost::get(address); + auto ivk = boost::get(viewingkey); - if (pwalletMain->HaveSaplingIncomingViewingKey(addr)) { - if (fIgnoreExistingKey) { - return NullUniValue; - } - } else { - pwalletMain->MarkDirty(); - - if (!pwalletMain->AddSaplingIncomingViewingKey(ivk, addr)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); - } + if (pwalletMain->HaveSaplingIncomingViewingKey(addr)) { + if (fIgnoreExistingKey) { + return NullUniValue; } } else { - auto vkey = boost::get(viewingkey); - auto addr = vkey.address(); - if (pwalletMain->HaveSproutSpendingKey(addr)) { - throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this viewing key"); - } + pwalletMain->MarkDirty(); - // Don't throw error in case a viewing key is already there - if (pwalletMain->HaveSproutViewingKey(addr)) { - if (fIgnoreExistingKey) { - return NullUniValue; - } - } else { - pwalletMain->MarkDirty(); - - if (!pwalletMain->AddSproutViewingKey(vkey)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); - } + if (!pwalletMain->AddSaplingIncomingViewingKey(ivk, addr)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); } } @@ -977,26 +956,12 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp, const CPubKey& m throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); } - if (boost::get(&address) == nullptr) { - auto addr = boost::get(address); - libzcash::SaplingIncomingViewingKey ivk; - if(!pwalletMain->GetSaplingIncomingViewingKey(addr, ivk)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold viewing key for this zaddr"); - } - return EncodeViewingKey(ivk); + auto addr = boost::get(address); + libzcash::SaplingIncomingViewingKey ivk; + if(!pwalletMain->GetSaplingIncomingViewingKey(addr, ivk)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold viewing key for this zaddr"); } - - auto addr = boost::get(address); - libzcash::SproutViewingKey vk; - if (!pwalletMain->GetSproutViewingKey(addr, vk)) { - libzcash::SproutSpendingKey k; - if (!pwalletMain->GetSproutSpendingKey(addr, k)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr"); - } - vk = k.viewing_key(); - } - - return EncodeViewingKey(vk); + return EncodeViewingKey(ivk); } extern int32_t KOMODO_NSPV; From 52e373967199152a6e2e60d090f919d1e831d54b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 3 Jun 2020 21:59:49 -0400 Subject: [PATCH 131/220] desprout --- src/rpc/misc.cpp | 8 +- src/test/rpc_wallet_tests.cpp | 4 +- src/wallet/gtest/test_wallet_zkeys.cpp | 297 ------------------------- src/wallet/rpcdisclosure.cpp | 7 +- 4 files changed, 13 insertions(+), 303 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a0248c2de..fb3e21137 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -537,14 +537,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk { if (fHelp || params.size() != 1) throw runtime_error( - "validateaddress \"komodoaddress\"\n" - "\nReturn information about the given Komodo address.\n" + "validateaddress \"hushaddress\"\n" + "\nReturn information about the given Hush address.\n" "\nArguments:\n" - "1. \"komodoaddress\" (string, required) The Komodo address to validate\n" + "1. \"hushaddress\" (string, required) The Hush address to validate\n" "\nResult:\n" "{\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" - " \"address\" : \"komodoaddress\", (string) The Komodo address validated\n" + " \"address\" : \"hushaddress\", (string) The Hush address validated\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n" " \"isscript\" : true|false, (boolean) If the key is a script\n" diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index f68bf8b79..107188779 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -465,7 +465,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) file << std::flush; // wallet should currently be empty - std::set addrs; + std::set addrs; pwalletMain->GetSaplingPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); @@ -477,11 +477,13 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) BOOST_CHECK(addrs.size()==1); // check that we have the spending key for the address + /* auto address = DecodePaymentAddress(testAddr); BOOST_CHECK(IsValidPaymentAddress(address)); BOOST_ASSERT(boost::get(&address) != nullptr); auto addr = boost::get(address); BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(addr)); + */ // Verify the spending key is the same as the test data diff --git a/src/wallet/gtest/test_wallet_zkeys.cpp b/src/wallet/gtest/test_wallet_zkeys.cpp index 365533b6c..7811c9c8a 100644 --- a/src/wallet/gtest/test_wallet_zkeys.cpp +++ b/src/wallet/gtest/test_wallet_zkeys.cpp @@ -106,303 +106,6 @@ TEST(wallet_zkeys_tests, StoreAndLoadSaplingZkeys) { EXPECT_TRUE(wallet.HaveSaplingIncomingViewingKey(dpa2)); } -/** - * This test covers methods on CWallet - * GenerateNewSproutZKey() - * AddSproutZKey() - * LoadZKey() - * LoadZKeyMetadata() - */ -TEST(wallet_zkeys_tests, store_and_load_zkeys) { - SelectParams(CBaseChainParams::MAIN); - - CWallet wallet; - - // wallet should be empty - std::set addrs; - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(0, addrs.size()); - - // wallet should have one key - auto addr = wallet.GenerateNewSproutZKey(); - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(1, addrs.size()); - - // verify wallet has spending key for the address - ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr)); - - // manually add new spending key to wallet - auto sk = libzcash::SproutSpendingKey::random(); - ASSERT_TRUE(wallet.AddSproutZKey(sk)); - - // verify wallet did add it - addr = sk.address(); - ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr)); - - // verify spending key stored correctly - libzcash::SproutSpendingKey keyOut; - wallet.GetSproutSpendingKey(addr, keyOut); - ASSERT_EQ(sk, keyOut); - - // verify there are two keys - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(2, addrs.size()); - ASSERT_EQ(1, addrs.count(addr)); - - // Load a third key into the wallet - sk = libzcash::SproutSpendingKey::random(); - ASSERT_TRUE(wallet.LoadZKey(sk)); - - // attach metadata to this third key - addr = sk.address(); - int64_t now = GetTime(); - CKeyMetadata meta(now); - ASSERT_TRUE(wallet.LoadZKeyMetadata(addr, meta)); - - // check metadata is the same - CKeyMetadata m= wallet.mapSproutZKeyMetadata[addr]; - ASSERT_EQ(m.nCreateTime, now); -} - -/** - * This test covers methods on CWallet - * AddSproutViewingKey() - * RemoveSproutViewingKey() - * LoadSproutViewingKey() - */ -TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) { - SelectParams(CBaseChainParams::MAIN); - - CWallet wallet; - - // wallet should be empty - std::set addrs; - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(0, addrs.size()); - - // manually add new viewing key to wallet - auto sk = libzcash::SproutSpendingKey::random(); - auto vk = sk.viewing_key(); - ASSERT_TRUE(wallet.AddSproutViewingKey(vk)); - - // verify wallet did add it - auto addr = sk.address(); - ASSERT_TRUE(wallet.HaveSproutViewingKey(addr)); - // and that we don't have the corresponding spending key - ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr)); - - // verify viewing key stored correctly - libzcash::SproutViewingKey vkOut; - wallet.GetSproutViewingKey(addr, vkOut); - ASSERT_EQ(vk, vkOut); - - // Load a second viewing key into the wallet - auto sk2 = libzcash::SproutSpendingKey::random(); - ASSERT_TRUE(wallet.LoadSproutViewingKey(sk2.viewing_key())); - - // verify wallet did add it - auto addr2 = sk2.address(); - ASSERT_TRUE(wallet.HaveSproutViewingKey(addr2)); - ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr2)); - - // Remove the first viewing key - ASSERT_TRUE(wallet.RemoveSproutViewingKey(vk)); - ASSERT_FALSE(wallet.HaveSproutViewingKey(addr)); - ASSERT_TRUE(wallet.HaveSproutViewingKey(addr2)); -} - -/** - * This test covers methods on CWalletDB - * WriteZKey() - */ -TEST(wallet_zkeys_tests, write_zkey_direct_to_db) { - SelectParams(CBaseChainParams::TESTNET); - - // Get temporary and unique path for file. - // Note: / operator to append paths - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - - bool fFirstRun; - CWallet wallet("wallet.dat"); - ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); - - // No default CPubKey set - ASSERT_TRUE(fFirstRun); - - // wallet should be empty - std::set addrs; - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(0, addrs.size()); - - // Add random key to the wallet - auto paymentAddress = wallet.GenerateNewSproutZKey(); - - // wallet should have one key - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(1, addrs.size()); - - // create random key and add it to database directly, bypassing wallet - auto sk = libzcash::SproutSpendingKey::random(); - auto addr = sk.address(); - int64_t now = GetTime(); - CKeyMetadata meta(now); - CWalletDB db("wallet.dat"); - db.WriteZKey(addr, sk, meta); - - // wallet should not be aware of key - ASSERT_FALSE(wallet.HaveSproutSpendingKey(addr)); - - // wallet sees one key - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(1, addrs.size()); - - // wallet should have default metadata for addr with null createtime - CKeyMetadata m = wallet.mapSproutZKeyMetadata[addr]; - ASSERT_EQ(m.nCreateTime, 0); - ASSERT_NE(m.nCreateTime, now); - - // load the wallet again - ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); - - // wallet can now see the spending key - ASSERT_TRUE(wallet.HaveSproutSpendingKey(addr)); - - // check key is the same - libzcash::SproutSpendingKey keyOut; - wallet.GetSproutSpendingKey(addr, keyOut); - ASSERT_EQ(sk, keyOut); - - // wallet should have two keys - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(2, addrs.size()); - - // check metadata is now the same - m = wallet.mapSproutZKeyMetadata[addr]; - ASSERT_EQ(m.nCreateTime, now); -} - -/** - * This test covers methods on CWalletDB - * WriteSproutViewingKey() - */ -TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) { - SelectParams(CBaseChainParams::TESTNET); - - // Get temporary and unique path for file. - // Note: / operator to append paths - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - - bool fFirstRun; - CWallet wallet("wallet-vkey.dat"); - ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); - - // No default CPubKey set - ASSERT_TRUE(fFirstRun); - - // create random viewing key and add it to database directly, bypassing wallet - auto sk = libzcash::SproutSpendingKey::random(); - auto vk = sk.viewing_key(); - auto addr = sk.address(); - int64_t now = GetTime(); - CKeyMetadata meta(now); - CWalletDB db("wallet-vkey.dat"); - db.WriteSproutViewingKey(vk); - - // wallet should not be aware of viewing key - ASSERT_FALSE(wallet.HaveSproutViewingKey(addr)); - - // load the wallet again - ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); - - // wallet can now see the viewing key - ASSERT_TRUE(wallet.HaveSproutViewingKey(addr)); - - // check key is the same - libzcash::SproutViewingKey vkOut; - wallet.GetSproutViewingKey(addr, vkOut); - ASSERT_EQ(vk, vkOut); -} - - - -/** - * This test covers methods on CWalletDB to load/save crypted z keys. - */ -TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) { - SelectParams(CBaseChainParams::TESTNET); - - // Get temporary and unique path for file. - // Note: / operator to append paths - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - - bool fFirstRun; - CWallet wallet("wallet_crypted.dat"); - ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); - - // No default CPubKey set - ASSERT_TRUE(fFirstRun); - - // wallet should be empty - std::set addrs; - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(0, addrs.size()); - - // Add random key to the wallet - auto paymentAddress = wallet.GenerateNewSproutZKey(); - - // wallet should have one key - wallet.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(1, addrs.size()); - - // encrypt wallet - SecureString strWalletPass; - strWalletPass.reserve(100); - strWalletPass = "hello"; - ASSERT_TRUE(wallet.EncryptWallet(strWalletPass)); - - // adding a new key will fail as the wallet is locked - EXPECT_ANY_THROW(wallet.GenerateNewSproutZKey()); - - // unlock wallet and then add - wallet.Unlock(strWalletPass); - auto paymentAddress2 = wallet.GenerateNewSproutZKey(); - - // Create a new wallet from the existing wallet path - CWallet wallet2("wallet_crypted.dat"); - ASSERT_EQ(DB_LOAD_OK, wallet2.LoadWallet(fFirstRun)); - - // Confirm it's not the same as the other wallet - ASSERT_TRUE(&wallet != &wallet2); - - // wallet should have two keys - wallet2.GetSproutPaymentAddresses(addrs); - ASSERT_EQ(2, addrs.size()); - - // check we have entries for our payment addresses - ASSERT_TRUE(addrs.count(paymentAddress)); - ASSERT_TRUE(addrs.count(paymentAddress2)); - - // spending key is crypted, so we can't extract valid payment address - libzcash::SproutSpendingKey keyOut; - wallet2.GetSproutSpendingKey(paymentAddress, keyOut); - ASSERT_FALSE(paymentAddress == keyOut.address()); - - // unlock wallet to get spending keys and verify payment addresses - wallet2.Unlock(strWalletPass); - - wallet2.GetSproutSpendingKey(paymentAddress, keyOut); - ASSERT_EQ(paymentAddress, keyOut.address()); - - wallet2.GetSproutSpendingKey(paymentAddress2, keyOut); - ASSERT_EQ(paymentAddress2, keyOut.address()); -} - /** * This test covers methods on CWalletDB to load/save crypted sapling z keys. */ diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index cd0cc42a6..918e70cbc 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -187,6 +188,8 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const C throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled."); } + throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosures not implemented for Sapling yet"); + LOCK2(cs_main, pwalletMain->cs_wallet); EnsureWalletIsUnlocked(); @@ -269,8 +272,9 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const C errs.push_back("Payment disclosure signature does not match transaction signature"); } + /* // Check the payment address is valid - SproutPaymentAddress zaddr = pd.payload.zaddr; + PaymentAddress zaddr = pd.payload.zaddr; { o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr))); @@ -308,6 +312,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const C errs.push_back(string("Error while decrypting payment disclosure note: ") + string(e.what()) ); } } + */ bool isValid = errs.empty(); o.push_back(Pair("valid", isValid)); From 7c6c7150c61e2183bc0af5449b18d8a48266f266 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 3 Jun 2020 22:20:10 -0400 Subject: [PATCH 132/220] desprout --- src/coins.cpp | 27 ----- src/primitives/transaction.cpp | 77 -------------- src/primitives/transaction.h | 177 --------------------------------- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.h | 5 - src/wallet/walletdb.cpp | 4 + src/wallet/walletdb.h | 10 +- 7 files changed, 6 insertions(+), 296 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 38fac8252..f183c99a0 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -628,33 +628,6 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const { boost::unordered_map intermediates; - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) - { - BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers) - { - if (GetNullifier(nullifier, SPROUT)) { - // If the nullifier is set, this transaction - // double-spends! - return false; - } - } - - SproutMerkleTree tree; - auto it = intermediates.find(joinsplit.anchor); - if (it != intermediates.end()) { - tree = it->second; - } else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) { - return false; - } - - BOOST_FOREACH(const uint256& commitment, joinsplit.commitments) - { - tree.append(commitment); - } - - intermediates.insert(std::make_pair(tree.root(), tree)); - } - for (const SpendDescription &spendDescription : tx.vShieldedSpend) { if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends LogPrintf("%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier.GetHex().c_str()); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 2cde04f2c..01c95adc3 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -26,83 +26,6 @@ #include "librustzcash.h" -JSDescription::JSDescription( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& anchor, - const std::array& inputs, - const std::array& outputs, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof, - uint256 *esk // payment disclosure -) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) -{ - std::array notes; - - proof = params.prove( - inputs, - outputs, - notes, - ciphertexts, - ephemeralKey, - joinSplitPubKey, - randomSeed, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new, - anchor, - computeProof, - esk // payment disclosure - ); -} - -JSDescription JSDescription::Randomized( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& anchor, - std::array& inputs, - std::array& outputs, - std::array& inputMap, - std::array& outputMap, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof, - uint256 *esk, // payment disclosure - std::function gen -) -{ - // Randomize the order of the inputs and outputs - inputMap = {0, 1}; - outputMap = {0, 1}; - - assert(gen); - - MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); - MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); - - return JSDescription( - params, joinSplitPubKey, anchor, inputs, outputs, - vpub_old, vpub_new, computeProof, - esk // payment disclosure - ); -} - -bool JSDescription::Verify( - ZCJoinSplit& params, - libzcash::ProofVerifier& verifier, - const uint256& joinSplitPubKey -) const { - return false; -} - -uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const -{ - return params.h_sig(randomSeed, nullifiers, joinSplitPubKey); -} - std::string COutPoint::ToString() const { return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 2ece7b255..b3afecd87 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -159,183 +159,6 @@ public: } }; -template -class SproutProofSerializer : public boost::static_visitor<> -{ - Stream& s; - bool useGroth; - -public: - SproutProofSerializer(Stream& s, bool useGroth) : s(s), useGroth(useGroth) {} - - void operator()(const libzcash::PHGRProof& proof) const - { - if (useGroth) { - throw std::ios_base::failure("Invalid Sprout proof for transaction format (expected GrothProof, found PHGRProof)"); - } - ::Serialize(s, proof); - } - - void operator()(const libzcash::GrothProof& proof) const - { - if (!useGroth) { - throw std::ios_base::failure("Invalid Sprout proof for transaction format (expected PHGRProof, found GrothProof)"); - } - ::Serialize(s, proof); - } -}; - -template -inline void SerReadWriteSproutProof(Stream& s, const T& proof, bool useGroth, CSerActionSerialize ser_action) -{ - auto ps = SproutProofSerializer(s, useGroth); - boost::apply_visitor(ps, proof); -} - -template -inline void SerReadWriteSproutProof(Stream& s, T& proof, bool useGroth, CSerActionUnserialize ser_action) -{ - if (useGroth) { - libzcash::GrothProof grothProof; - ::Unserialize(s, grothProof); - proof = grothProof; - } else { - libzcash::PHGRProof pghrProof; - ::Unserialize(s, pghrProof); - proof = pghrProof; - } -} - -class JSDescription -{ -public: - // These values 'enter from' and 'exit to' the value - // pool, respectively. - CAmount vpub_old; - CAmount vpub_new; - - // JoinSplits are always anchored to a root in the note - // commitment tree at some point in the blockchain - // history or in the history of the current - // transaction. - uint256 anchor; - - // Nullifiers are used to prevent double-spends. They - // are derived from the secrets placed in the note - // and the secret spend-authority key known by the - // spender. - std::array nullifiers; - - // Note commitments are introduced into the commitment - // tree, blinding the public about the values and - // destinations involved in the JoinSplit. The presence of - // a commitment in the note commitment tree is required - // to spend it. - std::array commitments; - - // Ephemeral key - uint256 ephemeralKey; - - // Ciphertexts - // These contain trapdoors, values and other information - // that the recipient needs, including a memo field. It - // is encrypted using the scheme implemented in crypto/NoteEncryption.cpp - std::array ciphertexts = {{ {{0}} }}; - - // Random seed - uint256 randomSeed; - - // MACs - // The verification of the JoinSplit requires these MACs - // to be provided as an input. - std::array macs; - - // JoinSplit proof - // This is a zk-SNARK which ensures that this JoinSplit is valid. - libzcash::SproutProof proof; - - JSDescription(): vpub_old(0), vpub_new(0) { } - - JSDescription( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& rt, - const std::array& inputs, - const std::array& outputs, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof = true, // Set to false in some tests - uint256 *esk = nullptr // payment disclosure - ); - - static JSDescription Randomized( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& rt, - std::array& inputs, - std::array& outputs, - std::array& inputMap, - std::array& outputMap, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof = true, // Set to false in some tests - uint256 *esk = nullptr, // payment disclosure - std::function gen = GetRandInt - ); - - // Verifies that the JoinSplit proof is correct. - bool Verify( - ZCJoinSplit& params, - libzcash::ProofVerifier& verifier, - const uint256& joinSplitPubKey - ) const; - - // Returns the calculated h_sig - uint256 h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - // nVersion is set by CTransaction and CMutableTransaction to - // (tx.fOverwintered << 31) | tx.nVersion - bool fOverwintered = s.GetVersion() >> 31; - int32_t txVersion = s.GetVersion() & 0x7FFFFFFF; - bool useGroth = fOverwintered && txVersion >= SAPLING_TX_VERSION; - - READWRITE(vpub_old); - READWRITE(vpub_new); - READWRITE(anchor); - READWRITE(nullifiers); - READWRITE(commitments); - READWRITE(ephemeralKey); - READWRITE(randomSeed); - READWRITE(macs); - ::SerReadWriteSproutProof(s, proof, useGroth, ser_action); - READWRITE(ciphertexts); - } - - friend bool operator==(const JSDescription& a, const JSDescription& b) - { - return ( - a.vpub_old == b.vpub_old && - a.vpub_new == b.vpub_new && - a.anchor == b.anchor && - a.nullifiers == b.nullifiers && - a.commitments == b.commitments && - a.ephemeralKey == b.ephemeralKey && - a.ciphertexts == b.ciphertexts && - a.randomSeed == b.randomSeed && - a.macs == b.macs && - a.proof == b.proof - ); - } - - friend bool operator!=(const JSDescription& a, const JSDescription& b) - { - return !(a == b); - } -}; class BaseOutPoint { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 37f67042b..604e21799 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4268,7 +4268,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my "\nResult:\n" "{\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" - " \"private\": xxxxx, (numeric) the total balance of private funds (in both Sprout and Sapling addresses)\n" + " \"private\": xxxxx, (numeric) the total balance of private funds (in Sapling addresses)\n" " \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n" "}\n" "\nExamples:\n" diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d82e100ed..f3526c583 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1408,7 +1408,6 @@ private: public: PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1421,7 +1420,6 @@ private: public: IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1433,7 +1431,6 @@ private: public: HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1445,7 +1442,6 @@ private: public: GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - boost::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1517,7 +1513,6 @@ public: ) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {} - SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 1177bbedd..4f6942bb7 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -653,6 +653,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "czkey") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another @@ -662,6 +663,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, vector vchCryptedSecret; ssValue >> vchCryptedSecret; wss.nCKeys++; + */ //if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) //{ @@ -704,11 +706,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkeymeta") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; CKeyMetadata keyMeta; ssValue >> keyMeta; wss.nZKeyMeta++; + */ // pwallet->LoadZKeyMetadata(addr, keyMeta); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 9069e3a08..8c34588ec 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -199,23 +200,14 @@ public: bool WriteHDChain(const CHDChain& chain); /// Write spending key to wallet database, where key is payment address and value is spending key. - bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta); bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta); bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk); - bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, - const libzcash::ReceivingKey & rk, - const std::vector& vchCryptedSecret, - const CKeyMetadata &keyMeta); bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); - - bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk); - bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk); - private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); From b32bf1f82c0c4ded804b2b0f009f339677b7a931 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 4 Jun 2020 21:51:21 -0400 Subject: [PATCH 133/220] Revert "desprout" This reverts commit 7c6c7150c61e2183bc0af5449b18d8a48266f266. --- src/coins.cpp | 27 +++++ src/primitives/transaction.cpp | 77 ++++++++++++++ src/primitives/transaction.h | 177 +++++++++++++++++++++++++++++++++ src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.h | 5 + src/wallet/walletdb.cpp | 4 - src/wallet/walletdb.h | 10 +- 7 files changed, 296 insertions(+), 6 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index f183c99a0..38fac8252 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -628,6 +628,33 @@ bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const { boost::unordered_map intermediates; + BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) + { + BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers) + { + if (GetNullifier(nullifier, SPROUT)) { + // If the nullifier is set, this transaction + // double-spends! + return false; + } + } + + SproutMerkleTree tree; + auto it = intermediates.find(joinsplit.anchor); + if (it != intermediates.end()) { + tree = it->second; + } else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) { + return false; + } + + BOOST_FOREACH(const uint256& commitment, joinsplit.commitments) + { + tree.append(commitment); + } + + intermediates.insert(std::make_pair(tree.root(), tree)); + } + for (const SpendDescription &spendDescription : tx.vShieldedSpend) { if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends LogPrintf("%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier.GetHex().c_str()); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 01c95adc3..2cde04f2c 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -26,6 +26,83 @@ #include "librustzcash.h" +JSDescription::JSDescription( + ZCJoinSplit& params, + const uint256& joinSplitPubKey, + const uint256& anchor, + const std::array& inputs, + const std::array& outputs, + CAmount vpub_old, + CAmount vpub_new, + bool computeProof, + uint256 *esk // payment disclosure +) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) +{ + std::array notes; + + proof = params.prove( + inputs, + outputs, + notes, + ciphertexts, + ephemeralKey, + joinSplitPubKey, + randomSeed, + macs, + nullifiers, + commitments, + vpub_old, + vpub_new, + anchor, + computeProof, + esk // payment disclosure + ); +} + +JSDescription JSDescription::Randomized( + ZCJoinSplit& params, + const uint256& joinSplitPubKey, + const uint256& anchor, + std::array& inputs, + std::array& outputs, + std::array& inputMap, + std::array& outputMap, + CAmount vpub_old, + CAmount vpub_new, + bool computeProof, + uint256 *esk, // payment disclosure + std::function gen +) +{ + // Randomize the order of the inputs and outputs + inputMap = {0, 1}; + outputMap = {0, 1}; + + assert(gen); + + MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); + MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); + + return JSDescription( + params, joinSplitPubKey, anchor, inputs, outputs, + vpub_old, vpub_new, computeProof, + esk // payment disclosure + ); +} + +bool JSDescription::Verify( + ZCJoinSplit& params, + libzcash::ProofVerifier& verifier, + const uint256& joinSplitPubKey +) const { + return false; +} + +uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const +{ + return params.h_sig(randomSeed, nullifiers, joinSplitPubKey); +} + std::string COutPoint::ToString() const { return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index b3afecd87..2ece7b255 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -159,6 +159,183 @@ public: } }; +template +class SproutProofSerializer : public boost::static_visitor<> +{ + Stream& s; + bool useGroth; + +public: + SproutProofSerializer(Stream& s, bool useGroth) : s(s), useGroth(useGroth) {} + + void operator()(const libzcash::PHGRProof& proof) const + { + if (useGroth) { + throw std::ios_base::failure("Invalid Sprout proof for transaction format (expected GrothProof, found PHGRProof)"); + } + ::Serialize(s, proof); + } + + void operator()(const libzcash::GrothProof& proof) const + { + if (!useGroth) { + throw std::ios_base::failure("Invalid Sprout proof for transaction format (expected PHGRProof, found GrothProof)"); + } + ::Serialize(s, proof); + } +}; + +template +inline void SerReadWriteSproutProof(Stream& s, const T& proof, bool useGroth, CSerActionSerialize ser_action) +{ + auto ps = SproutProofSerializer(s, useGroth); + boost::apply_visitor(ps, proof); +} + +template +inline void SerReadWriteSproutProof(Stream& s, T& proof, bool useGroth, CSerActionUnserialize ser_action) +{ + if (useGroth) { + libzcash::GrothProof grothProof; + ::Unserialize(s, grothProof); + proof = grothProof; + } else { + libzcash::PHGRProof pghrProof; + ::Unserialize(s, pghrProof); + proof = pghrProof; + } +} + +class JSDescription +{ +public: + // These values 'enter from' and 'exit to' the value + // pool, respectively. + CAmount vpub_old; + CAmount vpub_new; + + // JoinSplits are always anchored to a root in the note + // commitment tree at some point in the blockchain + // history or in the history of the current + // transaction. + uint256 anchor; + + // Nullifiers are used to prevent double-spends. They + // are derived from the secrets placed in the note + // and the secret spend-authority key known by the + // spender. + std::array nullifiers; + + // Note commitments are introduced into the commitment + // tree, blinding the public about the values and + // destinations involved in the JoinSplit. The presence of + // a commitment in the note commitment tree is required + // to spend it. + std::array commitments; + + // Ephemeral key + uint256 ephemeralKey; + + // Ciphertexts + // These contain trapdoors, values and other information + // that the recipient needs, including a memo field. It + // is encrypted using the scheme implemented in crypto/NoteEncryption.cpp + std::array ciphertexts = {{ {{0}} }}; + + // Random seed + uint256 randomSeed; + + // MACs + // The verification of the JoinSplit requires these MACs + // to be provided as an input. + std::array macs; + + // JoinSplit proof + // This is a zk-SNARK which ensures that this JoinSplit is valid. + libzcash::SproutProof proof; + + JSDescription(): vpub_old(0), vpub_new(0) { } + + JSDescription( + ZCJoinSplit& params, + const uint256& joinSplitPubKey, + const uint256& rt, + const std::array& inputs, + const std::array& outputs, + CAmount vpub_old, + CAmount vpub_new, + bool computeProof = true, // Set to false in some tests + uint256 *esk = nullptr // payment disclosure + ); + + static JSDescription Randomized( + ZCJoinSplit& params, + const uint256& joinSplitPubKey, + const uint256& rt, + std::array& inputs, + std::array& outputs, + std::array& inputMap, + std::array& outputMap, + CAmount vpub_old, + CAmount vpub_new, + bool computeProof = true, // Set to false in some tests + uint256 *esk = nullptr, // payment disclosure + std::function gen = GetRandInt + ); + + // Verifies that the JoinSplit proof is correct. + bool Verify( + ZCJoinSplit& params, + libzcash::ProofVerifier& verifier, + const uint256& joinSplitPubKey + ) const; + + // Returns the calculated h_sig + uint256 h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + // nVersion is set by CTransaction and CMutableTransaction to + // (tx.fOverwintered << 31) | tx.nVersion + bool fOverwintered = s.GetVersion() >> 31; + int32_t txVersion = s.GetVersion() & 0x7FFFFFFF; + bool useGroth = fOverwintered && txVersion >= SAPLING_TX_VERSION; + + READWRITE(vpub_old); + READWRITE(vpub_new); + READWRITE(anchor); + READWRITE(nullifiers); + READWRITE(commitments); + READWRITE(ephemeralKey); + READWRITE(randomSeed); + READWRITE(macs); + ::SerReadWriteSproutProof(s, proof, useGroth, ser_action); + READWRITE(ciphertexts); + } + + friend bool operator==(const JSDescription& a, const JSDescription& b) + { + return ( + a.vpub_old == b.vpub_old && + a.vpub_new == b.vpub_new && + a.anchor == b.anchor && + a.nullifiers == b.nullifiers && + a.commitments == b.commitments && + a.ephemeralKey == b.ephemeralKey && + a.ciphertexts == b.ciphertexts && + a.randomSeed == b.randomSeed && + a.macs == b.macs && + a.proof == b.proof + ); + } + + friend bool operator!=(const JSDescription& a, const JSDescription& b) + { + return !(a == b); + } +}; class BaseOutPoint { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 604e21799..37f67042b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4268,7 +4268,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my "\nResult:\n" "{\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" - " \"private\": xxxxx, (numeric) the total balance of private funds (in Sapling addresses)\n" + " \"private\": xxxxx, (numeric) the total balance of private funds (in both Sprout and Sapling addresses)\n" " \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n" "}\n" "\nExamples:\n" diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index f3526c583..d82e100ed 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1408,6 +1408,7 @@ private: public: PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} + bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1420,6 +1421,7 @@ private: public: IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} + bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1431,6 +1433,7 @@ private: public: HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1442,6 +1445,7 @@ private: public: GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + boost::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1513,6 +1517,7 @@ public: ) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {} + SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 4f6942bb7..1177bbedd 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -653,7 +653,6 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "czkey") { - /* libzcash::SproutPaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another @@ -663,7 +662,6 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, vector vchCryptedSecret; ssValue >> vchCryptedSecret; wss.nCKeys++; - */ //if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) //{ @@ -706,13 +704,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkeymeta") { - /* libzcash::SproutPaymentAddress addr; ssKey >> addr; CKeyMetadata keyMeta; ssValue >> keyMeta; wss.nZKeyMeta++; - */ // pwallet->LoadZKeyMetadata(addr, keyMeta); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 8c34588ec..9069e3a08 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,6 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers -// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -200,14 +199,23 @@ public: bool WriteHDChain(const CHDChain& chain); /// Write spending key to wallet database, where key is payment address and value is spending key. + bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta); bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta); bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk); + bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, + const libzcash::ReceivingKey & rk, + const std::vector& vchCryptedSecret, + const CKeyMetadata &keyMeta); bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); + + bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk); + bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk); + private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); From da6c0028a3e497e4c00f1dc11148be9717cf7108 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 4 Jun 2020 21:51:49 -0400 Subject: [PATCH 134/220] desprout --- src/coins.cpp | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 38fac8252..c0039120a 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -626,35 +626,6 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const { - boost::unordered_map intermediates; - - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) - { - BOOST_FOREACH(const uint256& nullifier, joinsplit.nullifiers) - { - if (GetNullifier(nullifier, SPROUT)) { - // If the nullifier is set, this transaction - // double-spends! - return false; - } - } - - SproutMerkleTree tree; - auto it = intermediates.find(joinsplit.anchor); - if (it != intermediates.end()) { - tree = it->second; - } else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) { - return false; - } - - BOOST_FOREACH(const uint256& commitment, joinsplit.commitments) - { - tree.append(commitment); - } - - intermediates.insert(std::make_pair(tree.root(), tree)); - } - for (const SpendDescription &spendDescription : tx.vShieldedSpend) { if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends LogPrintf("%s: sapling nullifier %s exists, preventing double spend\n", __FUNCTION__, spendDescription.nullifier.GetHex().c_str()); From ed91f0188bba048e0b50197a23853bf14a22afd8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 4 Jun 2020 21:56:04 -0400 Subject: [PATCH 135/220] We aint got no JoinSplits around here --- src/coins.cpp | 2 +- src/coins.h | 2 +- src/main.cpp | 6 +++--- src/test/coins_tests.cpp | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index c0039120a..602d153ec 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -624,7 +624,7 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr } -bool CCoinsViewCache::HaveJoinSplitRequirements(const CTransaction& tx) const +bool CCoinsViewCache::HaveShieldedRequirements(const CTransaction& tx) const { for (const SpendDescription &spendDescription : tx.vShieldedSpend) { if (GetNullifier(spendDescription.nullifier, SAPLING)) { // Prevent double spends diff --git a/src/coins.h b/src/coins.h index cc8b19f68..1211e7e07 100644 --- a/src/coins.h +++ b/src/coins.h @@ -563,7 +563,7 @@ public: bool HaveInputs(const CTransaction& tx) const; //! Check whether all joinsplit requirements (anchors/nullifiers) are satisfied - bool HaveJoinSplitRequirements(const CTransaction& tx) const; + bool HaveShieldedRequirements(const CTransaction& tx) const; //! Return priority of tx at height nHeight double GetPriority(const CTransaction &tx, int nHeight) const; diff --git a/src/main.cpp b/src/main.cpp index c75f51a28..f31847b04 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1894,7 +1894,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } // are the joinsplit's requirements met? - if (!view.HaveJoinSplitRequirements(tx)) + if (!view.HaveShieldedRequirements(tx)) { //fprintf(stderr,"accept failure.2\n"); return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); @@ -2719,7 +2719,7 @@ namespace Consensus { return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); // are the JoinSplit's requirements met? - if (!inputs.HaveJoinSplitRequirements(tx)) + if (!inputs.HaveShieldedRequirements(tx)) return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString())); CAmount nValueIn = 0; @@ -3536,7 +3536,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin REJECT_INVALID, "bad-txns-inputs-missingorspent"); } // are the JoinSplit's requirements met? - if (!view.HaveJoinSplitRequirements(tx)) + if (!view.HaveShieldedRequirements(tx)) return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"), REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met"); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index dc795ad7a..bb6432a81 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -632,7 +632,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) CMutableTransaction mtx; mtx.vjoinsplit.push_back(js2); - BOOST_CHECK(!cache.HaveJoinSplitRequirements(mtx)); + BOOST_CHECK(!cache.HaveShieldedRequirements(mtx)); } { @@ -642,7 +642,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) mtx.vjoinsplit.push_back(js2); mtx.vjoinsplit.push_back(js1); - BOOST_CHECK(!cache.HaveJoinSplitRequirements(mtx)); + BOOST_CHECK(!cache.HaveShieldedRequirements(mtx)); } { @@ -650,7 +650,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) mtx.vjoinsplit.push_back(js1); mtx.vjoinsplit.push_back(js2); - BOOST_CHECK(cache.HaveJoinSplitRequirements(mtx)); + BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } { @@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) mtx.vjoinsplit.push_back(js2); mtx.vjoinsplit.push_back(js3); - BOOST_CHECK(cache.HaveJoinSplitRequirements(mtx)); + BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } { @@ -669,7 +669,7 @@ BOOST_AUTO_TEST_CASE(chained_joinsplits) mtx.vjoinsplit.push_back(js2); mtx.vjoinsplit.push_back(js3); - BOOST_CHECK(cache.HaveJoinSplitRequirements(mtx)); + BOOST_CHECK(cache.HaveShieldedRequirements(mtx)); } } From ed2c9450f9032833f459816c3f6f91893fc8fcbe Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 01:20:37 -0400 Subject: [PATCH 136/220] desprout --- src/Makefile.am | 2 - src/gtest/test_transaction.cpp | 90 --- src/key_io.cpp | 44 +- src/keystore.cpp | 42 +- src/keystore.h | 8 +- src/paymentdisclosure.h | 1 + src/rpc/misc.cpp | 54 +- src/test/rpc_wallet_tests.cpp | 6 +- src/utiltest.cpp | 154 ----- src/utiltest.h | 19 - src/wallet/asyncrpcoperation_shieldcoinbase.h | 2 +- src/wallet/crypter.cpp | 111 +--- src/wallet/gtest/test_wallet.cpp | 570 +----------------- src/wallet/rpcwallet.cpp | 28 - src/wallet/wallet.h | 5 - src/wallet/walletdb.cpp | 16 +- src/wallet/walletdb.h | 11 +- src/zcash/Address.cpp | 38 +- src/zcbenchmarks.cpp | 34 +- 19 files changed, 52 insertions(+), 1183 deletions(-) delete mode 100644 src/gtest/test_transaction.cpp delete mode 100644 src/utiltest.cpp delete mode 100644 src/utiltest.h diff --git a/src/Makefile.am b/src/Makefile.am index 6277e0f98..2d2d7a691 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -347,8 +347,6 @@ endif libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ - utiltest.cpp \ - utiltest.h \ zcbenchmarks.cpp \ zcbenchmarks.h \ wallet/asyncrpcoperation_mergetoaddress.cpp \ diff --git a/src/gtest/test_transaction.cpp b/src/gtest/test_transaction.cpp deleted file mode 100644 index 1350768ff..000000000 --- a/src/gtest/test_transaction.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include - -#include "primitives/transaction.h" -#include "zcash/Note.hpp" -#include "zcash/Address.hpp" - -#include - -extern ZCJoinSplit* params; -extern int GenZero(int n); -extern int GenMax(int n); - -TEST(Transaction, JSDescriptionRandomized) { - // construct a merkle tree - SproutMerkleTree merkleTree; - - libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random(); - libzcash::SproutPaymentAddress addr = k.address(); - - libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); - - // commitment from coin - uint256 commitment = note.cm(); - - // insert commitment into the merkle tree - merkleTree.append(commitment); - - // compute the merkle root we will be working with - uint256 rt = merkleTree.root(); - - auto witness = merkleTree.witness(); - - // create JSDescription - uint256 joinSplitPubKey; - std::array inputs = { - libzcash::JSInput(witness, note, k), - libzcash::JSInput() // dummy input of zero value - }; - std::array outputs = { - libzcash::JSOutput(addr, 50), - libzcash::JSOutput(addr, 50) - }; - std::array inputMap; - std::array outputMap; - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false); - - std::set inputSet(inputMap.begin(), inputMap.end()); - std::set expectedInputSet {0, 1}; - EXPECT_EQ(expectedInputSet, inputSet); - - std::set outputSet(outputMap.begin(), outputMap.end()); - std::set expectedOutputSet {0, 1}; - EXPECT_EQ(expectedOutputSet, outputSet); - } - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false, nullptr, GenZero); - - std::array expectedInputMap {1, 0}; - std::array expectedOutputMap {1, 0}; - EXPECT_EQ(expectedInputMap, inputMap); - EXPECT_EQ(expectedOutputMap, outputMap); - } - - { - auto jsdesc = JSDescription::Randomized( - false, - *params, joinSplitPubKey, rt, - inputs, outputs, - inputMap, outputMap, - 0, 0, false, nullptr, GenMax); - - std::array expectedInputMap {0, 1}; - std::array expectedOutputMap {0, 1}; - EXPECT_EQ(expectedInputMap, inputMap); - EXPECT_EQ(expectedOutputMap, outputMap); - } -} diff --git a/src/key_io.cpp b/src/key_io.cpp index dd4176fee..dd4bf884c 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2014-2016 The Bitcoin Core developers // Copyright (c) 2016-2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -84,15 +85,6 @@ private: public: PaymentAddressEncoder(const CChainParams& params) : m_params(params) {} - std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const - { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zaddr; - std::vector data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - data.insert(data.end(), ss.begin(), ss.end()); - return EncodeBase58Check(data); - } - std::string operator()(const libzcash::SaplingPaymentAddress& zaddr) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -117,17 +109,6 @@ private: public: ViewingKeyEncoder(const CChainParams& params) : m_params(params) {} - std::string operator()(const libzcash::SproutViewingKey& vk) const - { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << vk; - std::vector data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; - } - std::string operator()(const libzcash::SaplingIncomingViewingKey& vk) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -152,17 +133,6 @@ private: public: SpendingKeyEncoder(const CChainParams& params) : m_params(params) {} - std::string operator()(const libzcash::SproutSpendingKey& zkey) const - { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << zkey; - std::vector data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY); - data.insert(data.end(), ss.begin(), ss.end()); - std::string ret = EncodeBase58Check(data); - memory_cleanse(data.data(), data.size()); - return ret; - } - std::string operator()(const libzcash::SaplingExtendedSpendingKey& zkey) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -324,18 +294,6 @@ std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) libzcash::PaymentAddress DecodePaymentAddress(const std::string& str) { std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& zaddr_prefix = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS); - if ((data.size() == libzcash::SerializedSproutPaymentAddressSize + zaddr_prefix.size()) && - std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SproutPaymentAddress ret; - ss >> ret; - return ret; - } - } - data.clear(); auto bech = bech32::Decode(str); if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS) && bech.second.size() == ConvertedSaplingPaymentAddressSize) { diff --git a/src/keystore.cpp b/src/keystore.cpp index 34bab456c..ca4fa3712 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -128,15 +129,6 @@ bool CBasicKeyStore::HaveWatchOnly() const return (!setWatchOnly.empty()); } -bool CBasicKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) -{ - LOCK(cs_SpendingKeyStore); - auto address = sk.address(); - mapSproutSpendingKeys[address] = sk; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key()))); - return true; -} - //! Sapling bool CBasicKeyStore::AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, @@ -155,14 +147,6 @@ bool CBasicKeyStore::AddSaplingSpendingKey( return true; } -bool CBasicKeyStore::AddSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - LOCK(cs_SpendingKeyStore); - auto address = vk.address(); - mapSproutViewingKeys[address] = vk; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc))); - return true; -} bool CBasicKeyStore::AddSaplingFullViewingKey( const libzcash::SaplingFullViewingKey &fvk, @@ -190,18 +174,7 @@ bool CBasicKeyStore::AddSaplingIncomingViewingKey( return true; } -bool CBasicKeyStore::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk) -{ - LOCK(cs_SpendingKeyStore); - mapSproutViewingKeys.erase(vk.address()); - return true; -} -bool CBasicKeyStore::HaveSproutViewingKey(const libzcash::SproutPaymentAddress &address) const -{ - LOCK(cs_SpendingKeyStore); - return mapSproutViewingKeys.count(address) > 0; -} bool CBasicKeyStore::HaveSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk) const { @@ -215,19 +188,6 @@ bool CBasicKeyStore::HaveSaplingIncomingViewingKey(const libzcash::SaplingPaymen return mapSaplingIncomingViewingKeys.count(addr) > 0; } -bool CBasicKeyStore::GetSproutViewingKey( - const libzcash::SproutPaymentAddress &address, - libzcash::SproutViewingKey &vkOut) const -{ - LOCK(cs_SpendingKeyStore); - SproutViewingKeyMap::const_iterator mi = mapSproutViewingKeys.find(address); - if (mi != mapSproutViewingKeys.end()) { - vkOut = mi->second; - return true; - } - return false; -} - bool CBasicKeyStore::GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingFullViewingKey &fvkOut) const { diff --git a/src/keystore.h b/src/keystore.h index ac2ccf233..6f34d9bc4 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -120,12 +120,7 @@ protected: KeyMap mapKeys; ScriptMap mapScripts; WatchOnlySet setWatchOnly; - /* - SproutSpendingKeyMap mapSproutSpendingKeys; - SproutViewingKeyMap mapSproutViewingKeys; - NoteDecryptorMap mapNoteDecryptors; - */ - + SaplingSpendingKeyMap mapSaplingSpendingKeys; SaplingFullViewingKeyMap mapSaplingFullViewingKeys; SaplingIncomingViewingKeyMap mapSaplingIncomingViewingKeys; @@ -246,7 +241,6 @@ public: typedef std::vector > CKeyingMaterial; typedef std::map > > CryptedKeyMap; -//typedef std::map > CryptedSproutSpendingKeyMap; //! Sapling typedef std::map > CryptedSaplingSpendingKeyMap; diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h index 28a1d4cdc..5c3a20c33 100644 --- a/src/paymentdisclosure.h +++ b/src/paymentdisclosure.h @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index fb3e21137..a41a8169d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -204,7 +204,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"version\": xxxxx, (numeric) the server version\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total Komodo balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total Hush balance of the wallet\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"timeoffset\": xxxxx, (numeric) the time offset\n" " \"connections\": xxxxx, (numeric) the number of connections\n" @@ -590,30 +590,6 @@ UniValue validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk } -class DescribePaymentAddressVisitor : public boost::static_visitor -{ -public: - UniValue operator()(const libzcash::InvalidEncoding &zaddr) const { return UniValue(UniValue::VOBJ); } - - UniValue operator()(const libzcash::SaplingPaymentAddress &zaddr) const { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("type", "sapling")); - obj.push_back(Pair("diversifier", HexStr(zaddr.d))); - obj.push_back(Pair("diversifiedtransmissionkey", zaddr.pk_d.GetHex())); -#ifdef ENABLE_WALLET - if (pwalletMain) { - libzcash::SaplingIncomingViewingKey ivk; - libzcash::SaplingFullViewingKey fvk; - bool isMine = pwalletMain->GetSaplingIncomingViewingKey(zaddr, ivk) && - pwalletMain->GetSaplingFullViewingKey(ivk, fvk) && - pwalletMain->HaveSaplingSpendingKey(fvk); - obj.push_back(Pair("ismine", isMine)); - } -#endif - return obj; - } -}; - UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 1) @@ -650,11 +626,25 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& my UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); - if (isValid) + auto zaddr = boost::get(&address); + if (isValid && (zaddr != nullptr)) { ret.push_back(Pair("address", strAddress)); - UniValue detail = boost::apply_visitor(DescribePaymentAddressVisitor(), address); - ret.pushKVs(detail); + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("type", "sapling")); + obj.push_back(Pair("diversifier", HexStr(zaddr->d))); + obj.push_back(Pair("diversifiedtransmissionkey", zaddr->pk_d.GetHex())); +#ifdef ENABLE_WALLET + if (pwalletMain) { + libzcash::SaplingIncomingViewingKey ivk; + libzcash::SaplingFullViewingKey fvk; + bool isMine = pwalletMain->GetSaplingIncomingViewingKey(*zaddr, ivk) && + pwalletMain->GetSaplingFullViewingKey(ivk, fvk) && + pwalletMain->HaveSaplingSpendingKey(fvk); + obj.push_back(Pair("ismine", isMine)); + } +#endif + ret.pushKVs(obj); } return ret; } @@ -733,9 +723,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp, const CPubKey& mypk) "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keys\" (string, required) A json array of keys which are Komodo addresses or hex-encoded public keys\n" + "2. \"keys\" (string, required) A json array of keys which are Hush addresses or hex-encoded public keys\n" " [\n" - " \"key\" (string) Komodo address or hex-encoded public key\n" + " \"key\" (string) Hush address or hex-encoded public key\n" " ,...\n" " ]\n" @@ -769,10 +759,10 @@ UniValue verifymessage(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (fHelp || params.size() != 3) throw runtime_error( - "verifymessage \"komodoaddress\" \"signature\" \"message\"\n" + "verifymessage \"hushaddress\" \"signature\" \"message\"\n" "\nVerify a signed message\n" "\nArguments:\n" - "1. \"komodoaddress\" (string, required) The Komodo address to use for the signature.\n" + "1. \"hushaddress\" (string, required) The Hush address to use for the signature.\n" "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n" "3. \"message\" (string, required) The message that was signed.\n" "\nResult:\n" diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 107188779..2abe2d782 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -571,9 +571,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) // Verify number of addresses stored in wallet is n1+n2 int numAddrs = myaddrs.size(); BOOST_CHECK(numAddrs == (2 * n1) + n2); - pwalletMain->GetSproutPaymentAddresses(addrs); pwalletMain->GetSaplingPaymentAddresses(saplingAddrs); - BOOST_CHECK(addrs.size() + saplingAddrs.size() == numAddrs); + BOOST_CHECK(saplingAddrs.size() == numAddrs); // Ask wallet to list addresses BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); @@ -595,9 +594,6 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) std::string newaddress = retValue.get_str(); auto address = DecodePaymentAddress(newaddress); BOOST_CHECK(IsValidPaymentAddress(address)); - BOOST_ASSERT(boost::get(&address) != nullptr); - auto newAddr = boost::get(address); - BOOST_CHECK(pwalletMain->HaveSproutSpendingKey(newAddr)); // Check if too many args BOOST_CHECK_THROW(CallRPC("z_getnewaddress toomanyargs"), runtime_error); diff --git a/src/utiltest.cpp b/src/utiltest.cpp deleted file mode 100644 index ead7fe6a0..000000000 --- a/src/utiltest.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Copyright (c) 2019-2020 The Hush developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "utiltest.h" - -#include "consensus/upgrades.h" - -#include - -CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, CAmount value, - bool randomInputs, - int32_t version /* = 2 */) { - CMutableTransaction mtx; - mtx.nVersion = version; - mtx.vin.resize(2); - if (randomInputs) { - mtx.vin[0].prevout.hash = GetRandHash(); - mtx.vin[1].prevout.hash = GetRandHash(); - } else { - mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); - mtx.vin[1].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); - } - mtx.vin[0].prevout.n = 0; - mtx.vin[1].prevout.n = 0; - - // Generate an ephemeral keypair. - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - mtx.joinSplitPubKey = joinSplitPubKey; - - std::array inputs = { - libzcash::JSInput(), // dummy input - libzcash::JSInput() // dummy input - }; - - std::array outputs = { - libzcash::JSOutput(sk.address(), value), - libzcash::JSOutput(sk.address(), value) - }; - - // Prepare JoinSplits - uint256 rt; - JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, - inputs, outputs, 2*value, 0, false}; - mtx.vjoinsplit.push_back(jsdesc); - - if (version >= 4) { - // Shielded Output - OutputDescription od; - mtx.vShieldedOutput.push_back(od); - } - - // Empty output script. - uint32_t consensusBranchId = SPROUT_BRANCH_ID; - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - - CTransaction tx {mtx}; - CWalletTx wtx {NULL, tx}; - return wtx; -} - -libzcash::SproutNote GetNote(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const CTransaction& tx, size_t js, size_t n) { - ZCNoteDecryption decryptor {sk.receiving_key()}; - auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); - auto note_pt = libzcash::SproutNotePlaintext::decrypt( - decryptor, - tx.vjoinsplit[js].ciphertexts[n], - tx.vjoinsplit[js].ephemeralKey, - hSig, - (unsigned char) n); - return note_pt.note(sk.address()); -} - -CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const libzcash::SproutNote& note, CAmount value) { - CMutableTransaction mtx; - mtx.vout.resize(2); - mtx.vout[0].nValue = value; - mtx.vout[1].nValue = 0; - - // Generate an ephemeral keypair. - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - mtx.joinSplitPubKey = joinSplitPubKey; - - // Fake tree for the unused witness - SproutMerkleTree tree; - - libzcash::JSOutput dummyout; - libzcash::JSInput dummyin; - - { - if (note.value() > value) { - libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random(); - libzcash::SproutPaymentAddress dummyaddr = dummykey.address(); - dummyout = libzcash::JSOutput(dummyaddr, note.value() - value); - } else if (note.value() < value) { - libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random(); - libzcash::SproutPaymentAddress dummyaddr = dummykey.address(); - libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value()), uint256(), uint256()); - tree.append(dummynote.cm()); - dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); - } - } - - tree.append(note.cm()); - - std::array inputs = { - libzcash::JSInput(tree.witness(), note, sk), - dummyin - }; - - std::array outputs = { - dummyout, // dummy output - libzcash::JSOutput() // dummy output - }; - - // Prepare JoinSplits - uint256 rt = tree.root(); - JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, - inputs, outputs, 0, value, false}; - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - uint32_t consensusBranchId = SPROUT_BRANCH_ID; - CScript scriptCode; - CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - CTransaction tx {mtx}; - CWalletTx wtx {NULL, tx}; - return wtx; -} diff --git a/src/utiltest.h b/src/utiltest.h deleted file mode 100644 index 327dc7be4..000000000 --- a/src/utiltest.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2016 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "wallet/wallet.h" -#include "zcash/JoinSplit.hpp" -#include "zcash/Note.hpp" -#include "zcash/NoteEncryption.hpp" - -CWalletTx GetValidReceive(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, CAmount value, - bool randomInputs, - int32_t version = 2); -libzcash::SproutNote GetNote(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const CTransaction& tx, size_t js, size_t n); -CWalletTx GetValidSpend(ZCJoinSplit& params, - const libzcash::SproutSpendingKey& sk, - const libzcash::SproutNote& note, CAmount value); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index b3fef0fc1..db4fb83af 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -1,4 +1,5 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -123,7 +124,6 @@ public: ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) : m_op(op), sendAmount(sendAmount) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index 38aff1a04..9d11a55fe 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -168,22 +169,6 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, - const libzcash::SproutPaymentAddress& address, - libzcash::SproutSpendingKey& sk) -{ - CKeyingMaterial vchSecret; - if (!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret)) - return false; - - if (vchSecret.size() != libzcash::SerializedSproutSpendingKeySize) - return false; - - CSecureDataStream ss(vchSecret, SER_NETWORK, PROTOCOL_VERSION); - ss >> sk; - return sk.address() == address; -} static bool DecryptSaplingSpendingKey(const CKeyingMaterial& vMasterKey, const std::vector& vchCryptedSecret, @@ -207,7 +192,7 @@ bool CCryptoKeyStore::SetCrypted() LOCK2(cs_KeyStore, cs_SpendingKeyStore); if (fUseCrypto) return true; - if (!(mapKeys.empty() && mapSproutSpendingKeys.empty() && mapSaplingSpendingKeys.empty())) + if (!(mapKeys.empty() && mapSaplingSpendingKeys.empty())) return false; fUseCrypto = true; return true; @@ -260,21 +245,6 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) if (fDecryptionThoroughlyChecked) break; } - CryptedSproutSpendingKeyMap::const_iterator miSprout = mapCryptedSproutSpendingKeys.begin(); - for (; miSprout != mapCryptedSproutSpendingKeys.end(); ++miSprout) - { - const libzcash::SproutPaymentAddress &address = (*miSprout).first; - const std::vector &vchCryptedSecret = (*miSprout).second; - libzcash::SproutSpendingKey sk; - if (!DecryptSproutSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk)) - { - keyFail = true; - break; - } - keyPass = true; - if (fDecryptionThoroughlyChecked) - break; - } CryptedSaplingSpendingKeyMap::const_iterator miSapling = mapCryptedSaplingSpendingKeys.begin(); for (; miSapling != mapCryptedSaplingSpendingKeys.end(); ++miSapling) { @@ -292,7 +262,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) } if (keyPass && keyFail) { - LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n"); + LogPrintf("Oh shit! The wallet is probably corrupted: Some keys decrypt but not all.\n"); assert(false); } if (keyFail || !keyPass) @@ -440,30 +410,6 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co return false; } -bool CCryptoKeyStore::AddSproutSpendingKey(const libzcash::SproutSpendingKey &sk) -{ - { - LOCK(cs_SpendingKeyStore); - if (!IsCrypted()) - return CBasicKeyStore::AddSproutSpendingKey(sk); - - if (IsLocked()) - return false; - - std::vector vchCryptedSecret; - CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << sk; - CKeyingMaterial vchSecret(ss.begin(), ss.end()); - auto address = sk.address(); - if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) - return false; - - if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) - return false; - } - return true; -} - bool CCryptoKeyStore::AddSaplingSpendingKey( const libzcash::SaplingExtendedSpendingKey &sk, const libzcash::SaplingPaymentAddress &defaultAddr) @@ -494,22 +440,6 @@ bool CCryptoKeyStore::AddSaplingSpendingKey( return true; } -bool CCryptoKeyStore::AddCryptedSproutSpendingKey( - const libzcash::SproutPaymentAddress &address, - const libzcash::ReceivingKey &rk, - const std::vector &vchCryptedSecret) -{ - { - LOCK(cs_SpendingKeyStore); - if (!SetCrypted()) - return false; - - mapCryptedSproutSpendingKeys[address] = vchCryptedSecret; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk))); - } - return true; -} - bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector &vchCryptedSecret, @@ -531,23 +461,6 @@ bool CCryptoKeyStore::AddCryptedSaplingSpendingKey( return true; } -bool CCryptoKeyStore::GetSproutSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const -{ - { - LOCK(cs_SpendingKeyStore); - if (!IsCrypted()) - return CBasicKeyStore::GetSproutSpendingKey(address, skOut); - - CryptedSproutSpendingKeyMap::const_iterator mi = mapCryptedSproutSpendingKeys.find(address); - if (mi != mapCryptedSproutSpendingKeys.end()) - { - const std::vector &vchCryptedSecret = (*mi).second; - return DecryptSproutSpendingKey(vMasterKey, vchCryptedSecret, address, skOut); - } - } - return false; -} - bool CCryptoKeyStore::GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingExtendedSpendingKey &skOut) const { { @@ -603,22 +516,6 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) } } mapKeys.clear(); - BOOST_FOREACH(SproutSpendingKeyMap::value_type& mSproutSpendingKey, mapSproutSpendingKeys) - { - const libzcash::SproutSpendingKey &sk = mSproutSpendingKey.second; - CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << sk; - CKeyingMaterial vchSecret(ss.begin(), ss.end()); - libzcash::SproutPaymentAddress address = sk.address(); - std::vector vchCryptedSecret; - if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) { - return false; - } - if (!AddCryptedSproutSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) { - return false; - } - } - mapSproutSpendingKeys.clear(); //! Sapling key support BOOST_FOREACH(SaplingSpendingKeyMap::value_type& mSaplingSpendingKey, mapSaplingSpendingKeys) { diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index dcc7fdfdd..0ad789137 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -139,341 +139,8 @@ TEST(WalletTests, SetupDatadirLocationRunAsFirstTest) { boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); } +/* -TEST(WalletTests, SproutNoteDataSerialisation) { - auto sk = libzcash::SproutSpendingKey::random(); - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - SproutMerkleTree tree; - nd.witnesses.push_front(tree.witness()); - noteData[jsoutpt] = nd; - - CDataStream ss(SER_DISK, CLIENT_VERSION); - ss << noteData; - - mapSproutNoteData_t noteData2; - ss >> noteData2; - - EXPECT_EQ(noteData, noteData2); - EXPECT_EQ(noteData[jsoutpt].witnesses, noteData2[jsoutpt].witnesses); -} - - -TEST(WalletTests, FindUnspentSproutNotes) { - SelectParams(CBaseChainParams::TESTNET); - CWallet wallet; - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - // We currently have an unspent and unconfirmed note in the wallet (depth of -1) - std::vector sproutEntries; - std::vector saplingEntries; - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", -1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - // Fake-mine the transaction - EXPECT_EQ(-1, chainActive.Height()); - CBlock block; - block.vtx.push_back(wtx); - block.hashMerkleRoot = block.BuildMerkleTree(); - auto blockHash = block.GetHash(); - CBlockIndex fakeIndex {block}; - mapBlockIndex.insert(std::make_pair(blockHash, &fakeIndex)); - chainActive.SetTip(&fakeIndex); - EXPECT_TRUE(chainActive.Contains(&fakeIndex)); - EXPECT_EQ(0, chainActive.Height()); - - wtx.SetMerkleBranch(block); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - - // We now have an unspent and confirmed note in the wallet (depth of 1) - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - - // Let's spend the note. - auto wtx2 = GetValidSpend(sk, note, 5); - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - // Fake-mine a spend transaction - EXPECT_EQ(0, chainActive.Height()); - CBlock block2; - block2.vtx.push_back(wtx2); - block2.hashMerkleRoot = block2.BuildMerkleTree(); - block2.hashPrevBlock = blockHash; - auto blockHash2 = block2.GetHash(); - CBlockIndex fakeIndex2 {block2}; - mapBlockIndex.insert(std::make_pair(blockHash2, &fakeIndex2)); - fakeIndex2.SetHeight(1); - chainActive.SetTip(&fakeIndex2); - EXPECT_TRUE(chainActive.Contains(&fakeIndex2)); - EXPECT_EQ(1, chainActive.Height()); - - wtx2.SetMerkleBranch(block2); - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_TRUE(wallet.IsSproutSpent(nullifier)); - - // The note has been spent. By default, GetFilteredNotes() ignores spent notes. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Let's include spent notes to retrieve it. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 0, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // The spent note has two confirmations. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // It does not have 3 confirmations. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 3, false); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - - // Let's receive a new note - CWalletTx wtx3; - { - auto wtx = GetValidReceive(sk, 20, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_FALSE(wallet.IsSproutSpent(nullifier)); - - wtx3 = wtx; - } - - // Fake-mine the new transaction - EXPECT_EQ(1, chainActive.Height()); - CBlock block3; - block3.vtx.push_back(wtx3); - block3.hashMerkleRoot = block3.BuildMerkleTree(); - block3.hashPrevBlock = blockHash2; - auto blockHash3 = block3.GetHash(); - CBlockIndex fakeIndex3 {block3}; - mapBlockIndex.insert(std::make_pair(blockHash3, &fakeIndex3)); - fakeIndex3.SetHeight(2); - chainActive.SetTip(&fakeIndex3); - EXPECT_TRUE(chainActive.Contains(&fakeIndex3)); - EXPECT_EQ(2, chainActive.Height()); - - wtx3.SetMerkleBranch(block3); - wallet.AddToWallet(wtx3, true, NULL); - - // We now have an unspent note which has one confirmation, in addition to our spent note. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Let's return the spent note too. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 1, false); - EXPECT_EQ(2, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // Increasing number of confirmations will exclude our new unspent note. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, false); - EXPECT_EQ(1, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - // If we also ignore spent notes at this depth, we won't find any notes. - wallet.GetFilteredNotes(sproutEntries, saplingEntries, "", 2, true); - EXPECT_EQ(0, sproutEntries.size()); - sproutEntries.clear(); - saplingEntries.clear(); - - // Tear down - chainActive.SetTip(NULL); - mapBlockIndex.erase(blockHash); - mapBlockIndex.erase(blockHash2); - mapBlockIndex.erase(blockHash3); -} - - -TEST(WalletTests, SetSproutNoteAddrsInCWalletTx) { - auto sk = libzcash::SproutSpendingKey::random(); - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - EXPECT_EQ(0, wtx.mapSproutNoteData.size()); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - EXPECT_EQ(noteData, wtx.mapSproutNoteData); -} - -TEST(WalletTests, SetSaplingNoteAddrsInCWalletTx) { - SelectParams(CBaseChainParams::REGTEST); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); - auto consensusParams = Params().GetConsensus(); - - TestWallet wallet; - - std::vector> rawSeed(32); - HDSeed seed(rawSeed); - auto sk = libzcash::SaplingExtendedSpendingKey::Master(seed); - auto expsk = sk.expsk; - auto fvk = expsk.full_viewing_key(); - auto ivk = fvk.in_viewing_key(); - auto pk = sk.DefaultAddress(); - - libzcash::SaplingNote note(pk, 50000); - auto cm = note.cm().get(); - SaplingMerkleTree tree; - tree.append(cm); - auto anchor = tree.root(); - auto witness = tree.witness(); - - auto nf = note.nullifier(fvk, witness.position()); - ASSERT_TRUE(nf); - uint256 nullifier = nf.get(); - - auto builder = TransactionBuilder(consensusParams, 1); - ASSERT_TRUE(builder.AddSaplingSpend(expsk, note, anchor, witness)); - builder.AddSaplingOutput(fvk.ovk, pk, 50000, {}); - builder.SetFee(0); - auto maybe_tx = builder.Build(); - ASSERT_EQ(static_cast(maybe_tx), true); - auto tx = maybe_tx.get(); - - CWalletTx wtx {&wallet, tx}; - - EXPECT_EQ(0, wtx.mapSaplingNoteData.size()); - mapSaplingNoteData_t noteData; - - SaplingOutPoint op {wtx.GetHash(), 0}; - SaplingNoteData nd; - nd.nullifier = nullifier; - nd.ivk = ivk; - nd.witnesses.push_front(witness); - nd.witnessHeight = 123; - noteData.insert(std::make_pair(op, nd)); - - wtx.SetSaplingNoteData(noteData); - EXPECT_EQ(noteData, wtx.mapSaplingNoteData); - - // Test individual fields in case equality operator is defined/changed. - EXPECT_EQ(ivk, wtx.mapSaplingNoteData[op].ivk); - EXPECT_EQ(nullifier, wtx.mapSaplingNoteData[op].nullifier); - EXPECT_EQ(nd.witnessHeight, wtx.mapSaplingNoteData[op].witnessHeight); - EXPECT_TRUE(witness == wtx.mapSaplingNoteData[op].witnesses.front()); - - // Revert to default - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); - UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); -} - -TEST(WalletTests, SetSproutInvalidNoteAddrsInCWalletTx) { - CWalletTx wtx; - EXPECT_EQ(0, wtx.mapSproutNoteData.size()); - - mapSproutNoteData_t noteData; - auto sk = libzcash::SproutSpendingKey::random(); - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), uint256()}; - noteData[jsoutpt] = nd; - - EXPECT_THROW(wtx.SetSproutNoteData(noteData), std::logic_error); -} - -// The following test is the same as SetInvalidSaplingNoteDataInCWalletTx -// TEST(WalletTests, SetSaplingInvalidNoteAddrsInCWalletTx) - -// Cannot add note data for an index which does not exist in tx.vShieldedOutput -TEST(WalletTests, SetInvalidSaplingNoteDataInCWalletTx) { - CWalletTx wtx; - EXPECT_EQ(0, wtx.mapSaplingNoteData.size()); - - mapSaplingNoteData_t noteData; - SaplingOutPoint op {uint256(), 1}; - SaplingNoteData nd; - noteData.insert(std::make_pair(op, nd)); - - EXPECT_THROW(wtx.SetSaplingNoteData(noteData), std::logic_error); -} - -TEST(WalletTests, GetSproutNoteNullifier) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - auto address = sk.address(); - auto dec = ZCNoteDecryption(sk.receiving_key()); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto hSig = wtx.vjoinsplit[0].h_sig( - *params, wtx.joinSplitPubKey); - - auto ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], - address, - dec, - hSig, 1); - EXPECT_NE(nullifier, ret); - - wallet.AddSproutSpendingKey(sk); - - ret = wallet.GetSproutNoteNullifier( - wtx.vjoinsplit[0], - address, - dec, - hSig, 1); - EXPECT_EQ(nullifier, ret); -} TEST(WalletTests, FindMySaplingNotes) { SelectParams(CBaseChainParams::REGTEST); @@ -577,92 +244,6 @@ TEST(WalletTests, FindMySaplingNotesWithIvkOnly) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } -TEST(WalletTests, FindMySproutNotes) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - auto sk2 = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk2); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(0, noteMap.size()); - - wallet.AddSproutSpendingKey(sk); - - noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_EQ(nd, noteMap[jsoutpt]); -} - -TEST(WalletTests, FindMySproutNotesInEncryptedWallet) { - TestWallet wallet; - uint256 r {GetRandHash()}; - CKeyingMaterial vMasterKey (r.begin(), r.end()); - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_NE(nd, noteMap[jsoutpt]); - - ASSERT_TRUE(wallet.Unlock(vMasterKey)); - - noteMap = wallet.FindMySproutNotes(wtx); - EXPECT_EQ(2, noteMap.size()); - EXPECT_EQ(1, noteMap.count(jsoutpt)); - EXPECT_EQ(nd, noteMap[jsoutpt]); -} - -TEST(WalletTests, GetConflictedSproutNotes) { - CWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - auto wtx2 = GetValidSpend(sk, note, 5); - auto wtx3 = GetValidSpend(sk, note, 10); - auto hash2 = wtx2.GetHash(); - auto hash3 = wtx3.GetHash(); - - // No conflicts for no spends - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - wallet.AddToWallet(wtx, true, NULL); - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - - // No conflicts for one spend - wallet.AddToWallet(wtx2, true, NULL); - EXPECT_EQ(0, wallet.GetConflicts(hash2).size()); - - // Conflicts for two spends - wallet.AddToWallet(wtx3, true, NULL); - auto c3 = wallet.GetConflicts(hash2); - EXPECT_EQ(2, c3.size()); - EXPECT_EQ(std::set({hash2, hash3}), c3); -} - // Generate note A and spend to create note B, from which we spend to create two conflicting transactions TEST(WalletTests, GetConflictedSaplingNotes) { SelectParams(CBaseChainParams::REGTEST); @@ -1735,88 +1316,6 @@ TEST(WalletTests, SetBestChainIgnoresTxsWithoutShieldedData) { wallet.SetBestChain(walletdb, loc); } -TEST(WalletTests, UpdateSproutNullifierNoteMap) { - TestWallet wallet; - uint256 r {GetRandHash()}; - CKeyingMaterial vMasterKey (r.begin(), r.end()); - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - ASSERT_TRUE(wallet.EncryptKeys(vMasterKey)); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - - // Pretend that we called FindMySproutNotes while the wallet was locked - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 1}; - SproutNoteData nd {sk.address()}; - noteData[jsoutpt] = nd; - wtx.SetSproutNoteData(noteData); - - wallet.AddToWallet(wtx, true, NULL); - EXPECT_EQ(0, wallet.mapSproutNullifiersToNotes.count(nullifier)); - - EXPECT_FALSE(wallet.UpdateNullifierNoteMap()); - - ASSERT_TRUE(wallet.Unlock(vMasterKey)); - - EXPECT_TRUE(wallet.UpdateNullifierNoteMap()); - EXPECT_EQ(1, wallet.mapSproutNullifiersToNotes.count(nullifier)); - EXPECT_EQ(wtx.GetHash(), wallet.mapSproutNullifiersToNotes[nullifier].hash); - EXPECT_EQ(0, wallet.mapSproutNullifiersToNotes[nullifier].js); - EXPECT_EQ(1, wallet.mapSproutNullifiersToNotes[nullifier].n); -} - -TEST(WalletTests, UpdatedSproutNoteData) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto note = GetNote(sk, wtx, 0, 0); - auto note2 = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - auto nullifier2 = note2.nullifier(sk); - auto wtx2 = wtx; - - // First pretend we added the tx to the wallet and - // we don't have the key for the second note - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {wtx.GetHash(), 0, 0}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - wtx.SetSproutNoteData(noteData); - - // Pretend we mined the tx by adding a fake witness - SproutMerkleTree tree; - wtx.mapSproutNoteData[jsoutpt].witnesses.push_front(tree.witness()); - wtx.mapSproutNoteData[jsoutpt].witnessHeight = 100; - - // Now pretend we added the key for the second note, and - // the tx was "added" to the wallet again to update it. - // This happens via the 'z_importkey' RPC method. - JSOutPoint jsoutpt2 {wtx2.GetHash(), 0, 1}; - SproutNoteData nd2 {sk.address(), nullifier2}; - noteData[jsoutpt2] = nd2; - wtx2.SetSproutNoteData(noteData); - - // The txs should initially be different - EXPECT_NE(wtx.mapSproutNoteData, wtx2.mapSproutNoteData); - EXPECT_EQ(1, wtx.mapSproutNoteData[jsoutpt].witnesses.size()); - EXPECT_EQ(100, wtx.mapSproutNoteData[jsoutpt].witnessHeight); - - // After updating, they should be the same - EXPECT_TRUE(wallet.UpdatedNoteData(wtx2, wtx)); - EXPECT_EQ(wtx.mapSproutNoteData, wtx2.mapSproutNoteData); - EXPECT_EQ(1, wtx.mapSproutNoteData[jsoutpt].witnesses.size()); - EXPECT_EQ(100, wtx.mapSproutNoteData[jsoutpt].witnessHeight); - // TODO: The new note should get witnessed (but maybe not here) (#1350) -} - TEST(WalletTests, UpdatedSaplingNoteData) { SelectParams(CBaseChainParams::REGTEST); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); @@ -1941,37 +1440,6 @@ TEST(WalletTests, UpdatedSaplingNoteData) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } -TEST(WalletTests, MarkAffectedSproutTransactionsDirty) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto hash = wtx.GetHash(); - auto note = GetNote(sk, wtx, 0, 1); - auto nullifier = note.nullifier(sk); - auto wtx2 = GetValidSpend(sk, note, 5); - - mapSproutNoteData_t noteData; - JSOutPoint jsoutpt {hash, 0, 1}; - SproutNoteData nd {sk.address(), nullifier}; - noteData[jsoutpt] = nd; - - wtx.SetSproutNoteData(noteData); - wallet.AddToWallet(wtx, true, NULL); - wallet.MarkAffectedTransactionsDirty(wtx); - - // After getting a cached value, the first tx should be clean - wallet.mapWallet[hash].GetDebit(ISMINE_ALL); - EXPECT_TRUE(wallet.mapWallet[hash].fDebitCached); - - // After adding the note spend, the first tx should be dirty - wallet.AddToWallet(wtx2, true, NULL); - wallet.MarkAffectedTransactionsDirty(wtx2); - EXPECT_FALSE(wallet.mapWallet[hash].fDebitCached); -} - TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { SelectParams(CBaseChainParams::REGTEST); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); @@ -1999,7 +1467,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { auto scriptPubKey = GetScriptForDestination(tsk.GetPubKey().GetID()); // Generate shielding tx from transparent to Sapling - // 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 t-ZEC fee + // 0.0005 t-HUSH in, 0.0004 z-HUSH out, 0.0001 t-HUSH fee auto builder = TransactionBuilder(consensusParams, 1, &keystore); builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000); builder.AddSaplingOutput(fvk.ovk, pk, 40000, {}); @@ -2093,39 +1561,7 @@ TEST(WalletTests, MarkAffectedSaplingTransactionsDirty) { UpdateNetworkUpgradeParameters(Consensus::UPGRADE_SAPLING, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); } - -TEST(WalletTests, SproutNoteLocking) { - TestWallet wallet; - - auto sk = libzcash::SproutSpendingKey::random(); - wallet.AddSproutSpendingKey(sk); - - auto wtx = GetValidReceive(sk, 10, true); - auto wtx2 = GetValidReceive(sk, 10, true); - - JSOutPoint jsoutpt {wtx.GetHash(), 0, 0}; - JSOutPoint jsoutpt2 {wtx2.GetHash(),0, 0}; - - // Test selective locking - wallet.LockNote(jsoutpt); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt)); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt2)); - - // Test selective unlocking - wallet.UnlockNote(jsoutpt); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt)); - - // Test multiple locking - wallet.LockNote(jsoutpt); - wallet.LockNote(jsoutpt2); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt)); - EXPECT_TRUE(wallet.IsLockedNote(jsoutpt2)); - - // Test unlock all - wallet.UnlockAllSproutNotes(); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt)); - EXPECT_FALSE(wallet.IsLockedNote(jsoutpt2)); -} +*/ TEST(WalletTests, SaplingNoteLocking) { TestWallet wallet; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 37f67042b..d3d396bbc 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5487,34 +5487,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp "Cannot send between Sprout and Sapling addresses using z_mergetoaddress"); } - // Find unspent notes and update estimated size - for (const CSproutNotePlaintextEntry& entry : sproutEntries) { - noteCounter++; - CAmount nValue = entry.plaintext.value(); - - if (!maxedOutNotesFlag) { - // If we haven't added any notes yet and the merge is to a - // z-address, we have already accounted for the first JoinSplit. - size_t increase = (sproutNoteInputs.empty() && !isToSproutZaddr) || (sproutNoteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; - if (estimatedTxSize + increase >= max_tx_size || - (sproutNoteLimit > 0 && noteCounter > sproutNoteLimit)) - { - maxedOutNotesFlag = true; - } else { - estimatedTxSize += increase; - auto zaddr = entry.address; - SproutSpendingKey zkey; - pwalletMain->GetSproutSpendingKey(zaddr, zkey); - sproutNoteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); - mergedNoteValue += nValue; - } - } - - if (maxedOutNotesFlag) { - remainingNoteValue += nValue; - } - } - for (const SaplingNoteEntry& entry : saplingEntries) { noteCounter++; CAmount nValue = entry.note.value(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d82e100ed..f3526c583 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1408,7 +1408,6 @@ private: public: PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1421,7 +1420,6 @@ private: public: IncomingViewingKeyBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1433,7 +1431,6 @@ private: public: HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1445,7 +1442,6 @@ private: public: GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} - boost::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; boost::optional operator()(const libzcash::InvalidEncoding& no) const; }; @@ -1517,7 +1513,6 @@ public: ) : m_wallet(wallet), params(params), nTime(_nTime), hdKeypath(_hdKeypath), seedFpStr(_seedFp), log(_log) {} - SpendingKeyAddResult operator()(const libzcash::SproutSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::SaplingExtendedSpendingKey &sk) const; SpendingKeyAddResult operator()(const libzcash::InvalidEncoding& no) const; }; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 1177bbedd..71331ed93 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -653,6 +653,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "czkey") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another @@ -663,12 +664,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ssValue >> vchCryptedSecret; wss.nCKeys++; - //if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) - //{ - // strErr = "Error reading wallet database: LoadCryptedZKey failed"; - // return false; - //} - //wss.fIsEncrypted = true; + if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) + { + strErr = "Error reading wallet database: LoadCryptedZKey failed"; + return false; + } + wss.fIsEncrypted = true; + */ } else if (strType == "csapzkey") { @@ -704,11 +706,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, } else if (strType == "zkeymeta") { + /* libzcash::SproutPaymentAddress addr; ssKey >> addr; CKeyMetadata keyMeta; ssValue >> keyMeta; wss.nZKeyMeta++; + */ // pwallet->LoadZKeyMetadata(addr, keyMeta); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 9069e3a08..64a4817d9 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -1,7 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers +// Copyright (c) 2009-2013 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -199,23 +200,15 @@ public: bool WriteHDChain(const CHDChain& chain); /// Write spending key to wallet database, where key is payment address and value is spending key. - bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta); bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta); bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk); - bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr, - const libzcash::ReceivingKey & rk, - const std::vector& vchCryptedSecret, - const CKeyMetadata &keyMeta); bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); - bool WriteSproutViewingKey(const libzcash::SproutViewingKey &vk); - bool EraseSproutViewingKey(const libzcash::SproutViewingKey &vk); - private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index 148cd321c..5ce66a82f 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -1,3 +1,7 @@ +// Copyright (c) 2019-2020 The Hush developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php + #include "Address.hpp" #include "NoteEncryption.hpp" #include "hash.h" @@ -13,36 +17,6 @@ const uint32_t SAPLING_BRANCH_ID = 0x76b809bb; namespace libzcash { -uint256 SproutPaymentAddress::GetHash() const { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << *this; - return Hash(ss.begin(), ss.end()); -} - -uint256 ReceivingKey::pk_enc() const { - return ZCNoteEncryption::generate_pubkey(*this); -} - -SproutPaymentAddress SproutViewingKey::address() const { - return SproutPaymentAddress(a_pk, sk_enc.pk_enc()); -} - -ReceivingKey SproutSpendingKey::receiving_key() const { - return ReceivingKey(ZCNoteEncryption::generate_privkey(*this)); -} - -SproutViewingKey SproutSpendingKey::viewing_key() const { - return SproutViewingKey(PRF_addr_a_pk(*this), receiving_key()); -} - -SproutSpendingKey SproutSpendingKey::random() { - return SproutSpendingKey(random_uint252()); -} - -SproutPaymentAddress SproutSpendingKey::address() const { - return viewing_key().address(); -} - //! Sapling uint256 SaplingPaymentAddress::GetHash() const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -119,10 +93,6 @@ class IsValidAddressForNetwork : public boost::static_visitor { public: IsValidAddressForNetwork(uint32_t consensusBranchId) : branchId(consensusBranchId) {} - bool operator()(const libzcash::SproutPaymentAddress &addr) const { - return true; - } - bool operator()(const libzcash::InvalidEncoding &addr) const { return false; } diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 9af3c184a..152ad7295 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -25,7 +25,6 @@ #include "sodium.h" #include "streams.h" #include "txdb.h" -#include "utiltest.h" #include "wallet/wallet.h" #include "zcbenchmarks.h" @@ -41,7 +40,7 @@ void pre_wallet_load() { LogPrintf("%s: In progress...\n", __func__); if (ShutdownRequested()) - throw new std::runtime_error("The node is shutting down"); + throw new std::runtime_error("The Hush node is shutting down"); if (pwalletMain) pwalletMain->Flush(false); @@ -93,37 +92,6 @@ double benchmark_sleep() return timer_stop(tv_start); } -std::vector benchmark_create_joinsplit_threaded(int nThreads) -{ - std::vector ret; - std::vector> tasks; - std::vector threads; - for (int i = 0; i < nThreads; i++) { - std::packaged_task task(&benchmark_create_joinsplit); - tasks.emplace_back(task.get_future()); - threads.emplace_back(std::move(task)); - } - std::future_status status; - for (auto it = tasks.begin(); it != tasks.end(); it++) { - it->wait(); - ret.push_back(it->get()); - } - for (auto it = threads.begin(); it != threads.end(); it++) { - it->join(); - } - return ret; -} - -double benchmark_verify_joinsplit(const JSDescription &joinsplit) -{ - struct timeval tv_start; - timer_start(tv_start); - uint256 joinSplitPubKey; - auto verifier = libzcash::ProofVerifier::Strict(); - joinsplit.Verify(*pzcashParams, verifier, joinSplitPubKey); - return timer_stop(tv_start); -} - #ifdef ENABLE_MINING double benchmark_solve_equihash() { From 2c661422928dd1de743b02f29c0dc88cb24608e5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 01:22:51 -0400 Subject: [PATCH 137/220] desprout --- src/key_io.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/key_io.cpp b/src/key_io.cpp index dd4bf884c..2626a0b9b 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -321,20 +321,6 @@ std::string EncodeViewingKey(const libzcash::ViewingKey& vk) libzcash::ViewingKey DecodeViewingKey(const std::string& str) { std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& vk_prefix = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY); - if ((data.size() == libzcash::SerializedSproutViewingKeySize + vk_prefix.size()) && - std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + vk_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SproutViewingKey ret; - ss >> ret; - memory_cleanse(serialized.data(), serialized.size()); - memory_cleanse(data.data(), data.size()); - return ret; - } - } - data.clear(); auto bech = bech32::Decode(str); if(bech.first == Params().Bech32HRP(CChainParams::SAPLING_INCOMING_VIEWING_KEY) && bech.second.size() == ConvertedSaplingIncomingViewingKeySize) { From 42a862650b4cfbe7a3f0c156cef68be4f7fa3a99 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 01:34:55 -0400 Subject: [PATCH 138/220] desprout --- src/key_io.cpp | 14 -------------- src/key_io.h | 1 + src/test/coins_tests.cpp | 17 +---------------- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/key_io.cpp b/src/key_io.cpp index 2626a0b9b..319c24eef 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -344,20 +344,6 @@ std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey) libzcash::SpendingKey DecodeSpendingKey(const std::string& str) { std::vector data; - if (DecodeBase58Check(str, data)) { - const std::vector& zkey_prefix = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY); - if ((data.size() == libzcash::SerializedSproutSpendingKeySize + zkey_prefix.size()) && - std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) { - CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end()); - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SproutSpendingKey ret; - ss >> ret; - memory_cleanse(serialized.data(), serialized.size()); - memory_cleanse(data.data(), data.size()); - return ret; - } - } - data.clear(); auto bech = bech32::Decode(str); if (bech.first == Params().Bech32HRP(CChainParams::SAPLING_EXTENDED_SPEND_KEY) && bech.second.size() == ConvertedSaplingExtendedSpendingKeySize) { diff --git a/src/key_io.h b/src/key_io.h index 013469ab6..567c9a2f2 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -1,6 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin Core developers // Copyright (c) 2016-2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index bb6432a81..8067b42b9 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -39,22 +40,6 @@ public: hashBestSaplingAnchor_ = SaplingMerkleTree::empty_root(); } - bool GetSproutAnchorAt(const uint256& rt, SproutMerkleTree &tree) const { - if (rt == SproutMerkleTree::empty_root()) { - SproutMerkleTree new_tree; - tree = new_tree; - return true; - } - - std::map::const_iterator it = mapSproutAnchors_.find(rt); - if (it == mapSproutAnchors_.end()) { - return false; - } else { - tree = it->second; - return true; - } - } - bool GetSaplingAnchorAt(const uint256& rt, SaplingMerkleTree &tree) const { if (rt == SaplingMerkleTree::empty_root()) { SaplingMerkleTree new_tree; From f7b1c1f26f537c4ba79eef257360aa81ce4a3208 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 07:20:38 -0400 Subject: [PATCH 139/220] Delete Payment Disclosures This code will be "experimental" forever, only supports Sprout, and is a piece of shit. Deleting with fire. Sapling viewing keys are the replacement, which already exist. --- doc/payment-disclosure.md | 107 ------ qa/pull-tester/rpc-tests.sh | 1 - qa/rpc-tests/paymentdisclosure.py | 215 ------------ src/Makefile.am | 7 - src/gtest/test_paymentdisclosure.cpp | 211 ------------ src/paymentdisclosure.cpp | 65 ---- src/paymentdisclosure.h | 149 -------- src/paymentdisclosuredb.cpp | 93 ----- src/paymentdisclosuredb.h | 42 --- .../asyncrpcoperation_mergetoaddress.cpp | 20 +- src/wallet/asyncrpcoperation_mergetoaddress.h | 7 +- src/wallet/asyncrpcoperation_sendmany.cpp | 17 +- src/wallet/asyncrpcoperation_sendmany.h | 7 +- .../asyncrpcoperation_shieldcoinbase.cpp | 19 - src/wallet/asyncrpcoperation_shieldcoinbase.h | 7 - src/wallet/rpcdisclosure.cpp | 324 ------------------ src/zcash/NoteEncryption.cpp | 50 +-- src/zcash/NoteEncryption.hpp | 29 +- 18 files changed, 8 insertions(+), 1362 deletions(-) delete mode 100644 doc/payment-disclosure.md delete mode 100755 qa/rpc-tests/paymentdisclosure.py delete mode 100644 src/gtest/test_paymentdisclosure.cpp delete mode 100644 src/paymentdisclosure.cpp delete mode 100644 src/paymentdisclosure.h delete mode 100644 src/paymentdisclosuredb.cpp delete mode 100644 src/paymentdisclosuredb.h delete mode 100644 src/wallet/rpcdisclosure.cpp diff --git a/doc/payment-disclosure.md b/doc/payment-disclosure.md deleted file mode 100644 index 02b4167da..000000000 --- a/doc/payment-disclosure.md +++ /dev/null @@ -1,107 +0,0 @@ -# Payment Disclosure (Experimental Feature) - -**Summary** - -Use RPC calls `z_getpaymentdisclosure` and `z_validatepaymentdisclosure` to reveal details of a shielded payment. - -**Who should read this document** - -Frequent users of shielded transactions, payment processors, exchanges, block explorer - -### Experimental Feature - -This is an experimental feature. Enable it by launching `zcashd` with flags: - - zcashd -experimentalfeatures -paymentdisclosure -debug=paymentdisclosure -txindex=1 - -These flags can also be set as options in `zcash.conf`. - -All nodes that generate or validate payment disclosures must run with `txindex=1` enabled. - -### Background - -Payment Disclosure is an implementation of the work-in-progress Payment Disclosure ZIP [1]. - -The ZIP describes a method of proving that a payment was sent to a shielded address. In the typical case, this means enabling a sender to present a proof that they transferred funds to a recipient's shielded address. - -[1] https://github.com/zcash/zips/pull/119 - -### Example Use Case - -Alice the customer sends 10 HUSH to Bob the merchant at the shielded address shown on their website. However, Bob is not sure if he received the funds. - -Alice's node is running with payment disclosure enabled, so Alice generates a payment disclosure and provides it to Bob, who verifies the payment was made. - -If Bob is a bad merchant, Alice can present the payment disclosure to a third party to validate that payment was indeed made. - -### Solution - -A payment disclosure can be generated for any output of a JoinSplit using the RPC call: - - z_getpaymentdisclosure txid js_index output_index (message) - -An optional message can be supplied. This could be used for a refund address or some other reference, as currently it is not common practice to (ahead of time) include a refund address in the memo field when making a payment. - -To validate a payment disclosure, the following RPC call can be used: - - z_validatepaymentdisclosure hexdata - -### Example - -Generate a payment disclosure for the first joinsplit, second output (index starts from zero): - - hush-cli z_getpaymentdisclosure 79189528d611e811a1c7bb0358dd31343033d14b4c1e998d7c4799c40f8b652b 0 1 "Hello" - -This returns a payment disclosure in the form of a hex string: - - 706462ff000a3722aafa8190cdf9710bfad6da2af6d3a74262c1fc96ad47df814b0cd5641c2b658b0fc499477c8d991e4c4bd133303431dd5803bbc7a111e811d6289518790000000000000000017e861adb829d8cb1cbcf6330b8c2e25fb0d08041a67a857815a136f0227f8a5342bce5b3c0d894e2983000eb594702d3c1580817d0374e15078528e56bb6f80c0548656c6c6f59a7085395c9e706d82afe3157c54ad4ae5bf144fcc774a8d9c921c58471402019c156ec5641e2173c4fb6467df5f28530dc4636fa71f4d0e48fc5c560fac500 - -To validate the payment disclosure: - - hush-cli z_validatepaymentdisclosure HEXDATA - -This returns data related to the payment and the payment disclosure: - - { - "txid": "79189528d611e811a1c7bb0358dd31343033d14b4c1e998d7c4799c40f8b652b", - "jsIndex": 0, - "outputIndex": 1, - "version": 0, - "onetimePrivKey": "1c64d50c4b81df47ad96fcc16242a7d3f62adad6fa0b71f9cd9081faaa22370a", - "message": "Hello", - "joinSplitPubKey": "d1c465d16166b602992479acfac18e87dc18065f6cefde6a002e70bc371b9faf", - "signatureVerified": true, - "paymentAddress": "ztaZJXy8iX8nrk2ytXKDBoTWqPkhQcj6E2ifARnD3wfkFwsxXs5SoX7NGmrjkzSiSKn8VtLHTJae48vX5NakvmDhtGNY5eb", - "memo": "f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "value": 12.49900000, - "commitmentMatch": true, - "valid": true - } - -The `signatureVerified` field confirms that the payment disclosure was generated and signed with the joinSplitPrivKey, which should only be known by the node generating and sending the transaction 7918...652b in question. - -### Where is the data stored? - -For all nodes, payment disclosure does not touch `wallet.dat` in any way. - -For nodes that only validate payment disclosures, no data is stored locally. - -For nodes that generate payment disclosures, a LevelDB database is created in the node's datadir. For most users, this would be in the folder: - - $HOME/.zcash/paymentdisclosure - -If you decide you don't want to use payment disclosure, it is safe to shut down your node and delete the database folder. - -### Security Properties - -Please consult the work-in-progress ZIP for details about the protocol, security properties and caveats. - -### Reminder - -Feedback is most welcome! - -This is an experimental feature so there are no guarantees that the protocol, database format, RPC interface etc. will remain the same in the future. - -### Notes - -Currently there is no user friendly way to help senders identify which joinsplit output index maps to a given payment they made. It is possible to construct this from `debug.log`. Ideas and feedback are most welcome on how to improve the user experience. diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index a23f2908d..94429cb7f 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -17,7 +17,6 @@ testScripts=( 'dpow.py' 'dpowconfs.py' 'ac_private.py' - 'paymentdisclosure.py' 'prioritisetransaction.py' 'wallet_treestate.py' 'wallet_anchorfork.py' diff --git a/qa/rpc-tests/paymentdisclosure.py b/qa/rpc-tests/paymentdisclosure.py deleted file mode 100755 index 48d4712a9..000000000 --- a/qa/rpc-tests/paymentdisclosure.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2017 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException -from test_framework.util import assert_equal, initialize_chain_clean, \ - start_node, connect_nodes_bi, wait_and_assert_operationid_status - -from decimal import Decimal - -class PaymentDisclosureTest (BitcoinTestFramework): - - def setup_chain(self): - print("Initializing test directory "+self.options.tmpdir) - initialize_chain_clean(self.options.tmpdir, 4) - - def setup_network(self, split=False): - args = ['-debug=zrpcunsafe,paymentdisclosure', '-experimentalfeatures', '-paymentdisclosure', '-txindex=1'] - self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, args)) - self.nodes.append(start_node(1, self.options.tmpdir, args)) - # node 2 does not enable payment disclosure - args2 = ['-debug=zrpcunsafe', '-experimentalfeatures', '-txindex=1'] - self.nodes.append(start_node(2, self.options.tmpdir, args2)) - connect_nodes_bi(self.nodes,0,1) - connect_nodes_bi(self.nodes,1,2) - connect_nodes_bi(self.nodes,0,2) - self.is_network_split=False - self.sync_all() - - def run_test (self): - print "Mining blocks..." - - self.nodes[0].generate(4) - walletinfo = self.nodes[0].getwalletinfo() - assert_equal(walletinfo['immature_balance'], 40) - assert_equal(walletinfo['balance'], 0) - self.sync_all() - self.nodes[2].generate(3) - self.sync_all() - self.nodes[1].generate(101) - self.sync_all() - assert_equal(self.nodes[0].getbalance(), 40) - assert_equal(self.nodes[1].getbalance(), 10) - assert_equal(self.nodes[2].getbalance(), 30) - - mytaddr = self.nodes[0].getnewaddress() - myzaddr = self.nodes[0].z_getnewaddress() - - # Check that Node 2 has payment disclosure disabled. - try: - self.nodes[2].z_getpaymentdisclosure("invalidtxid", 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("payment disclosure is disabled" in errorString) - - # Check that Node 0 returns an error for an unknown txid - try: - self.nodes[0].z_getpaymentdisclosure("invalidtxid", 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("No information available about transaction" in errorString) - - # Shield coinbase utxos from node 0 of value 40, standard fee of 0.00010000 - recipients = [{"address":myzaddr, "amount":Decimal('40.0')-Decimal('0.0001')}] - myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - txid = wait_and_assert_operationid_status(self.nodes[0], myopid) - - # Check the tx has joinsplits - assert( len(self.nodes[0].getrawtransaction("" + txid, 1)["vjoinsplit"]) > 0 ) - - # Sync mempools - self.sync_all() - - # Confirm that you can't create a payment disclosure for an unconfirmed tx - try: - self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Transaction has not been confirmed yet" in errorString) - - try: - self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Transaction has not been confirmed yet" in errorString) - - # Mine tx - self.nodes[0].generate(1) - self.sync_all() - - # Confirm that Node 1 cannot create a payment disclosure for a transaction which does not impact its wallet - try: - self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Transaction does not belong to the wallet" in errorString) - - # Check that an invalid joinsplit index is rejected - try: - self.nodes[0].z_getpaymentdisclosure(txid, 1, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Invalid js_index" in errorString) - - try: - self.nodes[0].z_getpaymentdisclosure(txid, -1, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Invalid js_index" in errorString) - - # Check that an invalid output index is rejected - try: - self.nodes[0].z_getpaymentdisclosure(txid, 0, 2) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Invalid output_index" in errorString) - - try: - self.nodes[0].z_getpaymentdisclosure(txid, 0, -1) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Invalid output_index" in errorString) - - # Ask Node 0 to create and validate a payment disclosure for output 0 - message = "Here is proof of my payment!" - pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 0, message) - result = self.nodes[0].z_validatepaymentdisclosure(pd) - assert(result["valid"]) - output_value_sum = Decimal(result["value"]) - - # Ask Node 1 to confirm the payment disclosure is valid - result = self.nodes[1].z_validatepaymentdisclosure(pd) - assert(result["valid"]) - assert_equal(result["message"], message) - assert_equal(result["value"], output_value_sum) - - # Confirm that payment disclosure begins with prefix zpd: - assert(pd.startswith("zpd:")) - - # Confirm that payment disclosure without prefix zpd: fails validation - try: - self.nodes[1].z_validatepaymentdisclosure(pd[4:]) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("payment disclosure prefix not found" in errorString) - - # Check that total value of output index 0 and index 1 should equal shielding amount of 40 less standard fee. - pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 1) - result = self.nodes[0].z_validatepaymentdisclosure(pd) - output_value_sum += Decimal(result["value"]) - assert_equal(output_value_sum, Decimal('39.99990000')) - - # Create a z->z transaction, sending shielded funds from node 0 to node 1 - node1zaddr = self.nodes[1].z_getnewaddress() - recipients = [{"address":node1zaddr, "amount":Decimal('1')}] - myopid = self.nodes[0].z_sendmany(myzaddr, recipients) - txid = wait_and_assert_operationid_status(self.nodes[0], myopid) - self.sync_all() - self.nodes[0].generate(1) - self.sync_all() - - # Confirm that Node 0 can create a valid payment disclosure - pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 0, "a message of your choice") - result = self.nodes[0].z_validatepaymentdisclosure(pd) - assert(result["valid"]) - - # Confirm that Node 1, even as recipient of shielded funds, cannot create a payment disclosure - # as the transaction was created by Node 0 and Node 1's payment disclosure database does not - # contain the necessary data to do so, where the data would only have been available on Node 0 - # when executing z_shieldcoinbase. - try: - self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Could not find payment disclosure info for the given joinsplit output" in errorString) - - # Payment disclosures cannot be created for transparent transactions. - txid = self.nodes[2].sendtoaddress(mytaddr, 1.0) - self.sync_all() - - # No matter the type of transaction, if it has not been confirmed, it is ignored. - try: - self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Transaction has not been confirmed yet" in errorString) - - self.nodes[0].generate(1) - self.sync_all() - - # Confirm that a payment disclosure can only be generated for a shielded transaction. - try: - self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) - assert(False) - except JSONRPCException as e: - errorString = e.error['message'] - assert("Transaction is not a shielded transaction" in errorString) - -if __name__ == '__main__': - PaymentDisclosureTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index 2d2d7a691..ab04c24bc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -181,8 +181,6 @@ BITCOIN_CORE_H = \ netbase.h \ notaries_staked.h \ noui.h \ - paymentdisclosure.h \ - paymentdisclosuredb.h \ policy/fees.h \ pow.h \ prevector.h \ @@ -303,8 +301,6 @@ libbitcoin_server_a_SOURCES = \ notaries_staked.cpp \ noui.cpp \ notarisationdb.cpp \ - paymentdisclosure.cpp \ - paymentdisclosuredb.cpp \ policy/fees.cpp \ pow.cpp \ rest.cpp \ @@ -355,10 +351,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/asyncrpcoperation_shieldcoinbase.cpp \ wallet/crypter.cpp \ wallet/db.cpp \ - paymentdisclosure.cpp \ - paymentdisclosuredb.cpp \ transaction_builder.cpp \ - wallet/rpcdisclosure.cpp \ wallet/rpcdump.cpp \ cc/CCtokens.cpp \ cc/CCassetsCore.cpp \ diff --git a/src/gtest/test_paymentdisclosure.cpp b/src/gtest/test_paymentdisclosure.cpp deleted file mode 100644 index c166cdbe1..000000000 --- a/src/gtest/test_paymentdisclosure.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include - -#include "main.h" -#include "utilmoneystr.h" -#include "chainparams.h" -#include "utilstrencodings.h" -#include "zcash/Address.hpp" -#include "wallet/wallet.h" -#include "amount.h" - -#include -#include -#include -#include -#include -#include -#include -#include "util.h" - -#include "paymentdisclosure.h" -#include "paymentdisclosuredb.h" - -#include "sodium.h" - -#include -#include -#include - -using namespace std; - -/* - To run tests: - ./zcash-gtest --gtest_filter="paymentdisclosure.*" - - Note: As an experimental feature, writing your own tests may require option flags to be set. - mapArgs["-experimentalfeatures"] = true; - mapArgs["-paymentdisclosure"] = true; -*/ - -#define NUM_TRIES 10000 - -#define DUMP_DATABASE_TO_STDOUT false - -static boost::uuids::random_generator uuidgen; - -static uint256 random_uint256() -{ - uint256 ret; - randombytes_buf(ret.begin(), 32); - return ret; -} - -// Subclass of PaymentDisclosureDB to add debugging methods -class PaymentDisclosureDBTest : public PaymentDisclosureDB { -public: - PaymentDisclosureDBTest(const boost::filesystem::path& dbPath) : PaymentDisclosureDB(dbPath) {} - - void DebugDumpAllStdout() { - ASSERT_NE(db, nullptr); - std::lock_guard guard(lock_); - - // Iterate over each item in the database and print them - leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions()); - - for (it->SeekToFirst(); it->Valid(); it->Next()) { - cout << it->key().ToString() << " : "; - // << it->value().ToString() << endl; - try { - std::string strValue = it->value().ToString(); - PaymentDisclosureInfo info; - CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); - ssValue >> info; - cout << info.ToString() << std::endl; - } catch (const std::exception& e) { - cout << e.what() << std::endl; - } - } - - if (false == it->status().ok()) { - cerr << "An error was found iterating over the database" << endl; - cerr << it->status().ToString() << endl; - } - - delete it; - } -}; - - - -// This test creates random payment disclosure blobs and checks that they can be -// 1. inserted and retrieved from a database -// 2. serialized and deserialized without corruption -// Note that the zpd: prefix is not part of the payment disclosure blob itself. It is only -// used as convention to improve the user experience when sharing payment disclosure blobs. -TEST(paymentdisclosure, mainnet) { - SelectParams(CBaseChainParams::MAIN); - - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - - std::cout << "Test payment disclosure database created in folder: " << pathTemp.string() << std::endl; - - PaymentDisclosureDBTest mydb(pathTemp); - - for (int i=0; i vch(&buffer[0], &buffer[0] + 32); - uint256 joinSplitPrivKey = uint256(vch); - - // Create payment disclosure key and info data to store in test database - size_t js = random_uint256().GetCheapHash() % std::numeric_limits::max(); - uint8_t n = random_uint256().GetCheapHash() % std::numeric_limits::max(); - PaymentDisclosureKey key { random_uint256(), js, n}; - PaymentDisclosureInfo info; - info.esk = random_uint256(); - info.joinSplitPrivKey = joinSplitPrivKey; - info.zaddr = libzcash::SproutSpendingKey::random().address(); - ASSERT_TRUE(mydb.Put(key, info)); - - // Retrieve info from test database into new local variable and test it matches - PaymentDisclosureInfo info2; - ASSERT_TRUE(mydb.Get(key, info2)); - ASSERT_EQ(info, info2); - - // Modify this local variable and confirm it no longer matches - info2.esk = random_uint256(); - info2.joinSplitPrivKey = random_uint256(); - info2.zaddr = libzcash::SproutSpendingKey::random().address(); - ASSERT_NE(info, info2); - - // Using the payment info object, let's create a dummy payload - PaymentDisclosurePayload payload; - payload.version = PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL; - payload.esk = info.esk; - payload.txid = key.hash; - payload.js = key.js; - payload.n = key.n; - payload.message = "random-" + boost::uuids::to_string(uuidgen()); // random message - payload.zaddr = info.zaddr; - - // Serialize and hash the payload to generate a signature - uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0); - - // Compute the payload signature - unsigned char payloadSig[64]; - if (!(crypto_sign_detached(&payloadSig[0], NULL, - dataToBeSigned.begin(), 32, - &buffer[0] // buffer containing both private and public key required - ) == 0)) - { - throw std::runtime_error("crypto_sign_detached failed"); - } - - // Sanity check - if (!(crypto_sign_verify_detached(&payloadSig[0], - dataToBeSigned.begin(), 32, - joinSplitPubKey.begin() - ) == 0)) - { - throw std::runtime_error("crypto_sign_verify_detached failed"); - } - - // Convert signature buffer to boost array - std::array arrayPayloadSig; - memcpy(arrayPayloadSig.data(), &payloadSig[0], 64); - - // Payment disclosure blob to pass around - PaymentDisclosure pd = {payload, arrayPayloadSig}; - - // Test payment disclosure constructors - PaymentDisclosure pd2(payload, arrayPayloadSig); - ASSERT_EQ(pd, pd2); - PaymentDisclosure pd3(joinSplitPubKey, key, info, payload.message); - ASSERT_EQ(pd, pd3); - - // Verify serialization and deserialization works - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pd; - std::string ssHexString = HexStr(ss.begin(), ss.end()); - - PaymentDisclosure pdTmp; - CDataStream ssTmp(ParseHex(ssHexString), SER_NETWORK, PROTOCOL_VERSION); - ssTmp >> pdTmp; - ASSERT_EQ(pd, pdTmp); - - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << pdTmp; - std::string ss2HexString = HexStr(ss2.begin(), ss2.end()); - ASSERT_EQ(ssHexString, ss2HexString); - - // Verify marker - ASSERT_EQ(pd.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES); - ASSERT_EQ(pdTmp.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES); - ASSERT_EQ(0, ssHexString.find("706462ff")); // Little endian encoding of PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES value - - // Sanity check - PaymentDisclosure pdDummy; - ASSERT_NE(pd, pdDummy); - } - -#if DUMP_DATABASE_TO_STDOUT == true - mydb.DebugDumpAllStdout(); -#endif -} diff --git a/src/paymentdisclosure.cpp b/src/paymentdisclosure.cpp deleted file mode 100644 index eb55a0536..000000000 --- a/src/paymentdisclosure.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentdisclosure.h" - -#include "key_io.h" -#include "util.h" - -std::string PaymentDisclosureInfo::ToString() const { - return strprintf("PaymentDisclosureInfo(version=%d, esk=%s, joinSplitPrivKey=, address=%s)", - version, esk.ToString(), EncodePaymentAddress(zaddr)); -} - -std::string PaymentDisclosure::ToString() const { - std::string s = HexStr(payloadSig.begin(), payloadSig.end()); - return strprintf("PaymentDisclosure(payload=%s, payloadSig=%s)", payload.ToString(), s); -} - -std::string PaymentDisclosurePayload::ToString() const { - return strprintf("PaymentDisclosurePayload(version=%d, esk=%s, txid=%s, js=%d, n=%d, address=%s, message=%s)", - version, esk.ToString(), txid.ToString(), js, n, EncodePaymentAddress(zaddr), message); -} - -PaymentDisclosure::PaymentDisclosure(const uint256 &joinSplitPubKey, const PaymentDisclosureKey &key, const PaymentDisclosureInfo &info, const std::string &message) -{ - // Populate payload member variable - payload.version = info.version; // experimental = 0, production = 1 etc. - payload.esk = info.esk; - payload.txid = key.hash; - payload.js = key.js; - payload.n = key.n; - payload.zaddr = info.zaddr; - payload.message = message; - - // Serialize and hash the payload to generate a signature - uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0); - - LogPrint("paymentdisclosure", "Payment Disclosure: signing raw payload = %s\n", dataToBeSigned.ToString()); - - // Prepare buffer to store ed25519 key pair in libsodium-compatible format - unsigned char bufferKeyPair[64]; - memcpy(&bufferKeyPair[0], info.joinSplitPrivKey.begin(), 32); - memcpy(&bufferKeyPair[32], joinSplitPubKey.begin(), 32); - - // Compute payload signature member variable - if (!(crypto_sign_detached(payloadSig.data(), NULL, - dataToBeSigned.begin(), 32, - &bufferKeyPair[0] - ) == 0)) - { - throw std::runtime_error("crypto_sign_detached failed"); - } - - // Sanity check - if (!(crypto_sign_verify_detached(payloadSig.data(), - dataToBeSigned.begin(), 32, - joinSplitPubKey.begin()) == 0)) - { - throw std::runtime_error("crypto_sign_verify_detached failed"); - } - - std::string sigString = HexStr(payloadSig.data(), payloadSig.data() + payloadSig.size()); - LogPrint("paymentdisclosure", "Payment Disclosure: signature = %s\n", sigString); -} diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h deleted file mode 100644 index 5c3a20c33..000000000 --- a/src/paymentdisclosure.h +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Copyright (c) 2019-2020 The Hush developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_PAYMENTDISCLOSURE_H -#define ZCASH_PAYMENTDISCLOSURE_H - -#include "uint256.h" -#include "clientversion.h" -#include "serialize.h" -#include "streams.h" -#include "version.h" - -// For JSOutPoint -#include "wallet/wallet.h" - -#include -#include -#include - - -// Ensure that the two different protocol messages, payment disclosure blobs and transactions, -// which are signed with the same key, joinSplitPrivKey, have disjoint encodings such that an -// encoding from one context will be rejected in the other. We know that the set of valid -// transaction versions is currently ({1..INT32_MAX}) so we will use a negative value for -// payment disclosure of -10328976 which in hex is 0xFF626470. Serialization is in little endian -// format, so a payment disclosure hex string begins 706462FF, which in ISO-8859-1 is "pdbÿ". -#define PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES -10328976 - -#define PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL 0 - -#define PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX "zpd:" - -typedef JSOutPoint PaymentDisclosureKey; - -struct PaymentDisclosureInfo { - uint8_t version; // 0 = experimental, 1 = first production version, etc. - uint256 esk; // zcash/NoteEncryption.cpp - uint256 joinSplitPrivKey; // primitives/transaction.h - // ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc - - libzcash::SproutPaymentAddress zaddr; - - PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) { - } - - PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(version); - READWRITE(esk); - READWRITE(joinSplitPrivKey); - READWRITE(zaddr); - } - - std::string ToString() const; - - friend bool operator==(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) { - return (a.version == b.version && a.esk == b.esk && a.joinSplitPrivKey == b.joinSplitPrivKey && a.zaddr == b.zaddr); - } - - friend bool operator!=(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) { - return !(a == b); - } - -}; - - -struct PaymentDisclosurePayload { - int32_t marker = PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES; // to be disjoint from transaction encoding - uint8_t version; // 0 = experimental, 1 = first production version, etc. - uint256 esk; // zcash/NoteEncryption.cpp - uint256 txid; // primitives/transaction.h - uint64_t js; // Index into CTransaction.vjoinsplit - uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS - libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp - std::string message; // parameter to RPC call - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(marker); - READWRITE(version); - READWRITE(esk); - READWRITE(txid); - READWRITE(js); - READWRITE(n); - READWRITE(zaddr); - READWRITE(message); - } - - std::string ToString() const; - - friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) { - return ( - a.version == b.version && - a.esk == b.esk && - a.txid == b.txid && - a.js == b.js && - a.n == b.n && - a.zaddr == b.zaddr && - a.message == b.message - ); - } - - friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) { - return !(a == b); - } -}; - -struct PaymentDisclosure { - PaymentDisclosurePayload payload; - std::array payloadSig; - // We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64]; - - PaymentDisclosure() {}; - PaymentDisclosure(const PaymentDisclosurePayload payload, const std::array sig) : payload(payload), payloadSig(sig) {}; - PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message); - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(payload); - READWRITE(payloadSig); - } - - std::string ToString() const; - - friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) { - return (a.payload == b.payload && a.payloadSig == b.payloadSig); - } - - friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) { - return !(a == b); - } -}; - - - -typedef std::pair PaymentDisclosureKeyInfo; - - -#endif // ZCASH_PAYMENTDISCLOSURE_H diff --git a/src/paymentdisclosuredb.cpp b/src/paymentdisclosuredb.cpp deleted file mode 100644 index 8840dcda0..000000000 --- a/src/paymentdisclosuredb.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentdisclosuredb.h" - -#include "util.h" -#include "dbwrapper.h" - -#include - -using namespace std; - -static boost::filesystem::path emptyPath; - -/** - * Static method to return the shared/default payment disclosure database. - */ -shared_ptr PaymentDisclosureDB::sharedInstance() { - // Thread-safe in C++11 and gcc 4.3 - static shared_ptr ptr = std::make_shared(); - return ptr; -} - -// C++11 delegated constructor -PaymentDisclosureDB::PaymentDisclosureDB() : PaymentDisclosureDB(emptyPath) { -} - -PaymentDisclosureDB::PaymentDisclosureDB(const boost::filesystem::path& dbPath) { - boost::filesystem::path path(dbPath); - if (path.empty()) { - path = GetDataDir() / "paymentdisclosure"; - LogPrintf("PaymentDisclosure: using default path for database: %s\n", path.string()); - } else { - LogPrintf("PaymentDisclosure: using custom path for database: %s\n", path.string()); - } - - TryCreateDirectory(path); - options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open(options, path.string(), &db); - dbwrapper_private::HandleError(status); // throws exception - LogPrintf("PaymentDisclosure: Opened LevelDB successfully\n"); -} - -PaymentDisclosureDB::~PaymentDisclosureDB() { - if (db != nullptr) { - delete db; - } -} - -bool PaymentDisclosureDB::Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info) -{ - if (db == nullptr) { - return false; - } - - std::lock_guard guard(lock_); - - CDataStream ssValue(SER_DISK, CLIENT_VERSION); - ssValue.reserve(GetSerializeSize(ssValue, info)); - ssValue << info; - leveldb::Slice slice(&ssValue[0], ssValue.size()); - - leveldb::Status status = db->Put(writeOptions, key.ToString(), slice); - dbwrapper_private::HandleError(status); - return true; -} - -bool PaymentDisclosureDB::Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info) -{ - if (db == nullptr) { - return false; - } - - std::lock_guard guard(lock_); - - std::string strValue; - leveldb::Status status = db->Get(readOptions, key.ToString(), &strValue); - if (!status.ok()) { - if (status.IsNotFound()) - return false; - LogPrintf("PaymentDisclosure: LevelDB read failure: %s\n", status.ToString()); - dbwrapper_private::HandleError(status); - } - - try { - CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); - ssValue >> info; - } catch (const std::exception&) { - return false; - } - return true; -} diff --git a/src/paymentdisclosuredb.h b/src/paymentdisclosuredb.h deleted file mode 100644 index 9352cac8f..000000000 --- a/src/paymentdisclosuredb.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_PAYMENTDISCLOSUREDB_H -#define ZCASH_PAYMENTDISCLOSUREDB_H - -#include "paymentdisclosure.h" - -#include -#include -#include -#include -#include - -#include - -#include - - -class PaymentDisclosureDB -{ -protected: - leveldb::DB* db = nullptr; - leveldb::Options options; - leveldb::ReadOptions readOptions; - leveldb::WriteOptions writeOptions; - mutable std::mutex lock_; - -public: - static std::shared_ptr sharedInstance(); - - PaymentDisclosureDB(); - PaymentDisclosureDB(const boost::filesystem::path& dbPath); - ~PaymentDisclosureDB(); - - bool Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info); - bool Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info); -}; - - -#endif // ZCASH_PAYMENTDISCLOSUREDB_H diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index ed4efc014..4e47a5a2d 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -133,9 +133,6 @@ saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), context // Lock UTXOs lock_utxos(); lock_notes(); - - // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); } AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress() @@ -210,25 +207,10 @@ void AsyncRPCOperation_mergetoaddress::main() unlock_utxos(); // clean up unlock_notes(); // clean up - - // !!! Payment disclosure START - if (success && paymentDisclosureMode && paymentDisclosureData_.size() > 0) { - uint256 txidhash = tx_.GetHash(); - std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); - for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { - p.first.hash = txidhash; - if (!db->Put(p.first, p.second)) { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); - } else { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); - } - } - } - // !!! Payment disclosure END } // Notes: -// 1. #1359 Currently there is no limit set on the number of joinsplits, so size of tx could be invalid. +// 1. #1359 Currently there is no limit set on the number of inputs+outputs, so size of tx could be invalid. // 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them. bool AsyncRPCOperation_mergetoaddress::main_impl() { diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index be49baff0..4876921db 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -1,4 +1,6 @@ // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers + // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,7 +24,6 @@ #include "amount.h" #include "asyncrpcoperation.h" -#include "paymentdisclosure.h" #include "primitives/transaction.h" #include "transaction_builder.h" #include "wallet.h" @@ -93,8 +94,6 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs - bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. - private: friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing @@ -148,8 +147,6 @@ private: void unlock_notes(); - // payment disclosure! - std::vector paymentDisclosureData_; }; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index a1ecb296d..31f987bef 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -211,25 +211,10 @@ void AsyncRPCOperation_sendmany::main() { s += strprintf(", error=%s)\n", getErrorMessage()); } LogPrintf("%s",s); - - // !!! Payment disclosure START - if (success && paymentDisclosureMode && paymentDisclosureData_.size()>0) { - uint256 txidhash = tx_.GetHash(); - std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); - for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { - p.first.hash = txidhash; - if (!db->Put(p.first, p.second)) { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); - } else { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); - } - } - } - // !!! Payment disclosure END } // Notes: -// 1. #1159 Currently there is no limit set on the number of joinsplits, so size of tx could be invalid. +// 1. #1159 Currently there is no limit set on the number of shielded spends, so size of tx could be invalid. // 2. #1360 Note selection is not optimal // 3. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them bool AsyncRPCOperation_sendmany::main_impl() { diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 8e39f341a..0b803ddd9 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -1,4 +1,5 @@ // Copyright (c) 2016 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -27,7 +28,6 @@ #include "zcash/JoinSplit.hpp" #include "zcash/Address.hpp" #include "wallet.h" -#include "paymentdisclosure.h" #include #include @@ -90,8 +90,6 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs - bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. - private: friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing @@ -143,9 +141,6 @@ private: uint256 anchor); void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error - - // payment disclosure! - std::vector paymentDisclosureData_; }; diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 5db0ca51b..de56ba3bc 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -48,9 +48,6 @@ #include "asyncrpcoperation_shieldcoinbase.h" -#include "paymentdisclosure.h" -#include "paymentdisclosuredb.h" - using namespace libzcash; extern uint64_t ASSETCHAINS_TIMELOCKGTE; @@ -108,8 +105,6 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( // Lock UTXOs lock_utxos(); - // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); } AsyncRPCOperation_shieldcoinbase::~AsyncRPCOperation_shieldcoinbase() { @@ -181,20 +176,6 @@ void AsyncRPCOperation_shieldcoinbase::main() { unlock_utxos(); // clean up - // !!! Payment disclosure START - if (success && paymentDisclosureMode && paymentDisclosureData_.size()>0) { - uint256 txidhash = tx_.GetHash(); - std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); - for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { - p.first.hash = txidhash; - if (!db->Put(p.first, p.second)) { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); - } else { - LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); - } - } - } - // !!! Payment disclosure END } bool AsyncRPCOperation_shieldcoinbase::main_impl() { diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index db4fb83af..3eb1a6cfc 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -34,8 +34,6 @@ #include -#include "paymentdisclosure.h" - // Default transaction fee if caller does not specify one. #define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000 @@ -81,8 +79,6 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs bool cheatSpend = false; // set when this is shielding a cheating coinbase - bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. - private: friend class ShieldToAddress; friend class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase; // class for unit testing @@ -110,9 +106,6 @@ private: void lock_utxos(); void unlock_utxos(); - - // payment disclosure! - std::vector paymentDisclosureData_; }; class ShieldToAddress : public boost::static_visitor diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp deleted file mode 100644 index 918e70cbc..000000000 --- a/src/wallet/rpcdisclosure.cpp +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Copyright (c) 2019-2020 The Hush developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "rpc/server.h" -#include "init.h" -#include "key_io.h" -#include "main.h" -#include "script/script.h" -#include "script/standard.h" -#include "sync.h" -#include "util.h" -#include "utiltime.h" -#include "wallet.h" - -#include -#include - -#include -#include - -#include - -#include "paymentdisclosure.h" -#include "paymentdisclosuredb.h" - -#include "zcash/Note.hpp" -#include "zcash/NoteEncryption.hpp" - -using namespace std; -using namespace libzcash; - -// Function declaration for function implemented in wallet/rpcwallet.cpp -bool EnsureWalletIsAvailable(bool avoidException); - -/** - * RPC call to generate a payment disclosure - */ -UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - string enableArg = "paymentdisclosure"; - auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true); - string strPaymentDisclosureDisabledMsg = ""; - if (!fEnablePaymentDisclosure) { - strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_getpaymentdisclosure", enableArg); - } - - if (fHelp || params.size() < 3 || params.size() > 4 ) - throw runtime_error( - "z_getpaymentdisclosure \"txid\" \"js_index\" \"output_index\" (\"message\") \n" - "\nGenerate a payment disclosure for a given joinsplit output.\n" - "\nEXPERIMENTAL FEATURE\n" - + strPaymentDisclosureDisabledMsg + - "\nArguments:\n" - "1. \"txid\" (string, required) \n" - "2. \"js_index\" (string, required) \n" - "3. \"output_index\" (string, required) \n" - "4. \"message\" (string, optional) \n" - "\nResult:\n" - "\"paymentdisclosure\" (string) Hex data string, with \"zpd:\" prefix.\n" - "\nExamples:\n" - + HelpExampleCli("z_getpaymentdisclosure", "96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2 0 0 \"refund\"") - + HelpExampleRpc("z_getpaymentdisclosure", "\"96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2\", 0, 0, \"refund\"") - ); - - if (!fEnablePaymentDisclosure) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled."); - } - - LOCK2(cs_main, pwalletMain->cs_wallet); - - EnsureWalletIsUnlocked(); - - // Check wallet knows about txid - string txid = params[0].get_str(); - uint256 hash; - hash.SetHex(txid); - - CTransaction tx; - uint256 hashBlock; - - // Check txid has been seen - if (!GetTransaction(hash, tx, hashBlock, true)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - } - - // Check tx has been confirmed - if (hashBlock.IsNull()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet"); - } - - // Check is mine - if (!pwalletMain->mapWallet.count(hash)) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction does not belong to the wallet"); - } - const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - - // Check if shielded tx - if (wtx.vjoinsplit.empty()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); - } - - // Check js_index - int js_index = params[1].get_int(); - if (js_index < 0 || js_index >= wtx.vjoinsplit.size()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid js_index"); - } - - // Check output_index - int output_index = params[2].get_int(); - if (output_index < 0 || output_index >= ZC_NUM_JS_OUTPUTS) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid output_index"); - } - - // Get message if it exists - string msg; - if (params.size() == 4) { - msg = params[3].get_str(); - } - - // Create PaymentDisclosureKey - PaymentDisclosureKey key = {hash, (size_t)js_index, (uint8_t)output_index }; - - // TODO: In future, perhaps init the DB in init.cpp - shared_ptr db = PaymentDisclosureDB::sharedInstance(); - PaymentDisclosureInfo info; - if (!db->Get(key, info)) { - throw JSONRPCError(RPC_DATABASE_ERROR, "Could not find payment disclosure info for the given joinsplit output"); - } - - PaymentDisclosure pd( wtx.joinSplitPubKey, key, info, msg ); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pd; - string strHex = HexStr(ss.begin(), ss.end()); - return PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX + strHex; -} - - - -/** - * RPC call to validate a payment disclosure data blob. - */ -UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) - return NullUniValue; - - string enableArg = "paymentdisclosure"; - auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true); - string strPaymentDisclosureDisabledMsg = ""; - if (!fEnablePaymentDisclosure) { - strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_validatepaymentdisclosure", enableArg); - } - - if (fHelp || params.size() != 1) - throw runtime_error( - "z_validatepaymentdisclosure \"paymentdisclosure\"\n" - "\nValidates a payment disclosure.\n" - "\nEXPERIMENTAL FEATURE\n" - + strPaymentDisclosureDisabledMsg + - "\nArguments:\n" - "1. \"paymentdisclosure\" (string, required) Hex data string, with \"zpd:\" prefix.\n" - "\nExamples:\n" - + HelpExampleCli("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"") - + HelpExampleRpc("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"") - ); - - if (!fEnablePaymentDisclosure) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled."); - } - - throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosures not implemented for Sapling yet"); - - LOCK2(cs_main, pwalletMain->cs_wallet); - - EnsureWalletIsUnlocked(); - - // Verify the payment disclosure input begins with "zpd:" prefix. - string strInput = params[0].get_str(); - size_t pos = strInput.find(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX); - if (pos != 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure prefix not found."); - } - string hexInput = strInput.substr(strlen(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX)); - if (!IsHex(hexInput)) - { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected payment disclosure data in hexadecimal format."); - } - - // Unserialize the payment disclosure data into an object - PaymentDisclosure pd; - CDataStream ss(ParseHex(hexInput), SER_NETWORK, PROTOCOL_VERSION); - try { - ss >> pd; - // too much data is ignored, but if not enough data, exception of type ios_base::failure is thrown, - // CBaseDataStream::read(): end of data: iostream error - } catch (const std::exception &e) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure data is malformed."); - } - - if (pd.payload.marker != PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure marker not found."); - } - - if (pd.payload.version != PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Payment disclosure version is unsupported."); - } - - uint256 hash = pd.payload.txid; - CTransaction tx; - uint256 hashBlock; - // Check if we have seen the transaction - if (!GetTransaction(hash, tx, hashBlock, true)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - } - - // Check if the transaction has been confirmed - if (hashBlock.IsNull()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet"); - } - - // Check if shielded tx - if (tx.vjoinsplit.empty()) { - throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); - } - - UniValue errs(UniValue::VARR); - UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", pd.payload.txid.ToString())); - - // Check js_index - if (pd.payload.js >= tx.vjoinsplit.size()) { - errs.push_back("Payment disclosure refers to an invalid joinsplit index"); - } - o.push_back(Pair("jsIndex", pd.payload.js)); - - if (pd.payload.n < 0 || pd.payload.n >= ZC_NUM_JS_OUTPUTS) { - errs.push_back("Payment disclosure refers to an invalid output index"); - } - o.push_back(Pair("outputIndex", pd.payload.n)); - o.push_back(Pair("version", pd.payload.version)); - o.push_back(Pair("onetimePrivKey", pd.payload.esk.ToString())); - o.push_back(Pair("message", pd.payload.message)); - o.push_back(Pair("joinSplitPubKey", tx.joinSplitPubKey.ToString())); - - // Verify the payment disclosure was signed using the same key as the transaction i.e. the joinSplitPrivKey. - uint256 dataToBeSigned = SerializeHash(pd.payload, SER_GETHASH, 0); - bool sigVerified = (crypto_sign_verify_detached(pd.payloadSig.data(), - dataToBeSigned.begin(), 32, - tx.joinSplitPubKey.begin()) == 0); - o.push_back(Pair("signatureVerified", sigVerified)); - if (!sigVerified) { - errs.push_back("Payment disclosure signature does not match transaction signature"); - } - - /* - // Check the payment address is valid - PaymentAddress zaddr = pd.payload.zaddr; - { - o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr))); - - try { - // Decrypt the note to get value and memo field - JSDescription jsdesc = tx.vjoinsplit[pd.payload.js]; - uint256 h_sig = jsdesc.h_sig(*pzcashParams, tx.joinSplitPubKey); - - ZCPaymentDisclosureNoteDecryption decrypter; - - ZCNoteEncryption::Ciphertext ciphertext = jsdesc.ciphertexts[pd.payload.n]; - - uint256 pk_enc = zaddr.pk_enc; - auto plaintext = decrypter.decryptWithEsk(ciphertext, pk_enc, pd.payload.esk, h_sig, pd.payload.n); - - CDataStream ssPlain(SER_NETWORK, PROTOCOL_VERSION); - ssPlain << plaintext; - SproutNotePlaintext npt; - ssPlain >> npt; - - string memoHexString = HexStr(npt.memo().data(), npt.memo().data() + npt.memo().size()); - o.push_back(Pair("memo", memoHexString)); - o.push_back(Pair("value", ValueFromAmount(npt.value()))); - - // Check the blockchain commitment matches decrypted note commitment - uint256 cm_blockchain = jsdesc.commitments[pd.payload.n]; - SproutNote note = npt.note(zaddr); - uint256 cm_decrypted = note.cm(); - bool cm_match = (cm_decrypted == cm_blockchain); - o.push_back(Pair("commitmentMatch", cm_match)); - if (!cm_match) { - errs.push_back("Commitment derived from payment disclosure does not match blockchain commitment"); - } - } catch (const std::exception &e) { - errs.push_back(string("Error while decrypting payment disclosure note: ") + string(e.what()) ); - } - } - */ - - bool isValid = errs.empty(); - o.push_back(Pair("valid", isValid)); - if (!isValid) { - o.push_back(Pair("errors", errs)); - } - - return o; -} diff --git a/src/zcash/NoteEncryption.cpp b/src/zcash/NoteEncryption.cpp index 63e073265..9f2d64563 100644 --- a/src/zcash/NoteEncryption.cpp +++ b/src/zcash/NoteEncryption.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include "NoteEncryption.hpp" #include #include "sodium.h" @@ -374,52 +376,6 @@ typename NoteDecryption::Plaintext NoteDecryption::decrypt return plaintext; } -// -// Payment disclosure - decrypt with esk -// -template -typename PaymentDisclosureNoteDecryption::Plaintext PaymentDisclosureNoteDecryption::decryptWithEsk - (const PaymentDisclosureNoteDecryption::Ciphertext &ciphertext, - const uint256 &pk_enc, - const uint256 &esk, - const uint256 &hSig, - unsigned char nonce - ) const -{ - uint256 dhsecret; - - if (crypto_scalarmult(dhsecret.begin(), esk.begin(), pk_enc.begin()) != 0) { - throw std::logic_error("Could not create DH secret"); - } - - // Regenerate keypair - uint256 epk = NoteEncryption::generate_pubkey(esk); - - unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE]; - KDF(K, dhsecret, epk, pk_enc, hSig, nonce); - - // The nonce is zero because we never reuse keys - unsigned char cipher_nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES] = {}; - - PaymentDisclosureNoteDecryption::Plaintext plaintext; - - // Message length is always NOTEENCRYPTION_AUTH_BYTES less than - // the ciphertext length. - if (crypto_aead_chacha20poly1305_ietf_decrypt(plaintext.begin(), NULL, - NULL, - ciphertext.begin(), PaymentDisclosureNoteDecryption::CLEN, - NULL, - 0, - cipher_nonce, K) != 0) { - throw note_decryption_failed(); - } - - return plaintext; -} - - - - template uint256 NoteEncryption::generate_privkey(const uint252 &a_sk) { @@ -461,6 +417,4 @@ uint252 random_uint252() template class NoteEncryption; template class NoteDecryption; -template class PaymentDisclosureNoteDecryption; - } diff --git a/src/zcash/NoteEncryption.hpp b/src/zcash/NoteEncryption.hpp index f6e692028..9c726d5cf 100644 --- a/src/zcash/NoteEncryption.hpp +++ b/src/zcash/NoteEncryption.hpp @@ -1,7 +1,4 @@ -/* -See the Zcash protocol specification for more information. -https://github.com/zcash/zips/blob/master/protocol/protocol.pdf -*/ +// Copyright (c) 2019-2020 The Hush developers #ifndef ZC_NOTE_ENCRYPTION_H_ #define ZC_NOTE_ENCRYPTION_H_ @@ -169,33 +166,9 @@ public: }; - -// Subclass PaymentDisclosureNoteDecryption provides a method to decrypt a note with esk. -template -class PaymentDisclosureNoteDecryption : public NoteDecryption { -protected: -public: - enum { CLEN=MLEN+NOTEENCRYPTION_AUTH_BYTES }; - typedef std::array Ciphertext; - typedef std::array Plaintext; - - PaymentDisclosureNoteDecryption() : NoteDecryption() {} - PaymentDisclosureNoteDecryption(uint256 sk_enc) : NoteDecryption(sk_enc) {} - - Plaintext decryptWithEsk( - const Ciphertext &ciphertext, - const uint256 &pk_enc, - const uint256 &esk, - const uint256 &hSig, - unsigned char nonce - ) const; -}; - } typedef libzcash::NoteEncryption ZCNoteEncryption; typedef libzcash::NoteDecryption ZCNoteDecryption; -typedef libzcash::PaymentDisclosureNoteDecryption ZCPaymentDisclosureNoteDecryption; - #endif /* ZC_NOTE_ENCRYPTION_H_ */ From 7e48b4f8ec46125a64c58d2901849e83c84ec258 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 09:31:31 -0400 Subject: [PATCH 140/220] desprout --- src/amount.h | 1 + src/key.h | 1 + src/key_io.cpp | 1 + src/primitives/block.h | 2 +- src/test/key_tests.cpp | 37 ++----------------------------------- src/util.h | 1 + 6 files changed, 7 insertions(+), 36 deletions(-) diff --git a/src/amount.h b/src/amount.h index be1c39a6e..c5f49593c 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key.h b/src/key.h index 857e8a8ae..16492b151 100644 --- a/src/key.h +++ b/src/key.h @@ -1,6 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/key_io.cpp b/src/key_io.cpp index 319c24eef..2e0dfeb9a 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -99,6 +99,7 @@ public: } std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; } + std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const { return {}; } }; class ViewingKeyEncoder : public boost::static_visitor diff --git a/src/primitives/block.h b/src/primitives/block.h index ea93d6f50..a2d0ba708 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2013 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 220d6a9b7..390b2bc7b 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2012-2013 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -22,6 +23,7 @@ using namespace std; using namespace libzcash; +//TODO: convert to Hush addresses static const std::string strSecret1 = "5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"; static const std::string strSecret2 = "5KC4ejrDjv152FGwP386VD1i2NYc5KkfSMyv1nGy1VGDxGHqVY3"; static const std::string strSecret1C = "Kwr371tjA9u2rFSMZjTNun2PXXP3WPZu2afRHTcta6KxEUdm1vEw"; @@ -186,41 +188,6 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_CHECK(detsigc == ParseHex("2052d8a32079c11e79db95af63bb9600c5b04f21a9ca33dc129c2bfa8ac9dc1cd561d8ae5e0f6c1a16bde3719c64c2fd70e404b6428ab9a69566962e8771b5944d")); } -BOOST_AUTO_TEST_CASE(zc_address_test) -{ - for (size_t i = 0; i < 1000; i++) { - auto sk = SproutSpendingKey::random(); - { - string sk_string = EncodeSpendingKey(sk); - - BOOST_CHECK(sk_string[0] == 'S'); - BOOST_CHECK(sk_string[1] == 'K'); - - auto spendingkey2 = DecodeSpendingKey(sk_string); - BOOST_CHECK(IsValidSpendingKey(spendingkey2)); - BOOST_ASSERT(boost::get(&spendingkey2) != nullptr); - auto sk2 = boost::get(spendingkey2); - BOOST_CHECK(sk.inner() == sk2.inner()); - } - { - auto addr = sk.address(); - - std::string addr_string = EncodePaymentAddress(addr); - - BOOST_CHECK(addr_string[0] == 'z'); - BOOST_CHECK(addr_string[1] == 'c'); - - auto paymentaddr2 = DecodePaymentAddress(addr_string); - BOOST_ASSERT(IsValidPaymentAddress(paymentaddr2)); - - BOOST_ASSERT(boost::get(&paymentaddr2) != nullptr); - auto addr2 = boost::get(paymentaddr2); - BOOST_CHECK(addr.a_pk == addr2.a_pk); - BOOST_CHECK(addr.pk_enc == addr2.pk_enc); - } - } -} - BOOST_AUTO_TEST_CASE(zs_address_test) { SelectParams(CBaseChainParams::REGTEST); diff --git a/src/util.h b/src/util.h index 2e8232871..d1bbdd26d 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From b089972147348bbb3e633aaec3b232225ef455d1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 10:07:36 -0400 Subject: [PATCH 141/220] delete --- src/rpcblockchain.old | 1625 ----------------------------------------- 1 file changed, 1625 deletions(-) delete mode 100644 src/rpcblockchain.old diff --git a/src/rpcblockchain.old b/src/rpcblockchain.old deleted file mode 100644 index a91f73a63..000000000 --- a/src/rpcblockchain.old +++ /dev/null @@ -1,1625 +0,0 @@ -// Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "amount.h" -#include "chain.h" -#include "chainparams.h" -#include "checkpoints.h" -#include "crosschain.h" -#include "base58.h" -#include "consensus/validation.h" -#include "cc/eval.h" -#include "main.h" -#include "primitives/transaction.h" -#include "rpcserver.h" -#include "sync.h" -#include "util.h" -#include "script/script.h" -#include "script/script_error.h" -#include "script/sign.h" -#include "script/standard.h" - -#include - -#include - -#include - -using namespace std; - -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); -void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); -int32_t komodo_longestchain(); -int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -<<<<<<< HEAD:src/rpcblockchain.old -extern int32_t KOMODO_LONGESTCHAIN; -======= ->>>>>>> master:src/rpcblockchain.cpp - -double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty) -{ - // Floating point number that is a multiple of the minimum difficulty, - // minimum difficulty = 1.0. - if (blockindex == NULL) - { - if (chainActive.LastTip() == NULL) - return 1.0; - else - blockindex = chainActive.LastTip(); - } - - uint32_t bits; - if (networkDifficulty) { - bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus()); - } else { - bits = blockindex->nBits; - } - - uint32_t powLimit = - UintToArith256(Params().GetConsensus().powLimit).GetCompact(); - int nShift = (bits >> 24) & 0xff; - int nShiftAmount = (powLimit >> 24) & 0xff; - - double dDiff = - (double)(powLimit & 0x00ffffff) / - (double)(bits & 0x00ffffff); - - while (nShift < nShiftAmount) - { - dDiff *= 256.0; - nShift++; - } - while (nShift > nShiftAmount) - { - dDiff /= 256.0; - nShift--; - } - - return dDiff; -} - -double GetDifficulty(const CBlockIndex* blockindex) -{ - return GetDifficultyINTERNAL(blockindex, false); -} - -double GetNetworkDifficulty(const CBlockIndex* blockindex) -{ - return GetDifficultyINTERNAL(blockindex, true); -} - -static UniValue ValuePoolDesc( - const std::string &name, - const boost::optional chainValue, - const boost::optional valueDelta) -{ - UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); - rv.push_back(Pair("monitored", (bool)chainValue)); - if (chainValue) { - rv.push_back(Pair("chainValue", ValueFromAmount(*chainValue))); - rv.push_back(Pair("chainValueZat", *chainValue)); - } - if (valueDelta) { - rv.push_back(Pair("valueDelta", ValueFromAmount(*valueDelta))); - rv.push_back(Pair("valueDeltaZat", *valueDelta)); - } - return rv; -} - -UniValue blockheaderToJSON(const CBlockIndex* blockindex) -{ - UniValue result(UniValue::VOBJ); - if ( blockindex == 0 ) - { - result.push_back(Pair("error", "null blockhash")); - return(result); - } - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) - confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); - result.push_back(Pair("rawconfirmations", confirmations)); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", blockindex->nVersion)); - result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); - result.push_back(Pair("time", (int64_t)blockindex->nTime)); - result.push_back(Pair("nonce", blockindex->nNonce.GetHex())); - result.push_back(Pair("solution", HexStr(blockindex->nSolution))); - result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("segid", (int64_t)blockindex->segid)); - - if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); - CBlockIndex *pnext = chainActive.Next(blockindex); - if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); - return result; -} - -UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) -{ - UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) { - confirmations = chainActive.Height() - blockindex->nHeight + 1; - } else { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); - } - result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); - result.push_back(Pair("rawconfirmations", confirmations)); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - result.push_back(Pair("segid", (int64_t)blockindex->segid)); - - UniValue deltas(UniValue::VARR); - - for (unsigned int i = 0; i < block.vtx.size(); i++) { - const CTransaction &tx = block.vtx[i]; - const uint256 txhash = tx.GetHash(); - - UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", txhash.GetHex())); - entry.push_back(Pair("index", (int)i)); - - UniValue inputs(UniValue::VARR); - - if (!tx.IsCoinBase()) { - - for (size_t j = 0; j < tx.vin.size(); j++) { - const CTxIn input = tx.vin[j]; - - UniValue delta(UniValue::VOBJ); - - CSpentIndexValue spentInfo; - CSpentIndexKey spentKey(input.prevout.hash, input.prevout.n); - - if (GetSpentIndex(spentKey, spentInfo)) { - if (spentInfo.addressType == 1) { - delta.push_back(Pair("address", CBitcoinAddress(CKeyID(spentInfo.addressHash)).ToString())); - } - else if (spentInfo.addressType == 2) { - delta.push_back(Pair("address", CBitcoinAddress(CScriptID(spentInfo.addressHash)).ToString())); - } - else { - continue; - } - delta.push_back(Pair("satoshis", -1 * spentInfo.satoshis)); - delta.push_back(Pair("index", (int)j)); - delta.push_back(Pair("prevtxid", input.prevout.hash.GetHex())); - delta.push_back(Pair("prevout", (int)input.prevout.n)); - - inputs.push_back(delta); - } else { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Spent information not available"); - } - - } - } - - entry.push_back(Pair("inputs", inputs)); - - UniValue outputs(UniValue::VARR); - - for (unsigned int k = 0; k < tx.vout.size(); k++) { - const CTxOut &out = tx.vout[k]; - - UniValue delta(UniValue::VOBJ); - - if (out.scriptPubKey.IsPayToScriptHash()) { - vector hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22); - delta.push_back(Pair("address", CBitcoinAddress(CScriptID(uint160(hashBytes))).ToString())); - - } - else if (out.scriptPubKey.IsPayToPublicKeyHash()) { - vector hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23); - delta.push_back(Pair("address", CBitcoinAddress(CKeyID(uint160(hashBytes))).ToString())); - } - else if (out.scriptPubKey.IsPayToPublicKey() || out.scriptPubKey.IsPayToCryptoCondition()) { - CTxDestination address; - if (ExtractDestination(out.scriptPubKey, address)) - { - //vector hashBytes(out.scriptPubKey.begin()+1, out.scriptPubKey.begin()+34); - //xxx delta.push_back(Pair("address", CBitcoinAddress(CKeyID(uint160(hashBytes))).ToString())); - delta.push_back(Pair("address", CBitcoinAddress(address).ToString())); - } - } - else { - continue; - } - - delta.push_back(Pair("satoshis", out.nValue)); - delta.push_back(Pair("index", (int)k)); - - outputs.push_back(delta); - } - - entry.push_back(Pair("outputs", outputs)); - deltas.push_back(entry); - - } - result.push_back(Pair("deltas", deltas)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", block.nNonce.GetHex())); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - - if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); - CBlockIndex *pnext = chainActive.Next(blockindex); - if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); - return result; -} - -UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) -{ - UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); - int confirmations = -1; - // Only report confirmations if the block is on the main chain - if (chainActive.Contains(blockindex)) - confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); - result.push_back(Pair("rawconfirmations", confirmations)); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - result.push_back(Pair("segid", (int64_t)blockindex->segid)); - UniValue txs(UniValue::VARR); - BOOST_FOREACH(const CTransaction&tx, block.vtx) - { - if(txDetails) - { - UniValue objTx(UniValue::VOBJ); - TxToJSON(tx, uint256(), objTx); - txs.push_back(objTx); - } - else - txs.push_back(tx.GetHash().GetHex()); - } - result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("nonce", block.nNonce.GetHex())); - result.push_back(Pair("solution", HexStr(block.nSolution))); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex())); - - UniValue valuePools(UniValue::VARR); - valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue)); - result.push_back(Pair("valuePools", valuePools)); - - if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); - CBlockIndex *pnext = chainActive.Next(blockindex); - if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); - return result; -} - -UniValue getblockcount(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getblockcount\n" - "\nReturns the number of blocks in the best valid block chain.\n" - "\nResult:\n" - "n (numeric) The current block count\n" - "\nExamples:\n" - + HelpExampleCli("getblockcount", "") - + HelpExampleRpc("getblockcount", "") - ); - - LOCK(cs_main); - return chainActive.Height(); -} - -UniValue getbestblockhash(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getbestblockhash\n" - "\nReturns the hash of the best (tip) block in the longest block chain.\n" - "\nResult\n" - "\"hex\" (string) the block hash hex encoded\n" - "\nExamples\n" - + HelpExampleCli("getbestblockhash", "") - + HelpExampleRpc("getbestblockhash", "") - ); - - LOCK(cs_main); - return chainActive.LastTip()->GetBlockHash().GetHex(); -} - -UniValue getdifficulty(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getdifficulty\n" - "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n" - "\nResult:\n" - "n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n" - "\nExamples:\n" - + HelpExampleCli("getdifficulty", "") - + HelpExampleRpc("getdifficulty", "") - ); - - LOCK(cs_main); - return GetNetworkDifficulty(); -} - -bool myIsutxo_spentinmempool(uint256 txid,int32_t vout) -{ - //char *uint256_str(char *str,uint256); char str[65]; - //LOCK(mempool.cs); - BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx) - { - const CTransaction &tx = e.GetTx(); - const uint256 &hash = tx.GetHash(); - BOOST_FOREACH(const CTxIn &txin,tx.vin) - { - //fprintf(stderr,"%s/v%d ",uint256_str(str,txin.prevout.hash),txin.prevout.n); - if ( txin.prevout.n == vout && txin.prevout.hash == txid ) - return(true); - } - //fprintf(stderr,"are vins for %s\n",uint256_str(str,hash)); - } - return(false); -} - -bool mytxid_inmempool(uint256 txid) -{ - BOOST_FOREACH(const CTxMemPoolEntry &e,mempool.mapTx) - { - const CTransaction &tx = e.GetTx(); - const uint256 &hash = tx.GetHash(); - if ( txid == hash ) - return(true); - } - return(false); -} - -UniValue mempoolToJSON(bool fVerbose = false) -{ - if (fVerbose) - { - LOCK(mempool.cs); - UniValue o(UniValue::VOBJ); - BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) - { - const uint256& hash = e.GetTx().GetHash(); - UniValue info(UniValue::VOBJ); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); - const CTransaction& tx = e.GetTx(); - set setDepends; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - if (mempool.exists(txin.prevout.hash)) - setDepends.insert(txin.prevout.hash.ToString()); - } - - UniValue depends(UniValue::VARR); - BOOST_FOREACH(const string& dep, setDepends) - { - depends.push_back(dep); - } - - info.push_back(Pair("depends", depends)); - o.push_back(Pair(hash.ToString(), info)); - } - return o; - } - else - { - vector vtxid; - mempool.queryHashes(vtxid); - - UniValue a(UniValue::VARR); - BOOST_FOREACH(const uint256& hash, vtxid) - a.push_back(hash.ToString()); - - return a; - } -} - -UniValue getrawmempool(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() > 1) - throw runtime_error( - "getrawmempool ( verbose )\n" - "\nReturns all transaction ids in memory pool as a json array of string transaction ids.\n" - "\nArguments:\n" - "1. verbose (boolean, optional, default=false) true for a json object, false for array of transaction ids\n" - "\nResult: (for verbose = false):\n" - "[ (json array of string)\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - "]\n" - "\nResult: (for verbose = true):\n" - "{ (json object)\n" - " \"transactionid\" : { (json object)\n" - " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" - " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" - " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) transaction priority now\n" - " \"depends\" : [ (array) unconfirmed transactions used as inputs for this transaction\n" - " \"transactionid\", (string) parent transaction id\n" - " ... ]\n" - " }, ...\n" - "}\n" - "\nExamples\n" - + HelpExampleCli("getrawmempool", "true") - + HelpExampleRpc("getrawmempool", "true") - ); - - LOCK(cs_main); - - bool fVerbose = false; - if (params.size() > 0) - fVerbose = params[0].get_bool(); - - return mempoolToJSON(fVerbose); -} - -UniValue getblockdeltas(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error(""); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlock block; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - - if(!ReadBlockFromDisk(block, pblockindex,1)) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); - - return blockToDeltasJSON(block, pblockindex); -} - -UniValue getblockhashes(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 2) - throw runtime_error( - "getblockhashes timestamp\n" - "\nReturns array of hashes of blocks within the timestamp range provided.\n" - "\nArguments:\n" - "1. high (numeric, required) The newer block timestamp\n" - "2. low (numeric, required) The older block timestamp\n" - "3. options (string, required) A json object\n" - " {\n" - " \"noOrphans\":true (boolean) will only include blocks on the main chain\n" - " \"logicalTimes\":true (boolean) will include logical timestamps with hashes\n" - " }\n" - "\nResult:\n" - "[\n" - " \"hash\" (string) The block hash\n" - "]\n" - "[\n" - " {\n" - " \"blockhash\": (string) The block hash\n" - " \"logicalts\": (numeric) The logical timestamp\n" - " }\n" - "]\n" - "\nExamples:\n" - + HelpExampleCli("getblockhashes", "1231614698 1231024505") - + HelpExampleRpc("getblockhashes", "1231614698, 1231024505") - + HelpExampleCli("getblockhashes", "1231614698 1231024505 '{\"noOrphans\":false, \"logicalTimes\":true}'") - ); - - unsigned int high = params[0].get_int(); - unsigned int low = params[1].get_int(); - bool fActiveOnly = false; - bool fLogicalTS = false; - - if (params.size() > 2) { - if (params[2].isObject()) { - UniValue noOrphans = find_value(params[2].get_obj(), "noOrphans"); - UniValue returnLogical = find_value(params[2].get_obj(), "logicalTimes"); - - if (noOrphans.isBool()) - fActiveOnly = noOrphans.get_bool(); - - if (returnLogical.isBool()) - fLogicalTS = returnLogical.get_bool(); - } - } - - std::vector > blockHashes; - - if (fActiveOnly) - LOCK(cs_main); - - if (!GetTimestampIndex(high, low, fActiveOnly, blockHashes)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for block hashes"); - } - - UniValue result(UniValue::VARR); - - for (std::vector >::const_iterator it=blockHashes.begin(); it!=blockHashes.end(); it++) { - if (fLogicalTS) { - UniValue item(UniValue::VOBJ); - item.push_back(Pair("blockhash", it->first.GetHex())); - item.push_back(Pair("logicalts", (int)it->second)); - result.push_back(item); - } else { - result.push_back(it->first.GetHex()); - } - } - - return result; -} - -UniValue getblockhash(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "getblockhash index\n" - "\nReturns hash of block in best-block-chain at index provided.\n" - "\nArguments:\n" - "1. index (numeric, required) The block index\n" - "\nResult:\n" - "\"hash\" (string) The block hash\n" - "\nExamples:\n" - + HelpExampleCli("getblockhash", "1000") - + HelpExampleRpc("getblockhash", "1000") - ); - - LOCK(cs_main); - - int nHeight = params[0].get_int(); - if (nHeight < 0 || nHeight > chainActive.Height()) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - - CBlockIndex* pblockindex = chainActive[nHeight]; - return pblockindex->GetBlockHash().GetHex(); -} - -/*uint256 _komodo_getblockhash(int32_t nHeight) -{ - uint256 hash; - LOCK(cs_main); - if ( nHeight >= 0 && nHeight <= chainActive.Height() ) - { - CBlockIndex* pblockindex = chainActive[nHeight]; - hash = pblockindex->GetBlockHash(); - int32_t i; - for (i=0; i<32; i++) - printf("%02x",((uint8_t *)&hash)[i]); - printf(" blockhash.%d\n",nHeight); - } else memset(&hash,0,sizeof(hash)); - return(hash); -}*/ - -UniValue getblockheader(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "getblockheader \"hash\" ( verbose )\n" - "\nIf verbose is false, returns a string that is serialized, hex-encoded data for blockheader 'hash'.\n" - "If verbose is true, returns an Object with information about blockheader .\n" - "\nArguments:\n" - "1. \"hash\" (string, required) The block hash\n" - "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" - "\nResult (for verbose = true):\n" - "{\n" - " \"hash\" : \"hash\", (string) the block hash (same as provided)\n" - " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" - " \"height\" : n, (numeric) The block height or index\n" - " \"version\" : n, (numeric) The block version\n" - " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" - " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" - " \"nonce\" : n, (numeric) The nonce\n" - " \"bits\" : \"1d00ffff\", (string) The bits\n" - " \"difficulty\" : x.xxx, (numeric) The difficulty\n" - " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" - " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" - "}\n" - "\nResult (for verbose=false):\n" - "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" - "\nExamples:\n" - + HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - + HelpExampleRpc("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - ); - - LOCK(cs_main); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - - bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); - - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (!fVerbose) - { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(); - std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); - return strHex; - } - - return blockheaderToJSON(pblockindex); -} - -UniValue getblock(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 1 || params.size() > 2) - throw runtime_error( - "getblock \"hash|height\" ( verbose )\n" - "\nIf verbose is false, returns a string that is serialized, hex-encoded data for block 'hash|height'.\n" - "If verbose is true, returns an Object with information about block .\n" - "\nArguments:\n" - "1. \"hash|height\" (string, required) The block hash or height\n" - "2. verbose (boolean, optional, default=true) true for a json object, false for the hex encoded data\n" - "\nResult (for verbose = true):\n" - "{\n" - " \"hash\" : \"hash\", (string) the block hash (same as provided hash)\n" - " \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" - " \"size\" : n, (numeric) The block size\n" - " \"height\" : n, (numeric) The block height or index (same as provided height)\n" - " \"version\" : n, (numeric) The block version\n" - " \"merkleroot\" : \"xxxx\", (string) The merkle root\n" - " \"tx\" : [ (array of string) The transaction ids\n" - " \"transactionid\" (string) The transaction id\n" - " ,...\n" - " ],\n" - " \"time\" : ttt, (numeric) The block time in seconds since epoch (Jan 1 1970 GMT)\n" - " \"nonce\" : n, (numeric) The nonce\n" - " \"bits\" : \"1d00ffff\", (string) The bits\n" - " \"difficulty\" : x.xxx, (numeric) The difficulty\n" - " \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" - " \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" - "}\n" - "\nResult (for verbose=false):\n" - "\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" - "\nExamples:\n" - + HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") - + HelpExampleCli("getblock", "12800") - + HelpExampleRpc("getblock", "12800") - ); - - LOCK(cs_main); - - std::string strHash = params[0].get_str(); - - // If height is supplied, find the hash - if (strHash.size() < (2 * sizeof(uint256))) { - // std::stoi allows characters, whereas we want to be strict - regex r("[[:digit:]]+"); - if (!regex_match(strHash, r)) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); - } - - int nHeight = -1; - try { - nHeight = std::stoi(strHash); - } - catch (const std::exception &e) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); - } - - if (nHeight < 0 || nHeight > chainActive.Height()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - } - strHash = chainActive[nHeight]->GetBlockHash().GetHex(); - } - - uint256 hash(uint256S(strHash)); - - bool fVerbose = true; - if (params.size() > 1) - fVerbose = params[1].get_bool(); - - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlock block; - CBlockIndex* pblockindex = mapBlockIndex[hash]; - - if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - - if(!ReadBlockFromDisk(block, pblockindex,1)) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); - - if (!fVerbose) - { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << block; - std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); - return strHex; - } - - return blockToJSON(block, pblockindex); -} - -UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "gettxoutsetinfo\n" - "\nReturns statistics about the unspent transaction output set.\n" - "Note this call may take some time.\n" - "\nResult:\n" - "{\n" - " \"height\":n, (numeric) The current block height (index)\n" - " \"bestblock\": \"hex\", (string) the best block hash hex\n" - " \"transactions\": n, (numeric) The number of transactions\n" - " \"txouts\": n, (numeric) The number of output transactions\n" - " \"bytes_serialized\": n, (numeric) The serialized size\n" - " \"hash_serialized\": \"hash\", (string) The serialized hash\n" - " \"total_amount\": x.xxx (numeric) The total amount\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("gettxoutsetinfo", "") - + HelpExampleRpc("gettxoutsetinfo", "") - ); - - UniValue ret(UniValue::VOBJ); - - CCoinsStats stats; - FlushStateToDisk(); - if (pcoinsTip->GetStats(stats)) { - ret.push_back(Pair("height", (int64_t)stats.nHeight)); - ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); - ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); - ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); - ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); - ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); - ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); - } - return ret; -} - -#include "komodo_defs.h" -#include "komodo_structs.h" - -#define IGUANA_MAXSCRIPTSIZE 10001 -#define KOMODO_KVDURATION 1440 -#define KOMODO_KVBINARY 2 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; -uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume); -int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); -int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); -int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); - -UniValue kvsearch(const UniValue& params, bool fHelp) -{ - UniValue ret(UniValue::VOBJ); uint32_t flags; uint8_t value[IGUANA_MAXSCRIPTSIZE*8],key[IGUANA_MAXSCRIPTSIZE*8]; int32_t duration,j,height,valuesize,keylen; uint256 refpubkey; static uint256 zeroes; - if (fHelp || params.size() != 1 ) - throw runtime_error( - "kvsearch key\n" - "\nSearch for a key stored via the kvupdate command. This feature is only available for asset chains.\n" - "\nArguments:\n" - "1. key (string, required) search the chain for this key\n" - "\nResult:\n" - "{\n" - " \"coin\": \"xxxxx\", (string) chain the key is stored on\n" - " \"currentheight\": xxxxx, (numeric) current height of the chain\n" - " \"key\": \"xxxxx\", (string) key\n" - " \"keylen\": xxxxx, (string) length of the key \n" - " \"owner\": \"xxxxx\" (string) hex string representing the owner of the key \n" - " \"height\": xxxxx, (numeric) height the key was stored at\n" - " \"expiration\": xxxxx, (numeric) height the key will expire\n" - " \"flags\": x (numeric) 1 if the key was created with a password; 0 otherwise.\n" - " \"value\": \"xxxxx\", (string) stored value\n" - " \"valuesize\": xxxxx (string) amount of characters stored\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("kvsearch", "examplekey") - + HelpExampleRpc("kvsearch", "\"examplekey\"") - ); - LOCK(cs_main); - if ( (keylen= (int32_t)strlen(params[0].get_str().c_str())) > 0 ) - { - ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); - ret.push_back(Pair("currentheight", (int64_t)chainActive.LastTip()->nHeight)); - ret.push_back(Pair("key",params[0].get_str())); - ret.push_back(Pair("keylen",keylen)); - if ( keylen < sizeof(key) ) - { - memcpy(key,params[0].get_str().c_str(),keylen); - if ( (valuesize= komodo_kvsearch(&refpubkey,chainActive.LastTip()->nHeight,&flags,&height,value,key,keylen)) >= 0 ) - { - std::string val; char *valuestr; - val.resize(valuesize); - valuestr = (char *)val.data(); - memcpy(valuestr,value,valuesize); - if ( memcmp(&zeroes,&refpubkey,sizeof(refpubkey)) != 0 ) - ret.push_back(Pair("owner",refpubkey.GetHex())); - ret.push_back(Pair("height",height)); - duration = ((flags >> 2) + 1) * KOMODO_KVDURATION; - ret.push_back(Pair("expiration", (int64_t)(height+duration))); - ret.push_back(Pair("flags",(int64_t)flags)); - ret.push_back(Pair("value",val)); - ret.push_back(Pair("valuesize",valuesize)); - } else ret.push_back(Pair("error",(char *)"cant find key")); - } else ret.push_back(Pair("error",(char *)"key too big")); - } else ret.push_back(Pair("error",(char *)"null key")); - return ret; -} - -UniValue minerids(const UniValue& params, bool fHelp) -{ - uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); uint8_t minerids[2000],pubkeys[65][33]; int32_t i,j,n,numnotaries,tally[129]; - if ( fHelp || params.size() != 1 ) - throw runtime_error("minerids needs height\n"); - LOCK(cs_main); - int32_t height = atoi(params[0].get_str().c_str()); - if ( height <= 0 ) - height = chainActive.LastTip()->nHeight; - else - { - CBlockIndex *pblockindex = chainActive[height]; - if ( pblockindex != 0 ) - timestamp = pblockindex->GetBlockTime(); - } - if ( (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) - { - memset(tally,0,sizeof(tally)); - numnotaries = komodo_notaries(pubkeys,height,timestamp); - if ( numnotaries > 0 ) - { - for (i=0; i= numnotaries ) - tally[128]++; - else tally[minerids[i]]++; - } - for (i=0; i<64; i++) - { - UniValue item(UniValue::VOBJ); std::string hex,kmdaddress; char *hexstr,kmdaddr[64],*ptr; int32_t m; - hex.resize(66); - hexstr = (char *)hex.data(); - for (j=0; j<33; j++) - sprintf(&hexstr[j*2],"%02x",pubkeys[i][j]); - item.push_back(Pair("notaryid", i)); - - bitcoin_address(kmdaddr,60,pubkeys[i],33); - m = (int32_t)strlen(kmdaddr); - kmdaddress.resize(m); - ptr = (char *)kmdaddress.data(); - memcpy(ptr,kmdaddr,m); - item.push_back(Pair("KMDaddress", kmdaddress)); - - item.push_back(Pair("pubkey", hex)); - item.push_back(Pair("blocks", tally[i])); - a.push_back(item); - } - UniValue item(UniValue::VOBJ); - item.push_back(Pair("pubkey", (char *)"external miners")); - item.push_back(Pair("blocks", tally[128])); - a.push_back(item); - } - ret.push_back(Pair("mined", a)); - ret.push_back(Pair("numnotaries", numnotaries)); - } else ret.push_back(Pair("error", (char *)"couldnt extract minerids")); - return ret; -} - -UniValue notaries(const UniValue& params, bool fHelp) -{ - UniValue a(UniValue::VARR); uint32_t timestamp=0; UniValue ret(UniValue::VOBJ); int32_t i,j,n,m; char *hexstr; uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr; - if ( fHelp || (params.size() != 1 && params.size() != 2) ) - throw runtime_error("notaries height timestamp\n"); - LOCK(cs_main); - int32_t height = atoi(params[0].get_str().c_str()); - if ( params.size() == 2 ) - timestamp = (uint32_t)atol(params[1].get_str().c_str()); - else timestamp = (uint32_t)time(NULL); - if ( height < 0 ) - { - height = chainActive.LastTip()->nHeight; - timestamp = chainActive.LastTip()->GetBlockTime(); - } - else if ( params.size() < 2 ) - { - CBlockIndex *pblockindex = chainActive[height]; - if ( pblockindex != 0 ) - timestamp = pblockindex->GetBlockTime(); - } - if ( (n= komodo_notaries(pubkeys,height,timestamp)) > 0 ) - { - for (i=0; i 0 ) - ret.push_back(Pair("withdraws", opretbuf)); - else ret.push_back(Pair("withdraws", (char *)"")); - for (baseid=0; baseid<32; baseid++) - { - UniValue item(UniValue::VOBJ); UniValue obj(UniValue::VOBJ); - if ( pax_fiatstatus(&available,&deposited,&issued,&withdrawn,&approved,&redeemed,CURRENCIES[baseid]) == 0 ) - { - if ( deposited != 0 || issued != 0 || withdrawn != 0 || approved != 0 || redeemed != 0 ) - { - item.push_back(Pair("available", ValueFromAmount(available))); - item.push_back(Pair("deposited", ValueFromAmount(deposited))); - item.push_back(Pair("issued", ValueFromAmount(issued))); - item.push_back(Pair("withdrawn", ValueFromAmount(withdrawn))); - item.push_back(Pair("approved", ValueFromAmount(approved))); - item.push_back(Pair("redeemed", ValueFromAmount(redeemed))); - obj.push_back(Pair(CURRENCIES[baseid],item)); - a.push_back(obj); - } - } - } - ret.push_back(Pair("fiatstatus", a)); - return ret; -} - -UniValue paxprice(const UniValue& params, bool fHelp) -{ - if ( fHelp || params.size() > 4 || params.size() < 2 ) - throw runtime_error("paxprice \"base\" \"rel\" height\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); uint64_t basevolume=0,relvolume,seed; - std::string base = params[0].get_str(); - std::string rel = params[1].get_str(); - int32_t height; - if ( params.size() == 2 ) - height = chainActive.LastTip()->nHeight; - else height = atoi(params[2].get_str().c_str()); - //if ( params.size() == 3 || (basevolume= COIN * atof(params[3].get_str().c_str())) == 0 ) - basevolume = 100000; - relvolume = komodo_paxprice(&seed,height,(char *)base.c_str(),(char *)rel.c_str(),basevolume); - ret.push_back(Pair("base", base)); - ret.push_back(Pair("rel", rel)); - ret.push_back(Pair("height", height)); - char seedstr[32]; - sprintf(seedstr,"%llu",(long long)seed); - ret.push_back(Pair("seed", seedstr)); - if ( height < 0 || height > chainActive.Height() ) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - else - { - CBlockIndex *pblockindex = chainActive[height]; - if ( pblockindex != 0 ) - ret.push_back(Pair("timestamp", (int64_t)pblockindex->nTime)); - if ( basevolume != 0 && relvolume != 0 ) - { - ret.push_back(Pair("price",((double)relvolume / (double)basevolume))); - ret.push_back(Pair("invprice",((double)basevolume / (double)relvolume))); - ret.push_back(Pair("basevolume",ValueFromAmount(basevolume))); - ret.push_back(Pair("relvolume",ValueFromAmount(relvolume))); - } else ret.push_back(Pair("error", "overflow or error in one or more of parameters")); - } - return ret; -} - -UniValue paxprices(const UniValue& params, bool fHelp) -{ - if ( fHelp || params.size() != 3 ) - throw runtime_error("paxprices \"base\" \"rel\" maxsamples\n"); - LOCK(cs_main); - UniValue ret(UniValue::VOBJ); uint64_t relvolume,prices[4096]; uint32_t i,n; int32_t heights[sizeof(prices)/sizeof(*prices)]; - std::string base = params[0].get_str(); - std::string rel = params[1].get_str(); - int32_t maxsamples = atoi(params[2].get_str().c_str()); - if ( maxsamples < 1 ) - maxsamples = 1; - else if ( maxsamples > sizeof(heights)/sizeof(*heights) ) - maxsamples = sizeof(heights)/sizeof(*heights); - ret.push_back(Pair("base", base)); - ret.push_back(Pair("rel", rel)); - n = komodo_paxprices(heights,prices,maxsamples,(char *)base.c_str(),(char *)rel.c_str()); - UniValue a(UniValue::VARR); - for (i=0; i chainActive.Height() ) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - else - { - CBlockIndex *pblockindex = chainActive[heights[i]]; - - item.push_back(Pair("t", (int64_t)pblockindex->nTime)); - item.push_back(Pair("p", (double)prices[i] / COIN)); - a.push_back(item); - } - } - ret.push_back(Pair("array", a)); - return ret; -} - -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); - -UniValue gettxout(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() < 2 || params.size() > 3) - throw runtime_error( - "gettxout \"txid\" n ( includemempool )\n" - "\nReturns details about an unspent transaction output.\n" - "\nArguments:\n" - "1. \"txid\" (string, required) The transaction id\n" - "2. n (numeric, required) vout value\n" - "3. includemempool (boolean, optional) Whether to include the mempool\n" - "\nResult:\n" - "{\n" - " \"bestblock\" : \"hash\", (string) the block hash\n" - " \"confirmations\" : n, (numeric) The number of confirmations\n" - " \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" - " \"scriptPubKey\" : { (json object)\n" - " \"asm\" : \"code\", (string) \n" - " \"hex\" : \"hex\", (string) \n" - " \"reqSigs\" : n, (numeric) Number of required signatures\n" - " \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" - " \"addresses\" : [ (array of string) array of Komodo addresses\n" - " \"komodoaddress\" (string) Komodo address\n" - " ,...\n" - " ]\n" - " },\n" - " \"version\" : n, (numeric) The version\n" - " \"coinbase\" : true|false (boolean) Coinbase or not\n" - "}\n" - - "\nExamples:\n" - "\nGet unspent transactions\n" - + HelpExampleCli("listunspent", "") + - "\nView the details\n" - + HelpExampleCli("gettxout", "\"txid\" 1") + - "\nAs a json rpc call\n" - + HelpExampleRpc("gettxout", "\"txid\", 1") - ); - - LOCK(cs_main); - - UniValue ret(UniValue::VOBJ); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - int n = params[1].get_int(); - bool fMempool = true; - if (params.size() > 2) - fMempool = params[2].get_bool(); - - CCoins coins; - if (fMempool) { - LOCK(mempool.cs); - CCoinsViewMemPool view(pcoinsTip, mempool); - if (!view.GetCoins(hash, coins)) - return NullUniValue; - mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool - } else { - if (!pcoinsTip->GetCoins(hash, coins)) - return NullUniValue; - } - if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) - return NullUniValue; - - BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); - CBlockIndex *pindex = it->second; - ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); - if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) - ret.push_back(Pair("confirmations", 0)); - else - { - ret.push_back(Pair("confirmations", komodo_dpowconfs(coins.nHeight,pindex->nHeight - coins.nHeight + 1))); - ret.push_back(Pair("rawconfirmations", pindex->nHeight - coins.nHeight + 1)); - } - ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); - uint64_t interest; int32_t txheight; uint32_t locktime; - if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue,(int32_t)pindex->nHeight)) != 0 ) - ret.push_back(Pair("interest", ValueFromAmount(interest))); - UniValue o(UniValue::VOBJ); - ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); - ret.push_back(Pair("scriptPubKey", o)); - ret.push_back(Pair("version", coins.nVersion)); - ret.push_back(Pair("coinbase", coins.fCoinBase)); - - return ret; -} - -UniValue verifychain(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() > 2) - throw runtime_error( - "verifychain ( checklevel numblocks )\n" - "\nVerifies blockchain database.\n" - "\nArguments:\n" - "1. checklevel (numeric, optional, 0-4, default=3) How thorough the block verification is.\n" - "2. numblocks (numeric, optional, default=288, 0=all) The number of blocks to check.\n" - "\nResult:\n" - "true|false (boolean) Verified or not\n" - "\nExamples:\n" - + HelpExampleCli("verifychain", "") - + HelpExampleRpc("verifychain", "") - ); - - LOCK(cs_main); - - int nCheckLevel = GetArg("-checklevel", 3); - int nCheckDepth = GetArg("-checkblocks", 288); - if (params.size() > 0) - nCheckLevel = params[0].get_int(); - if (params.size() > 1) - nCheckDepth = params[1].get_int(); - - return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); -} - -/** Implementation of IsSuperMajority with better feedback */ -static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) -{ - int nFound = 0; - CBlockIndex* pstart = pindex; - for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++) - { - if (pstart->nVersion >= minVersion) - ++nFound; - pstart = pstart->pprev; - } - - UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("status", nFound >= nRequired)); - rv.push_back(Pair("found", nFound)); - rv.push_back(Pair("required", nRequired)); - rv.push_back(Pair("window", consensusParams.nMajorityWindow)); - return rv; -} - -static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) -{ - UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); - rv.push_back(Pair("version", version)); - rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); - rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams))); - return rv; -} - -static UniValue NetworkUpgradeDesc(const Consensus::Params& consensusParams, Consensus::UpgradeIndex idx, int height) -{ - UniValue rv(UniValue::VOBJ); - auto upgrade = NetworkUpgradeInfo[idx]; - rv.push_back(Pair("name", upgrade.strName)); - rv.push_back(Pair("activationheight", consensusParams.vUpgrades[idx].nActivationHeight)); - switch (NetworkUpgradeState(height, consensusParams, idx)) { - case UPGRADE_DISABLED: rv.push_back(Pair("status", "disabled")); break; - case UPGRADE_PENDING: rv.push_back(Pair("status", "pending")); break; - case UPGRADE_ACTIVE: rv.push_back(Pair("status", "active")); break; - } - rv.push_back(Pair("info", upgrade.strInfo)); - return rv; -} - -void NetworkUpgradeDescPushBack( - UniValue& networkUpgrades, - const Consensus::Params& consensusParams, - Consensus::UpgradeIndex idx, - int height) -{ - // Network upgrades with an activation height of NO_ACTIVATION_HEIGHT are - // hidden. This is used when network upgrade implementations are merged - // without specifying the activation height. - if (consensusParams.vUpgrades[idx].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { - networkUpgrades.push_back(Pair( - HexInt(NetworkUpgradeInfo[idx].nBranchId), - NetworkUpgradeDesc(consensusParams, idx, height))); - } -} - - -UniValue getblockchaininfo(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getblockchaininfo\n" - "Returns an object containing various state info regarding block chain processing.\n" - "\nNote that when the chain tip is at the last block before a network upgrade activation,\n" - "consensus.chaintip != consensus.nextblock.\n" - "\nResult:\n" - "{\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" - " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" - " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" - " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" - " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" - " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" - " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" - " \"size_on_disk\": xxxxxx, (numeric) the estimated size of the block and undo files on disk\n" - " \"commitments\": xxxxxx, (numeric) the current number of note commitments in the commitment tree\n" - " \"softforks\": [ (array) status of softforks in progress\n" - " {\n" - " \"id\": \"xxxx\", (string) name of softfork\n" - " \"version\": xx, (numeric) block version\n" - " \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n" - " \"status\": xx, (boolean) true if threshold reached\n" - " \"found\": xx, (numeric) number of blocks with the new version found\n" - " \"required\": xx, (numeric) number of blocks required to trigger\n" - " \"window\": xx, (numeric) maximum size of examined window of recent blocks\n" - " },\n" - " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" - " }, ...\n" - " ],\n" - " \"upgrades\": { (object) status of network upgrades\n" - " \"xxxx\" : { (string) branch ID of the upgrade\n" - " \"name\": \"xxxx\", (string) name of upgrade\n" - " \"activationheight\": xxxxxx, (numeric) block height of activation\n" - " \"status\": \"xxxx\", (string) status of upgrade\n" - " \"info\": \"xxxx\", (string) additional information about upgrade\n" - " }, ...\n" - " },\n" - " \"consensus\": { (object) branch IDs of the current and upcoming consensus rules\n" - " \"chaintip\": \"xxxxxxxx\", (string) branch ID used to validate the current chain tip\n" - " \"nextblock\": \"xxxxxxxx\" (string) branch ID that the next block will be validated under\n" - " }\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("getblockchaininfo", "") - + HelpExampleRpc("getblockchaininfo", "") - ); - - LOCK(cs_main); - double progress; - if ( ASSETCHAINS_SYMBOL[0] == 0 ) { - progress = Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.LastTip()); - } else { - int32_t longestchain = KOMODO_LONGESTCHAIN;//komodo_longestchain(); - progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; - } - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); - obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex())); - obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); - obj.push_back(Pair("verificationprogress", progress)); - obj.push_back(Pair("chainwork", chainActive.LastTip()->nChainWork.GetHex())); - obj.push_back(Pair("pruned", fPruneMode)); - obj.push_back(Pair("size_on_disk", CalculateCurrentUsage())); - - ZCIncrementalMerkleTree tree; - pcoinsTip->GetAnchorAt(pcoinsTip->GetBestAnchor(), tree); - #ifdef __APPLE__ - obj.push_back(Pair("commitments", (uint64_t)tree.size())); - #else - obj.push_back(Pair("commitments", tree.size())); - #endif - - CBlockIndex* tip = chainActive.LastTip(); - UniValue valuePools(UniValue::VARR); - valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none)); - obj.push_back(Pair("valuePools", valuePools)); - - const Consensus::Params& consensusParams = Params().GetConsensus(); - UniValue softforks(UniValue::VARR); - softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); - softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); - softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); - obj.push_back(Pair("softforks", softforks)); - - UniValue upgrades(UniValue::VOBJ); - for (int i = Consensus::UPGRADE_OVERWINTER; i < Consensus::MAX_NETWORK_UPGRADES; i++) { - NetworkUpgradeDescPushBack(upgrades, consensusParams, Consensus::UpgradeIndex(i), tip->nHeight); - } - obj.push_back(Pair("upgrades", upgrades)); - - UniValue consensus(UniValue::VOBJ); - consensus.push_back(Pair("chaintip", HexInt(CurrentEpochBranchId(tip->nHeight, consensusParams)))); - consensus.push_back(Pair("nextblock", HexInt(CurrentEpochBranchId(tip->nHeight + 1, consensusParams)))); - obj.push_back(Pair("consensus", consensus)); - - if (fPruneMode) - { - CBlockIndex *block = chainActive.LastTip(); - while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) - block = block->pprev; - - obj.push_back(Pair("pruneheight", block->nHeight)); - } - return obj; -} - -/** Comparison function for sorting the getchaintips heads. */ -struct CompareBlocksByHeight -{ - bool operator()(const CBlockIndex* a, const CBlockIndex* b) const - { - /* Make sure that unequal blocks with the same height do not compare - equal. Use the pointers themselves to make a distinction. */ - - if (a->nHeight != b->nHeight) - return (a->nHeight > b->nHeight); - - return a < b; - } -}; - -#include - -UniValue getchaintips(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getchaintips\n" - "Return information about all known tips in the block tree," - " including the main chain as well as orphaned branches.\n" - "\nResult:\n" - "[\n" - " {\n" - " \"height\": xxxx, (numeric) height of the chain tip\n" - " \"hash\": \"xxxx\", (string) block hash of the tip\n" - " \"branchlen\": 0 (numeric) zero for main chain\n" - " \"status\": \"active\" (string) \"active\" for the main chain\n" - " },\n" - " {\n" - " \"height\": xxxx,\n" - " \"hash\": \"xxxx\",\n" - " \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n" - " \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n" - " }\n" - "]\n" - "Possible values for status:\n" - "1. \"invalid\" This branch contains at least one invalid block\n" - "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" - "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" - "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" - "5. \"active\" This is the tip of the active main chain, which is certainly valid\n" - "\nExamples:\n" - + HelpExampleCli("getchaintips", "") - + HelpExampleRpc("getchaintips", "") - ); - - LOCK(cs_main); - - /* Build up a list of chain tips. We start with the list of all - known blocks, and successively remove blocks that appear as pprev - of another block. */ - /*static pthread_mutex_t mutex; static int32_t didinit; - if ( didinit == 0 ) - { - pthread_mutex_init(&mutex,NULL); - didinit = 1; - } - pthread_mutex_lock(&mutex);*/ - std::set setTips; - int32_t n = 0; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - { - n++; - setTips.insert(item.second); - } - fprintf(stderr,"iterations getchaintips %d\n",n); - n = 0; - BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) - { - const CBlockIndex* pprev=0; - n++; - if ( item.second != 0 ) - pprev = item.second->pprev; - if (pprev) - setTips.erase(pprev); - } - fprintf(stderr,"iterations getchaintips %d\n",n); - //pthread_mutex_unlock(&mutex); - - // Always report the currently active tip. - setTips.insert(chainActive.LastTip()); - - /* Construct the output array. */ - UniValue res(UniValue::VARR); const CBlockIndex *forked; - BOOST_FOREACH(const CBlockIndex* block, setTips) - BOOST_FOREACH(const CBlockIndex* block, setTips) - { - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("height", block->nHeight)); - obj.push_back(Pair("hash", block->phashBlock->GetHex())); - forked = chainActive.FindFork(block); - if ( forked != 0 ) - { - const int branchLen = block->nHeight - forked->nHeight; - obj.push_back(Pair("branchlen", branchLen)); - - string status; - if (chainActive.Contains(block)) { - // This block is part of the currently active chain. - status = "active"; - } else if (block->nStatus & BLOCK_FAILED_MASK) { - // This block or one of its ancestors is invalid. - status = "invalid"; - } else if (block->nChainTx == 0) { - // This block cannot be connected because full block data for it or one of its parents is missing. - status = "headers-only"; - } else if (block->IsValid(BLOCK_VALID_SCRIPTS)) { - // This block is fully validated, but no longer part of the active chain. It was probably the active block once, but was reorganized. - status = "valid-fork"; - } else if (block->IsValid(BLOCK_VALID_TREE)) { - // The headers for this block are valid, but it has not been validated. It was probably never part of the most-work chain. - status = "valid-headers"; - } else { - // No clue. - status = "unknown"; - } - obj.push_back(Pair("status", status)); - } - res.push_back(obj); - } - - return res; -} - -UniValue mempoolInfoToJSON() -{ - UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); - ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); - - return ret; -} - -UniValue getmempoolinfo(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getmempoolinfo\n" - "\nReturns details on the active state of the TX memory pool.\n" - "\nResult:\n" - "{\n" - " \"size\": xxxxx (numeric) Current tx count\n" - " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" - " \"usage\": xxxxx (numeric) Total memory usage for the mempool\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("getmempoolinfo", "") - + HelpExampleRpc("getmempoolinfo", "") - ); - - return mempoolInfoToJSON(); -} - -UniValue invalidateblock(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "invalidateblock \"hash\"\n" - "\nPermanently marks a block as invalid, as if it violated a consensus rule.\n" - "\nArguments:\n" - "1. hash (string, required) the hash of the block to mark as invalid\n" - "\nResult:\n" - "\nExamples:\n" - + HelpExampleCli("invalidateblock", "\"blockhash\"") - + HelpExampleRpc("invalidateblock", "\"blockhash\"") - ); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - CValidationState state; - - { - LOCK(cs_main); - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, pblockindex); - } - - if (state.IsValid()) { - ActivateBestChain(state); - } - - if (!state.IsValid()) { - throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); - } - - return NullUniValue; -} - -UniValue reconsiderblock(const UniValue& params, bool fHelp) -{ - if (fHelp || params.size() != 1) - throw runtime_error( - "reconsiderblock \"hash\"\n" - "\nRemoves invalidity status of a block and its descendants, reconsider them for activation.\n" - "This can be used to undo the effects of invalidateblock.\n" - "\nArguments:\n" - "1. hash (string, required) the hash of the block to reconsider\n" - "\nResult:\n" - "\nExamples:\n" - + HelpExampleCli("reconsiderblock", "\"blockhash\"") - + HelpExampleRpc("reconsiderblock", "\"blockhash\"") - ); - - std::string strHash = params[0].get_str(); - uint256 hash(uint256S(strHash)); - CValidationState state; - - { - LOCK(cs_main); - if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); - - CBlockIndex* pblockindex = mapBlockIndex[hash]; - ReconsiderBlock(state, pblockindex); - } - - if (state.IsValid()) { - ActivateBestChain(state); - } - - if (!state.IsValid()) { - throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); - } - - return NullUniValue; -} From 86a98587a1d1fa7c89f77ef213416eed7b5eb1b2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 10:14:52 -0400 Subject: [PATCH 142/220] desprout --- src/consensus/upgrades.cpp | 1 + src/serialize.h | 1 + src/wallet/asyncrpcoperation_mergetoaddress.h | 49 ---------- src/wallet/gtest/test_wallet.cpp | 5 - src/wallet/rpcwallet.cpp | 4 +- src/wallet/wallet.cpp | 2 +- src/wallet/wallet.h | 91 ++----------------- src/zcash/Address.hpp | 73 +-------------- src/zcash/JoinSplit.cpp | 18 ---- src/zcash/JoinSplit.hpp | 56 ------------ src/zcash/Note.hpp | 63 +------------ src/zcash/prf.h | 10 +- src/zcash/zip32.h | 3 +- 13 files changed, 24 insertions(+), 352 deletions(-) diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp index b75e0c002..984ca377e 100644 --- a/src/consensus/upgrades.cpp +++ b/src/consensus/upgrades.cpp @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers // Copyright (c) 2018 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/serialize.h b/src/serialize.h index 3d9c3fae6..9d23b469c 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2009-2014 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index 4876921db..32dbcf015 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -44,29 +44,11 @@ using namespace libzcash; // Input UTXO is a tuple of txid, vout, amount, script typedef std::tuple MergeToAddressInputUTXO; -// Input JSOP is a tuple of JSOutpoint, note, amount, spending key -typedef std::tuple MergeToAddressInputSproutNote; - typedef std::tuple MergeToAddressInputSaplingNote; // A recipient is a tuple of address, memo (optional if zaddr) typedef std::tuple MergeToAddressRecipient; -// Package of info which is passed to perform_joinsplit methods. -struct MergeToAddressJSInfo { - std::vector vjsin; - std::vector vjsout; - std::vector notes; - std::vector zkeys; - CAmount vpub_old = 0; - CAmount vpub_new = 0; -}; - -// A struct to help us track the witness and anchor for a given JSOutPoint -struct MergeToAddressWitnessAnchorData { - boost::optional witness; - uint256 anchor; -}; class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation { @@ -116,7 +98,6 @@ private: std::unordered_map jsopWitnessAnchorMap; std::vector utxoInputs_; - std::vector sproutNoteInputs_; std::vector saplingNoteInputs_; TransactionBuilder builder_; @@ -125,18 +106,6 @@ private: std::array get_memo_from_hex_string(std::string s); bool main_impl(); - // JoinSplit without any input notes to spend - UniValue perform_joinsplit(MergeToAddressJSInfo&); - - // JoinSplit with input notes to spend (JSOutPoints)) - UniValue perform_joinsplit(MergeToAddressJSInfo&, std::vector&); - - // JoinSplit where you have the witnesses and anchor - UniValue perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor); - void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error void lock_utxos(); @@ -180,24 +149,6 @@ public: return delegate->main_impl(); } - UniValue perform_joinsplit(MergeToAddressJSInfo& info) - { - return delegate->perform_joinsplit(info); - } - - UniValue perform_joinsplit(MergeToAddressJSInfo& info, std::vector& v) - { - return delegate->perform_joinsplit(info, v); - } - - UniValue perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor) - { - return delegate->perform_joinsplit(info, witnesses, anchor); - } - void sign_send_raw_transaction(UniValue obj) { delegate->sign_send_raw_transaction(obj); diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 0ad789137..6373b6e9f 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -75,11 +75,6 @@ CWalletTx GetValidReceive(const libzcash::SproutSpendingKey& sk, CAmount value, return GetValidReceive(*params, sk, value, randomInputs, version); } -libzcash::SproutNote GetNote(const libzcash::SproutSpendingKey& sk, - const CTransaction& tx, size_t js, size_t n) { - return GetNote(*params, sk, tx, js, n); -} - CWalletTx GetValidSpend(const libzcash::SproutSpendingKey& sk, const libzcash::SproutNote& note, CAmount value) { return GetValidSpend(*params, sk, note, value); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d3d396bbc..2a451dc12 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3123,7 +3123,7 @@ UniValue getalldata(const UniValue& params, bool fHelp,const CPubKey&) if (wtx.GetDepthInMainChain() < 0) continue; - if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted()) + if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted()) continue; //Assign Immature @@ -3309,7 +3309,7 @@ UniValue getalldata(const UniValue& params, bool fHelp,const CPubKey&) if (!CheckFinalTx(wtx)) continue; - if (wtx.mapSaplingNoteData.size() == 0 && wtx.mapSproutNoteData.size() == 0 && !wtx.IsTrusted()) + if (wtx.mapSaplingNoteData.size() == 0 && !wtx.IsTrusted()) continue; //Excude transactions with less confirmations than required diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4be804abb..a346a547f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -934,7 +934,7 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO for (std::pair& wtxItem : mapWallet) { nWitnessTxIncrement += 1; - if (wtxItem.second.mapSproutNoteData.empty() && wtxItem.second.mapSaplingNoteData.empty()) + if (wtxItem.second.mapSaplingNoteData.empty()) continue; if (wtxItem.second.GetDepthInMainChain() > 0) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index f3526c583..0cd7d8bb6 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -236,82 +236,19 @@ public: std::string ToString() const; }; -class SproutNoteData +class SaplingNoteData { public: - libzcash::SproutPaymentAddress address; - - /** - * Cached note nullifier. May not be set if the wallet was not unlocked when - * this was SproutNoteData was created. If not set, we always assume that the - * note has not been spent. - * - * It's okay to cache the nullifier in the wallet, because we are storing - * the spending key there too, which could be used to derive this. - * If the wallet is encrypted, this means that someone with access to the - * locked wallet cannot spend notes, but can connect received notes to the - * transactions they are spent in. This is the same security semantics as - * for transparent addresses. - */ - boost::optional nullifier; - - /** - * Cached incremental witnesses for spendable Notes. - * Beginning of the list is the most recent witness. - */ - std::list witnesses; - /** * Block height corresponding to the most current witness. * - * When we first create a SproutNoteData in CWallet::FindMySproutNotes, this is set to + * When we first create a SaplingNoteData in CWallet::FindMySaplingNotes, this is set to * -1 as a placeholder. The next time CWallet::ChainTip is called, we can * determine what height the witness cache for this note is valid for (even * if no witnesses were cached), and so can set the correct value in * CWallet::BuildWitnessCache and CWallet::DecrementNoteWitnesses. */ - int witnessHeight; - //In Memory Only - bool witnessRootValidated; - - SproutNoteData() : address(), nullifier(), witnessHeight {-1}, witnessRootValidated {false} { } - SproutNoteData(libzcash::SproutPaymentAddress a) : - address {a}, nullifier(), witnessHeight {-1}, witnessRootValidated {false} { } - SproutNoteData(libzcash::SproutPaymentAddress a, uint256 n) : - address {a}, nullifier {n}, witnessHeight {-1}, witnessRootValidated {false} { } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(address); - READWRITE(nullifier); - READWRITE(witnesses); - READWRITE(witnessHeight); - } - - friend bool operator<(const SproutNoteData& a, const SproutNoteData& b) { - return (a.address < b.address || - (a.address == b.address && a.nullifier < b.nullifier)); - } - - friend bool operator==(const SproutNoteData& a, const SproutNoteData& b) { - return (a.address == b.address && a.nullifier == b.nullifier); - } - - friend bool operator!=(const SproutNoteData& a, const SproutNoteData& b) { - return !(a == b); - } -}; - -class SaplingNoteData -{ -public: - /** - * We initialize the height to -1 for the same reason as we do in SproutNoteData. - * See the comment in that class for a full description. - */ SaplingNoteData() : witnessHeight {-1}, nullifier() { } SaplingNoteData(libzcash::SaplingIncomingViewingKey ivk) : ivk {ivk}, witnessHeight {-1}, nullifier() { } SaplingNoteData(libzcash::SaplingIncomingViewingKey ivk, uint256 n) : ivk {ivk}, witnessHeight {-1}, nullifier(n) { } @@ -347,18 +284,11 @@ public: } }; + +// NOTE: this sprout structure is serialized into wallet.dat, removing it would change wallet.dat format on disk :( typedef std::map mapSproutNoteData_t; typedef std::map mapSaplingNoteData_t; -/** Decrypted note, its location in a transaction, and number of confirmations. */ -struct CSproutNotePlaintextEntry -{ - JSOutPoint jsop; - libzcash::SproutPaymentAddress address; - libzcash::SproutNotePlaintext plaintext; - int confirmations; -}; - /** Sapling note, its location in a transaction, and number of confirmations. */ struct SaplingNoteEntry { @@ -824,7 +754,6 @@ public: protected: - int SproutWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight); int SaplingWitnessMinimumHeight(const uint256& nullifier, int nWitnessHeight, int nMinimumHeight); /** @@ -848,11 +777,11 @@ protected: try { for (std::pair& wtxItem : mapWallet) { auto wtx = wtxItem.second; - // We skip transactions for which mapSproutNoteData and mapSaplingNoteData - // are empty. This covers transactions that have no Sprout or Sapling data + // We skip transactions for which mapSaplingNoteData + // is empty. This covers transactions that have no Sapling data // (i.e. are purely transparent), as well as shielding and unshielding // transactions in which we only have transparent addresses involved. - if (!(wtx.mapSproutNoteData.empty() && wtx.mapSaplingNoteData.empty())) { + if (!(wtx.mapSaplingNoteData.empty())) { if (!walletdb.WriteTx(wtxItem.first, wtx)) { LogPrintf("SetBestChain(): Failed to write CWalletTx, aborting atomic write\n"); walletdb.TxnAbort(); @@ -1319,8 +1248,7 @@ public: bool LoadCryptedHDSeed(const uint256& seedFp, const std::vector& seed); /* Find notes filtered by payment address, min depth, ability to spend */ - void GetFilteredNotes(std::vector& sproutEntries, - std::vector& saplingEntries, + void GetFilteredNotes(std::vector& saplingEntries, std::string address, int minDepth=1, bool ignoreSpent=true, @@ -1328,8 +1256,7 @@ public: /* Find notes filtered by payment addresses, min depth, max depth, if they are spent, if a spending key is required, and if they are locked */ - void GetFilteredNotes(std::vector& sproutEntries, - std::vector& saplingEntries, + void GetFilteredNotes(std::vector& saplingEntries, std::set& filterAddresses, int minDepth=1, int maxDepth=INT_MAX, diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index 42ee0031b..df9034bce 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #ifndef ZC_ADDRESS_H_ #define ZC_ADDRESS_H_ @@ -26,34 +28,6 @@ const size_t SerializedSaplingSpendingKeySize = 32; typedef std::array diversifier_t; -class SproutPaymentAddress { -public: - uint256 a_pk; - uint256 pk_enc; - - SproutPaymentAddress() : a_pk(), pk_enc() { } - SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(a_pk); - READWRITE(pk_enc); - } - - //! Get the 256-bit SHA256d hash of this payment address. - uint256 GetHash() const; - - friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { - return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc; - } - friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { - return (a.a_pk < b.a_pk || - (a.a_pk == b.a_pk && a.pk_enc < b.pk_enc)); - } -}; - class ReceivingKey : public uint256 { public: ReceivingKey() { } @@ -62,45 +36,6 @@ public: uint256 pk_enc() const; }; -class SproutViewingKey { -public: - uint256 a_pk; - ReceivingKey sk_enc; - - SproutViewingKey() : a_pk(), sk_enc() { } - SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(a_pk); - READWRITE(sk_enc); - } - - SproutPaymentAddress address() const; - - friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) { - return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc; - } - friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) { - return (a.a_pk < b.a_pk || - (a.a_pk == b.a_pk && a.sk_enc < b.sk_enc)); - } -}; - -class SproutSpendingKey : public uint252 { -public: - SproutSpendingKey() : uint252() { } - SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { } - - static SproutSpendingKey random(); - - ReceivingKey receiving_key() const; - SproutViewingKey viewing_key() const; - SproutPaymentAddress address() const; -}; - //! Sapling functions. class SaplingPaymentAddress { public: @@ -218,8 +153,8 @@ public: SaplingPaymentAddress default_address() const; }; -typedef boost::variant PaymentAddress; -typedef boost::variant ViewingKey; +typedef boost::variant PaymentAddress; +typedef boost::variant ViewingKey; } diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 0a052209a..e71bf25b1 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -246,24 +246,6 @@ uint256 JoinSplit::h_sig( return output; } -SproutNote JSOutput::note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const { - uint256 rho = PRF_rho(phi, i, h_sig); - - return SproutNote(addr.a_pk, value, rho, r); -} - -JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) { - SproutSpendingKey a_sk = SproutSpendingKey::random(); - addr = a_sk.address(); -} - -JSInput::JSInput() : witness(SproutMerkleTree().witness()), - key(SproutSpendingKey::random()) { - note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256()); - SproutMerkleTree dummy_tree; - dummy_tree.append(note.cm()); - witness = dummy_tree.witness(); -} template class JoinSplit; diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index 09e31570f..27df05db0 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -24,69 +24,13 @@ typedef std::array GrothProof; typedef boost::variant SproutProof; class JSInput { -public: - SproutWitness witness; - SproutNote note; - SproutSpendingKey key; - - JSInput(); - JSInput(SproutWitness witness, - SproutNote note, - SproutSpendingKey key) : witness(witness), note(note), key(key) { } - - uint256 nullifier() const { - return note.nullifier(key); - } }; class JSOutput { -public: - SproutPaymentAddress addr; - uint64_t value; - std::array memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00 - - JSOutput(); - JSOutput(SproutPaymentAddress addr, uint64_t value) : addr(addr), value(value) { } - - SproutNote note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const; }; template class JoinSplit { -public: - virtual ~JoinSplit() {} - - static JoinSplit* Prepared(); - - static uint256 h_sig(const uint256& randomSeed, - const std::array& nullifiers, - const uint256& joinSplitPubKey - ); - - // Compute nullifiers, macs, note commitments & encryptions, and SNARK proof - virtual SproutProof prove( - const std::array& inputs, - const std::array& outputs, - std::array& out_notes, - std::array& out_ciphertexts, - uint256& out_ephemeralKey, - const uint256& joinSplitPubKey, - uint256& out_randomSeed, - std::array& out_hmacs, - std::array& out_nullifiers, - std::array& out_commitments, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt, - bool computeProof = true, - // For paymentdisclosure, we need to retrieve the esk. - // Reference as non-const parameter with default value leads to compile error. - // So use pointer for simplicity. - uint256 *out_esk = nullptr - ) = 0; - -protected: - JoinSplit() {} }; } diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 7d3377306..5b16d95c5 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #ifndef ZC_NOTE_H_ #define ZC_NOTE_H_ @@ -22,25 +24,6 @@ public: inline uint64_t value() const { return value_; }; }; -class SproutNote : public BaseNote { -public: - uint256 a_pk; - uint256 rho; - uint256 r; - - SproutNote(uint256 a_pk, uint64_t value, uint256 rho, uint256 r) - : BaseNote(value), a_pk(a_pk), rho(rho), r(r) {} - - SproutNote(); - - virtual ~SproutNote() {}; - - uint256 cm() const; - - uint256 nullifier(const SproutSpendingKey& a_sk) const; -}; - - class SaplingNote : public BaseNote { public: diversifier_t d; @@ -74,48 +57,6 @@ public: inline const std::array & memo() const { return memo_; } }; -class SproutNotePlaintext : public BaseNotePlaintext { -public: - uint256 rho; - uint256 r; - - SproutNotePlaintext() {} - - SproutNotePlaintext(const SproutNote& note, std::array memo); - - SproutNote note(const SproutPaymentAddress& addr) const; - - virtual ~SproutNotePlaintext() {} - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - unsigned char leadingByte = 0x00; - READWRITE(leadingByte); - - if (leadingByte != 0x00) { - throw std::ios_base::failure("lead byte of SproutNotePlaintext is not recognized"); - } - - READWRITE(value_); - READWRITE(rho); - READWRITE(r); - READWRITE(memo_); - } - - static SproutNotePlaintext decrypt(const ZCNoteDecryption& decryptor, - const ZCNoteDecryption::Ciphertext& ciphertext, - const uint256& ephemeralKey, - const uint256& h_sig, - unsigned char nonce - ); - - ZCNoteEncryption::Ciphertext encrypt(ZCNoteEncryption& encryptor, - const uint256& pk_enc - ) const; -}; - typedef std::pair SaplingNotePlaintextEncryptionResult; class SaplingNotePlaintext : public BaseNotePlaintext { diff --git a/src/zcash/prf.h b/src/zcash/prf.h index f666cfa23..adfd7d710 100644 --- a/src/zcash/prf.h +++ b/src/zcash/prf.h @@ -1,5 +1,6 @@ +// Copyright (c) 2019-2020 The Hush developers /* -Zcash uses SHA256Compress as a PRF for various components +Hush uses SHA256Compress as a PRF for various components within the zkSNARK circuit. */ @@ -11,13 +12,6 @@ within the zkSNARK circuit. #include -//! Sprout functions -uint256 PRF_addr_a_pk(const uint252& a_sk); -uint256 PRF_addr_sk_enc(const uint252& a_sk); -uint256 PRF_nf(const uint252& a_sk, const uint256& rho); -uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig); -uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig); - //! Sapling functions uint256 PRF_ask(const uint256& sk); uint256 PRF_nsk(const uint256& sk); diff --git a/src/zcash/zip32.h b/src/zcash/zip32.h index 44bc58598..1521dddd1 100644 --- a/src/zcash/zip32.h +++ b/src/zcash/zip32.h @@ -1,4 +1,5 @@ // Copyright (c) 2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -134,7 +135,7 @@ struct SaplingExtendedSpendingKey { } }; -typedef boost::variant SpendingKey; +typedef boost::variant SpendingKey; } From a44fa2ede4f474ed5a70dfa7a391ead3bf60075d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 10:24:22 -0400 Subject: [PATCH 143/220] This datastructure is tied to the wallet.dat format on disk --- src/wallet/wallet.h | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0cd7d8bb6..f6e6274d1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -236,6 +236,56 @@ public: std::string ToString() const; }; +// NOTE: wallet.dat format depends on this data structure :( +class SproutNoteData + { + public: + libzcash::SproutPaymentAddress address; + + /** + * Cached note nullifier. May not be set if the wallet was not unlocked when + * this was SproutNoteData was created. If not set, we always assume that the + * note has not been spent. + * + * It's okay to cache the nullifier in the wallet, because we are storing + * the spending key there too, which could be used to derive this. + * If the wallet is encrypted, this means that someone with access to the + * locked wallet cannot spend notes, but can connect received notes to the + * transactions they are spent in. This is the same security semantics as + * for transparent addresses. + */ + boost::optional nullifier; + + /** + * Cached incremental witnesses for spendable Notes. + * Beginning of the list is the most recent witness. + */ + std::list witnesses; + + /** + * Block height corresponding to the most current witness. + * + * When we first create a SaplingNoteData in CWallet::FindMySaplingNotes, this is set to + * -1 as a placeholder. The next time CWallet::ChainTip is called, we can + * determine what height the witness cache for this note is valid for (even + * if no witnesses were cached), and so can set the correct value in + * CWallet::BuildWitnessCache and CWallet::DecrementNoteWitnesses. + */ + int witnessHeight; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(address); + READWRITE(nullifier); + READWRITE(witnesses); + READWRITE(witnessHeight); + } + +}; + + class SaplingNoteData { public: From 90406d601c9ece64697379568982224af1970d87 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 11:13:30 -0400 Subject: [PATCH 144/220] desprout --- src/primitives/transaction.cpp | 78 +------------------------ src/wallet/asyncrpcoperation_sendmany.h | 43 +------------- src/zcash/Address.hpp | 31 ++++++++++ 3 files changed, 33 insertions(+), 119 deletions(-) diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 2cde04f2c..53aeeda99 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -26,83 +27,6 @@ #include "librustzcash.h" -JSDescription::JSDescription( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& anchor, - const std::array& inputs, - const std::array& outputs, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof, - uint256 *esk // payment disclosure -) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) -{ - std::array notes; - - proof = params.prove( - inputs, - outputs, - notes, - ciphertexts, - ephemeralKey, - joinSplitPubKey, - randomSeed, - macs, - nullifiers, - commitments, - vpub_old, - vpub_new, - anchor, - computeProof, - esk // payment disclosure - ); -} - -JSDescription JSDescription::Randomized( - ZCJoinSplit& params, - const uint256& joinSplitPubKey, - const uint256& anchor, - std::array& inputs, - std::array& outputs, - std::array& inputMap, - std::array& outputMap, - CAmount vpub_old, - CAmount vpub_new, - bool computeProof, - uint256 *esk, // payment disclosure - std::function gen -) -{ - // Randomize the order of the inputs and outputs - inputMap = {0, 1}; - outputMap = {0, 1}; - - assert(gen); - - MappedShuffle(inputs.begin(), inputMap.begin(), ZC_NUM_JS_INPUTS, gen); - MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen); - - return JSDescription( - params, joinSplitPubKey, anchor, inputs, outputs, - vpub_old, vpub_new, computeProof, - esk // payment disclosure - ); -} - -bool JSDescription::Verify( - ZCJoinSplit& params, - libzcash::ProofVerifier& verifier, - const uint256& joinSplitPubKey -) const { - return false; -} - -uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const -{ - return params.h_sig(randomSeed, nullifiers, joinSplitPubKey); -} - std::string COutPoint::ToString() const { return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 0b803ddd9..86e6ef775 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -46,19 +46,6 @@ typedef std::tuple SendManyRecipient; // Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase) typedef std::tuple SendManyInputUTXO; -// Input JSOP is a tuple of JSOutpoint, note and amount -typedef std::tuple SendManyInputJSOP; - -// Package of info which is passed to perform_joinsplit methods. -struct AsyncJoinSplitInfo -{ - std::vector vjsin; - std::vector vjsout; - std::vector notes; - CAmount vpub_old = 0; - CAmount vpub_new = 0; -}; - // A struct to help us track the witness and anchor for a given JSOutPoint struct WitnessAnchorData { boost::optional witness; @@ -115,7 +102,7 @@ private: std::vector t_outputs_; std::vector z_outputs_; std::vector t_inputs_; - std::vector z_sprout_inputs_; + //std::vector z_sprout_inputs_; std::vector z_sapling_inputs_; TransactionBuilder builder_; @@ -128,18 +115,6 @@ private: std::array get_memo_from_hex_string(std::string s); bool main_impl(); - // JoinSplit without any input notes to spend - UniValue perform_joinsplit(AsyncJoinSplitInfo &); - - // JoinSplit with input notes to spend (JSOutPoints)) - UniValue perform_joinsplit(AsyncJoinSplitInfo &, std::vector & ); - - // JoinSplit where you have the witnesses and anchor - UniValue perform_joinsplit( - AsyncJoinSplitInfo & info, - std::vector> witnesses, - uint256 anchor); - void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error }; @@ -185,22 +160,6 @@ public: return delegate->main_impl(); } - UniValue perform_joinsplit(AsyncJoinSplitInfo &info) { - return delegate->perform_joinsplit(info); - } - - UniValue perform_joinsplit(AsyncJoinSplitInfo &info, std::vector &v ) { - return delegate->perform_joinsplit(info, v); - } - - UniValue perform_joinsplit( - AsyncJoinSplitInfo & info, - std::vector> witnesses, - uint256 anchor) - { - return delegate->perform_joinsplit(info, witnesses, anchor); - } - void sign_send_raw_transaction(UniValue obj) { delegate->sign_send_raw_transaction(obj); } diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index df9034bce..ac90120a5 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -36,6 +36,37 @@ public: uint256 pk_enc() const; }; + +// NOTE: wallet.dat format depends on this +class SproutPaymentAddress { +public: + uint256 a_pk; + uint256 pk_enc; + + SproutPaymentAddress() : a_pk(), pk_enc() { } + SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(a_pk); + READWRITE(pk_enc); + } + + //! Get the 256-bit SHA256d hash of this payment address. + uint256 GetHash() const; + + friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { + return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc; + } + friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) { + return (a.a_pk < b.a_pk || + (a.a_pk == b.a_pk && a.pk_enc < b.pk_enc)); + } +}; + + //! Sapling functions. class SaplingPaymentAddress { public: From 3cb215e39ad5fc163cfb4b726d6eb3e6ad13bde7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 12:17:41 -0400 Subject: [PATCH 145/220] more desprout, ugh --- src/init.cpp | 5 +- src/rpc/client.cpp | 2 - src/rpc/server.cpp | 6 +- .../asyncrpcoperation_mergetoaddress.cpp | 1 - src/wallet/asyncrpcoperation_sendmany.cpp | 4 +- src/wallet/rpcwallet.cpp | 8 +- src/zcash/JoinSplit.cpp | 163 +----------------- src/zcash/Note.cpp | 4 + src/zcash/prf.h | 10 +- 9 files changed, 21 insertions(+), 182 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index fd0303786..32cefbe91 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1042,10 +1042,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-developerencryptwallet")) { fprintf(stderr,"%s wallet encryption error\n", __FUNCTION__); return InitError(_("Wallet encryption requires -experimentalfeatures.")); - } - else if (mapArgs.count("-paymentdisclosure")) { - fprintf(stderr,"%s payment disclosure error\n", __FUNCTION__); - return InitError(_("Payment disclosure requires -experimentalfeatures.")); + //TODO: make this non experimental } else if (mapArgs.count("-zmergetoaddress")) { fprintf(stderr,"%s zmerge error\n", __FUNCTION__); return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures.")); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 79011da34..4f11a476f 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -164,8 +164,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "kvupdate", 4 }, { "z_importkey", 2 }, { "z_importviewingkey", 2 }, - { "z_getpaymentdisclosure", 1}, - { "z_getpaymentdisclosure", 2}, { "z_listsentbyaddress", 1}, { "z_listsentbyaddress", 2}, { "z_listsentbyaddress", 3}, diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 181de29bb..cfe21a6d5 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -669,11 +669,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "z_importviewingkey", &z_importviewingkey, true }, { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, - { "wallet", "opreturn_burn", &opreturn_burn, true }, - - // TODO: rearrange into another category - { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, - { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } + { "wallet", "opreturn_burn", &opreturn_burn, true } #endif // ENABLE_WALLET }; diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 4e47a5a2d..0ecb1ec12 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -46,7 +46,6 @@ #include #include -#include "paymentdisclosuredb.h" int32_t komodo_blockheight(uint256 hash); using namespace libzcash; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 31f987bef..06b8960cf 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -49,7 +49,6 @@ #include #include -#include "paymentdisclosuredb.h" #include using namespace libzcash; @@ -142,9 +141,8 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } - // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); + paymentDisclosureMode = false; } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2a451dc12..340f62a9c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8309,9 +8309,6 @@ extern UniValue z_importviewingkey(const UniValue& params, bool fHelp, const CPu extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp -extern UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); - static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- @@ -8380,10 +8377,7 @@ static const CRPCCommand commands[] = { "wallet", "z_getinfo", &z_getinfo, true }, { "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true }, - { "wallet", "z_getnotescount", &z_getnotescount, false }, - // TODO: rearrange into another category - { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, - { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } + { "wallet", "z_getnotescount", &z_getnotescount, false } }; diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index e71bf25b1..db51ff1fd 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers #include "JoinSplit.hpp" #include "prf.h" #include "sodium.h" @@ -28,6 +29,7 @@ public: JoinSplitCircuit() {} ~JoinSplitCircuit() {} + /* SproutProof prove( const std::array& inputs, const std::array& outputs, @@ -45,169 +47,13 @@ public: bool computeProof, uint256 *out_esk // Payment disclosure ) { - if (vpub_old > MAX_MONEY) { - throw std::invalid_argument("nonsensical vpub_old value"); - } - - if (vpub_new > MAX_MONEY) { - throw std::invalid_argument("nonsensical vpub_new value"); - } - - uint64_t lhs_value = vpub_old; - uint64_t rhs_value = vpub_new; - - for (size_t i = 0; i < NumInputs; i++) { - // Sanity checks of input - { - // If note has nonzero value - if (inputs[i].note.value() != 0) { - // The witness root must equal the input root. - if (inputs[i].witness.root() != rt) { - throw std::invalid_argument("joinsplit not anchored to the correct root"); - } - - // The tree must witness the correct element - if (inputs[i].note.cm() != inputs[i].witness.element()) { - throw std::invalid_argument("witness of wrong element for joinsplit input"); - } - } - - // Ensure we have the key to this note. - if (inputs[i].note.a_pk != inputs[i].key.address().a_pk) { - throw std::invalid_argument("input note not authorized to spend with given key"); - } - - // Balance must be sensical - if (inputs[i].note.value() > MAX_MONEY) { - throw std::invalid_argument("nonsensical input note value"); - } - - lhs_value += inputs[i].note.value(); - - if (lhs_value > MAX_MONEY) { - throw std::invalid_argument("nonsensical left hand size of joinsplit balance"); - } - } - - // Compute nullifier of input - out_nullifiers[i] = inputs[i].nullifier(); - } - - // Sample randomSeed - out_randomSeed = random_uint256(); - - // Compute h_sig - uint256 h_sig = this->h_sig(out_randomSeed, out_nullifiers, joinSplitPubKey); - - // Sample phi - uint252 phi = random_uint252(); - - // Compute notes for outputs - for (size_t i = 0; i < NumOutputs; i++) { - // Sanity checks of output - { - if (outputs[i].value > MAX_MONEY) { - throw std::invalid_argument("nonsensical output value"); - } - - rhs_value += outputs[i].value; - - if (rhs_value > MAX_MONEY) { - throw std::invalid_argument("nonsensical right hand side of joinsplit balance"); - } - } - - // Sample r - uint256 r = random_uint256(); - - out_notes[i] = outputs[i].note(phi, r, i, h_sig); - } - - if (lhs_value != rhs_value) { - throw std::invalid_argument("invalid joinsplit balance"); - } - - // Compute the output commitments - for (size_t i = 0; i < NumOutputs; i++) { - out_commitments[i] = out_notes[i].cm(); - } - - // Encrypt the ciphertexts containing the note - // plaintexts to the recipients of the value. - { - ZCNoteEncryption encryptor(h_sig); - - for (size_t i = 0; i < NumOutputs; i++) { - SproutNotePlaintext pt(out_notes[i], outputs[i].memo); - - out_ciphertexts[i] = pt.encrypt(encryptor, outputs[i].addr.pk_enc); - } - - out_ephemeralKey = encryptor.get_epk(); - - // !!! Payment disclosure START - if (out_esk != nullptr) { - *out_esk = encryptor.get_esk(); - } - // !!! Payment disclosure END - } - - // Authenticate h_sig with each of the input - // spending keys, producing macs which protect - // against malleability. - for (size_t i = 0; i < NumInputs; i++) { - out_macs[i] = PRF_pk(inputs[i].key, i, h_sig); - } - - if (!computeProof) { - return GrothProof(); - } - GrothProof proof; - - CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION); - ss1 << inputs[0].witness.path(); - std::vector auth1(ss1.begin(), ss1.end()); - - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << inputs[1].witness.path(); - std::vector auth2(ss2.begin(), ss2.end()); - - librustzcash_sprout_prove( - proof.begin(), - - phi.begin(), - rt.begin(), - h_sig.begin(), - - inputs[0].key.begin(), - inputs[0].note.value(), - inputs[0].note.rho.begin(), - inputs[0].note.r.begin(), - auth1.data(), - - inputs[1].key.begin(), - inputs[1].note.value(), - inputs[1].note.rho.begin(), - inputs[1].note.r.begin(), - auth2.data(), - - out_notes[0].a_pk.begin(), - out_notes[0].value(), - out_notes[0].r.begin(), - - out_notes[1].a_pk.begin(), - out_notes[1].value(), - out_notes[1].r.begin(), - - vpub_old, - vpub_new - ); - return proof; } + */ }; +/* template JoinSplit* JoinSplit::Prepared() { @@ -250,4 +96,5 @@ uint256 JoinSplit::h_sig( template class JoinSplit; +*/ } diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 23210c784..f9e9a2058 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include "Note.hpp" #include "prf.h" #include "crypto/sha256.h" @@ -11,6 +13,7 @@ using namespace libzcash; +/* SproutNote::SproutNote() { a_pk = random_uint256(); rho = random_uint256(); @@ -39,6 +42,7 @@ uint256 SproutNote::cm() const { uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const { return PRF_nf(a_sk, rho); } +*/ // Construct and populate Sapling note for a given payment address and value. SaplingNote::SaplingNote(const SaplingPaymentAddress& address, const uint64_t value) : BaseNote(value) { diff --git a/src/zcash/prf.h b/src/zcash/prf.h index adfd7d710..f666cfa23 100644 --- a/src/zcash/prf.h +++ b/src/zcash/prf.h @@ -1,6 +1,5 @@ -// Copyright (c) 2019-2020 The Hush developers /* -Hush uses SHA256Compress as a PRF for various components +Zcash uses SHA256Compress as a PRF for various components within the zkSNARK circuit. */ @@ -12,6 +11,13 @@ within the zkSNARK circuit. #include +//! Sprout functions +uint256 PRF_addr_a_pk(const uint252& a_sk); +uint256 PRF_addr_sk_enc(const uint252& a_sk); +uint256 PRF_nf(const uint252& a_sk, const uint256& rho); +uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig); +uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig); + //! Sapling functions uint256 PRF_ask(const uint256& sk); uint256 PRF_nsk(const uint256& sk); From 0cc4772c2559daf5616c03e8c217c3a2a0f26361 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 5 Jun 2020 12:43:01 -0400 Subject: [PATCH 146/220] desprout --- src/zcash/Note.cpp | 51 ---------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index f9e9a2058..9cd327d1b 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -92,57 +92,6 @@ boost::optional SaplingNote::nullifier(const SaplingFullViewingKey& vk, return result; } -SproutNotePlaintext::SproutNotePlaintext( - const SproutNote& note, - std::array memo) : BaseNotePlaintext(note, memo) -{ - rho = note.rho; - r = note.r; -} - -SproutNote SproutNotePlaintext::note(const SproutPaymentAddress& addr) const -{ - return SproutNote(addr.a_pk, value_, rho, r); -} - -SproutNotePlaintext SproutNotePlaintext::decrypt(const ZCNoteDecryption& decryptor, - const ZCNoteDecryption::Ciphertext& ciphertext, - const uint256& ephemeralKey, - const uint256& h_sig, - unsigned char nonce - ) -{ - auto plaintext = decryptor.decrypt(ciphertext, ephemeralKey, h_sig, nonce); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << plaintext; - - SproutNotePlaintext ret; - ss >> ret; - - assert(ss.size() == 0); - - return ret; -} - -ZCNoteEncryption::Ciphertext SproutNotePlaintext::encrypt(ZCNoteEncryption& encryptor, - const uint256& pk_enc - ) const -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << (*this); - - ZCNoteEncryption::Plaintext pt; - - assert(pt.size() == ss.size()); - - memcpy(&pt[0], &ss[0], pt.size()); - - return encryptor.encrypt(pk_enc, pt); -} - - - // Construct and populate SaplingNotePlaintext for a given note and memo. SaplingNotePlaintext::SaplingNotePlaintext( const SaplingNote& note, From 22d4d1a06e88d0cc6bae7bc8dc4665931d5b11a8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 04:34:30 -0400 Subject: [PATCH 147/220] desprout --- .../asyncrpcoperation_mergetoaddress.cpp | 21 +-- src/wallet/asyncrpcoperation_mergetoaddress.h | 4 - ...asyncrpcoperation_saplingconsolidation.cpp | 3 +- src/wallet/asyncrpcoperation_sendmany.cpp | 18 +-- src/wallet/rpcwallet.cpp | 125 ++++-------------- 5 files changed, 31 insertions(+), 140 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 0ecb1ec12..79eaee5a9 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -74,19 +74,17 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( boost::optional builder, CMutableTransaction contextualTx, std::vector utxoInputs, - std::vector sproutNoteInputs, std::vector saplingNoteInputs, MergeToAddressRecipient recipient, CAmount fee, UniValue contextInfo) : -tx_(contextualTx), utxoInputs_(utxoInputs), sproutNoteInputs_(sproutNoteInputs), -saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo) +tx_(contextualTx), utxoInputs_(utxoInputs), saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo) { if (fee < 0 || fee > MAX_MONEY) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range"); } - if (utxoInputs.empty() && sproutNoteInputs.empty() && saplingNoteInputs.empty()) { + if (utxoInputs.empty() && saplingNoteInputs.empty()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "No inputs"); } @@ -94,14 +92,6 @@ saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), context throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing"); } - if (sproutNoteInputs.size() > 0 && saplingNoteInputs.size() > 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"); - } - - if (sproutNoteInputs.size() > 0 && builder) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Sprout notes are not supported by the TransactionBuilder"); - } - isUsingBuilder_ = false; if (builder) { isUsingBuilder_ = true; @@ -215,7 +205,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() { assert(isToTaddr_ != isToZaddr_); - bool isPureTaddrOnlyTx = (sproutNoteInputs_.empty() && saplingNoteInputs_.empty() && isToTaddr_); + bool isPureTaddrOnlyTx = (saplingNoteInputs_.empty() && isToTaddr_); CAmount minersFee = fee_; size_t numInputs = utxoInputs_.size(); @@ -240,9 +230,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } CAmount z_inputs_total = 0; - for (const MergeToAddressInputSproutNote& t : sproutNoteInputs_) { - z_inputs_total += std::get<2>(t); - } for (const MergeToAddressInputSaplingNote& t : saplingNoteInputs_) { z_inputs_total += std::get<2>(t); @@ -293,7 +280,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() /** * SCENARIO #0 * - * Sprout not involved, so we just use the TransactionBuilder and we're done. + * Only sapling involved, so we just use the TransactionBuilder and we're done. * * This is based on code from AsyncRPCOperation_sendmany::main_impl() and should be refactored. */ diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index 32dbcf015..69150161e 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -57,7 +57,6 @@ public: boost::optional builder, CMutableTransaction contextualTx, std::vector utxoInputs, - std::vector sproutNoteInputs, std::vector saplingNoteInputs, MergeToAddressRecipient recipient, CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE, @@ -94,9 +93,6 @@ private: uint256 joinSplitPubKey_; unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; - // The key is the result string from calling JSOutPoint::ToString() - std::unordered_map jsopWitnessAnchorMap; - std::vector utxoInputs_; std::vector saplingNoteInputs_; diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 0a57b8948..477545348 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -87,7 +87,6 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { return status; } - std::vector sproutEntries; std::vector saplingEntries; std::set addresses; { @@ -95,7 +94,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // We set minDepth to 11 to avoid unconfirmed notes and in anticipation of specifying // an anchor at height N-10 for each SpendDescription // Consider, should notes be sorted? - pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, "", 11); + pwalletMain->GetFilteredNotes(saplingEntries, "", 11); if (fConsolidationMapUsed) { const vector& v = mapMultiArgs["-consolidatesaplingaddress"]; for(int i = 0; i < v.size(); i++) { diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 06b8960cf..9e82e41db 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -248,18 +248,12 @@ bool AsyncRPCOperation_sendmany::main_impl() { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address."); } - // At least one of z_sprout_inputs_ and z_sapling_inputs_ must be empty by design - assert(z_sprout_inputs_.empty() || z_sapling_inputs_.empty()); - CAmount t_inputs_total = 0; for (SendManyInputUTXO & t : t_inputs_) { t_inputs_total += std::get<2>(t); } CAmount z_inputs_total = 0; - for (SendManyInputJSOP & t : z_sprout_inputs_) { - z_inputs_total += std::get<2>(t); - } for (auto t : z_sapling_inputs_) { z_inputs_total += t.note.value(); } @@ -687,20 +681,10 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { bool AsyncRPCOperation_sendmany::find_unspent_notes() { - std::vector sproutEntries; std::vector saplingEntries; { LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, fromaddress_, mindepth_); - } - - // If using the TransactionBuilder, we only want Sapling notes. - // If not using it, we only want Sprout notes. - // TODO: Refactor `GetFilteredNotes()` so we only fetch what we need. - if (isUsingBuilder_) { - sproutEntries.clear(); - } else { - saplingEntries.clear(); + pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_); } for (auto entry : saplingEntries) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 340f62a9c..b65e6a839 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -70,7 +70,6 @@ using namespace libzcash; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; -const std::string ADDR_TYPE_SPROUT = "sprout"; const std::string ADDR_TYPE_SAPLING = "sapling"; extern UniValue TxJoinSplitToJSON(const CTransaction& tx); extern int32_t KOMODO_INSYNC; @@ -3787,9 +3786,8 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk) UniValue results(UniValue::VARR); if (zaddrs.size() > 0) { - std::vector sproutEntries; std::vector saplingEntries; - pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false); + pwalletMain->GetFilteredNotes(saplingEntries, zaddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false); std::set> nullifierSet = pwalletMain->GetNullifiersForAddresses(zaddrs); for (auto & entry : saplingEntries) { @@ -4047,10 +4045,9 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) { CAmount balance = 0; - std::vector sproutEntries; std::vector saplingEntries; LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, address, minDepth, true, ignoreUnspendable); + pwalletMain->GetFilteredNotes(saplingEntries, address, minDepth, true, ignoreUnspendable); for (auto & entry : saplingEntries) { balance += CAmount(entry.note.value()); } @@ -4102,16 +4099,14 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr."); } - // Visitor to support Sprout and Sapling addrs if (!boost::apply_visitor(PaymentAddressBelongsToWallet(pwalletMain), zaddr) && !boost::apply_visitor(IncomingViewingKeyBelongsToWallet(pwalletMain), zaddr)) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); } UniValue result(UniValue::VARR); - std::vector sproutEntries; std::vector saplingEntries; - pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, fromaddress, nMinDepth, false, false); + pwalletMain->GetFilteredNotes(saplingEntries, fromaddress, nMinDepth, false, false); std::set> nullifierSet; auto hasSpendingKey = boost::apply_visitor(HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr); @@ -4223,7 +4218,7 @@ UniValue z_getnotescount(const UniValue& params, bool fHelp,const CPubKey& mypk) "z_getnotescount\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) Only include notes in transactions confirmed at least this many times.\n" - "\nReturns the number of sprout and sapling notes available in the wallet.\n" + "\nReturns the number of sapling notes available in the wallet.\n" "\nResult:\n" "{\n" " \"sapling\" (numeric) the number of sapling notes in the wallet\n" @@ -4268,7 +4263,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my "\nResult:\n" "{\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" - " \"private\": xxxxx, (numeric) the total balance of private funds (in both Sprout and Sapling addresses)\n" + " \"private\": xxxxx, (numeric) the total balance of private funds\n" " \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n" "}\n" "\nExamples:\n" @@ -4650,14 +4645,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found."); } - // Remember whether this is a Sprout or Sapling address + // Remember whether this is a Sapling address fromSapling = boost::get(&res) != nullptr; } - // This logic will need to be updated if we add a new shielded pool - bool fromSprout = !(fromTaddr || fromSapling); - - if (fromSprout) - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot send from a Sprout zaddr, only Sapling zaddrs supported."); UniValue outputs = params[1].get_array(); @@ -4667,15 +4657,11 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // Keep track of addresses to spot duplicates set setAddress; - // Track whether we see any Sprout addresses - bool noSproutAddrs = !fromSprout; - // Recipients std::vector taddrRecipients; std::vector zaddrRecipients; CAmount nTotalOut = 0; - bool containsSproutOutput = false; bool containsSaplingOutput = false; for (const UniValue& o : outputs.getValues()) { @@ -4696,35 +4682,6 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) auto res = DecodePaymentAddress(address); if (IsValidPaymentAddress(res, branchId)) { isZaddr = true; - - bool toSapling = boost::get(&res) != nullptr; - bool toSprout = !toSapling; - noSproutAddrs = noSproutAddrs && toSapling; - - containsSproutOutput |= toSprout; - containsSaplingOutput |= toSapling; - - // Sending to both Sprout and Sapling is currently unsupported using z_sendmany - if (containsSproutOutput && containsSaplingOutput) { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - "Cannot send to both Sprout and Sapling addresses using z_sendmany"); - } - if ( GetTime() > KOMODO_SAPLING_DEADLINE ) - { - if ( fromSprout || toSprout ) - throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage has expired"); - } - if ( toSapling && ASSETCHAINS_SYMBOL[0] == 0 ) - throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage will expire soon"); - - // If we are sending from a shielded address, all recipient - // shielded addresses must be of the same type. - if ((fromSprout && toSapling) || (fromSapling && toSprout)) { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - "Cannot send between Sprout and Sapling addresses using z_sendmany"); - } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address ); } @@ -4915,9 +4872,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // Builder (used if Sapling addresses are involved) boost::optional builder; - if (noSproutAddrs) { - builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); - } + builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); // Contextual transaction we will build on // (used if no Sapling addresses are involved) @@ -5190,11 +5145,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp return NullUniValue; string enableArg = "zmergetoaddress"; - auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true); - std::string strDisabledMsg = ""; - if (!fEnableMergeToAddress) { - strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg); - } + //auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true); + //std::string strDisabledMsg = ""; + //if (!fEnableMergeToAddress) { + // strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg); + //} if (fHelp || params.size() < 2 || params.size() > 7) throw runtime_error( @@ -5256,7 +5211,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp THROW_IF_SYNCING(KOMODO_INSYNC); bool useAnyUTXO = false; - bool useAnySprout = false; bool useAnySapling = false; std::set taddrs = {}; std::set zaddrs = {}; @@ -5277,8 +5231,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp if (address == "ANY_TADDR") { useAnyUTXO = true; - } else if (address == "ANY_SPROUT") { - useAnySprout = true; } else if (address == "ANY_SAPLING") { useAnySapling = true; } else { @@ -5303,8 +5255,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp if (useAnyUTXO && taddrs.size() > 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific t-addrs when using \"ANY_TADDR\""); } - if ((useAnySprout || useAnySapling) && zaddrs.size() > 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SPROUT\" or \"ANY_SAPLING\""); + if ((useAnySapling) && zaddrs.size() > 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SAPLING\""); } const int nextBlockHeight = chainActive.Height() + 1; @@ -5313,7 +5265,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp // Validate the destination address auto destaddress = params[1].get_str(); - bool isToSproutZaddr = false; bool isToSaplingZaddr = false; CTxDestination taddr = DecodeDestination(destaddress); if (!IsValidDestination(taddr)) { @@ -5326,7 +5277,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); } } else { - isToSproutZaddr = true; + throw JSONRPCError(RPC_INVALID_PARAMETER, "Only Sapling zaddrs allowed!"); } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); @@ -5351,14 +5302,12 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp } } - int sproutNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT; int saplingNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT; if (params.size() > 4) { int nNoteLimit = params[4].get_int(); if (nNoteLimit < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative"); } - sproutNoteLimit = nNoteLimit; saplingNoteLimit = nNoteLimit; } @@ -5375,7 +5324,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp std::string memo; if (params.size() > 6) { memo = params[6].get_str(); - if (!(isToSproutZaddr || isToSaplingZaddr)) { + if (!isToSaplingZaddr) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr."); } else if (!IsHex(memo)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format."); @@ -5389,7 +5338,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp // Prepare to get UTXOs and notes std::vector utxoInputs; - std::vector sproutNoteInputs; std::vector saplingNoteInputs; CAmount mergedUTXOValue = 0; CAmount mergedNoteValue = 0; @@ -5403,9 +5351,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp unsigned int max_tx_size = saplingActive ? MAX_TX_SIZE_AFTER_SAPLING : MAX_TX_SIZE_BEFORE_SAPLING; size_t estimatedTxSize = 200; // tx overhead + wiggle room - if (isToSproutZaddr) { - estimatedTxSize += JOINSPLIT_SIZE; - } else if (isToSaplingZaddr) { + + if (isToSaplingZaddr) { estimatedTxSize += OUTPUTDESCRIPTION_SIZE; } @@ -5463,29 +5410,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp } } - if (useAnySprout || useAnySapling || zaddrs.size() > 0) { + if (useAnySapling || zaddrs.size() > 0) { // Get available notes - std::vector sproutEntries; - //std::vector saplingEntries; - //pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs); - std::vector saplingEntries,skipsapling; - pwalletMain->GetFilteredNotes(sproutEntries, useAnySprout == 0 ? saplingEntries : skipsapling, zaddrs); - // If Sapling is not active, do not allow sending from a sapling addresses. - if (!saplingActive && saplingEntries.size() > 0) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); - } - // Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress - if (sproutEntries.size() > 0 && saplingEntries.size() > 0) { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"); - } - // If sending between shielded addresses, they must be the same type - if ((saplingEntries.size() > 0 && isToSproutZaddr) || (sproutEntries.size() > 0 && isToSaplingZaddr)) { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - "Cannot send between Sprout and Sapling addresses using z_mergetoaddress"); - } + std::vector saplingEntries; + pwalletMain->GetFilteredNotes(saplingEntries, zaddrs); for (const SaplingNoteEntry& entry : saplingEntries) { noteCounter++; @@ -5514,7 +5442,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp } size_t numUtxos = utxoInputs.size(); - size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size(); + size_t numNotes = saplingNoteInputs.size(); //fprintf(stderr, "num utxos.%li\n", numUtxos); if (numUtxos < 2 && numNotes == 0) { @@ -5552,22 +5480,19 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( Params().GetConsensus(), nextBlockHeight); - bool isSproutShielded = sproutNoteInputs.size() > 0 || isToSproutZaddr; - if (contextualTx.nVersion == 1 && isSproutShielded) { - contextualTx.nVersion = 2; // Tx format should support vjoinsplit - } // Builder (used if Sapling addresses are involved) boost::optional builder; if (isToSaplingZaddr || saplingNoteInputs.size() > 0) { builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); - } else + } else { contextualTx.nExpiryHeight = 0; // set non z-tx to have no expiry height. + } // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); std::shared_ptr operation( - new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, sproutNoteInputs, saplingNoteInputs, recipient, nFee, contextInfo) ); + new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, saplingNoteInputs, recipient, nFee, contextInfo) ); q->addOperation(operation); AsyncRPCOperationId operationId = operation->getId(); From f13171efc69f907c631255b5438ebdcd48c04e95 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 05:14:21 -0400 Subject: [PATCH 148/220] desprout --- src/init.cpp | 6 +++--- src/init.h | 4 ++-- src/main.cpp | 9 --------- src/metrics.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 3 --- src/wallet/rpcwallet.cpp | 10 ++-------- src/wallet/wallet.cpp | 4 +--- 7 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 32cefbe91..7d9733372 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -101,7 +101,7 @@ extern int32_t KOMODO_SNAPSHOT_INTERVAL; extern void komodo_init(int32_t height); -ZCJoinSplit* pzcashParams = NULL; +//ZCJoinSplit* pzcashParams = NULL; #ifdef ENABLE_WALLET CWallet* pwalletMain = NULL; @@ -305,8 +305,8 @@ void Shutdown() delete pwalletMain; pwalletMain = NULL; #endif - delete pzcashParams; - pzcashParams = NULL; + //delete pzcashParams; + //pzcashParams = NULL; globalVerifyHandle.reset(); ECC_Stop(); LogPrintf("%s: done\n", __func__); diff --git a/src/init.h b/src/init.h index 108339865..c68d59419 100644 --- a/src/init.h +++ b/src/init.h @@ -23,7 +23,7 @@ #include -#include "zcash/JoinSplit.hpp" +//#include "zcash/JoinSplit.hpp" class CScheduler; class CWallet; @@ -34,7 +34,7 @@ class thread_group; } // namespace boost extern CWallet* pwalletMain; -extern ZCJoinSplit* pzcashParams; +//extern ZCJoinSplit* pzcashParams; void StartShutdown(); bool ShutdownRequested(); diff --git a/src/main.cpp b/src/main.cpp index f31847b04..c2e9c5bfb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1367,15 +1367,6 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState if (!CheckTransactionWithoutProofVerification(tiptime,tx, state)) { return false; - } else { - // Ensure that zk-SNARKs v|| y - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { - if (!joinsplit.Verify(*pzcashParams, verifier, tx.joinSplitPubKey)) { - return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"), - REJECT_INVALID, "bad-txns-joinsplit-verification-failed"); - } - } - return true; } } diff --git a/src/metrics.cpp b/src/metrics.cpp index ff0863a19..adbef02f2 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -288,7 +288,7 @@ int printMiningStatus(bool mining) } else if (IsInitialBlockDownload()) { std::cout << _("Mining is paused while downloading blocks.") << std::endl; } else { - std::cout << _("Mining is paused (a JoinSplit may be in progress).") << std::endl; + std::cout << _("Mining is paused, enhance your calm") << std::endl; } } lines++; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 9e82e41db..1b709b142 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -140,9 +140,6 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( } else { LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } - - // Enable payment disclosure if requested - paymentDisclosureMode = false; } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b65e6a839..66ab58f47 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5135,7 +5135,6 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp, const CPubKey& myp #define MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT 10 #define MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT 90 -#define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION) #define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION) #define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION) @@ -5154,7 +5153,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp if (fHelp || params.size() < 2 || params.size() > 7) throw runtime_error( "z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n" - + strDisabledMsg + "\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`" "\nto combine those into a single note." "\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they" @@ -5198,14 +5196,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" "}\n" "\nExamples:\n" - + HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf") - + HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + + HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' zs1aW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf") + + HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"zs1aW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") ); - if (!fEnableMergeToAddress) { - throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled."); - } - LOCK2(cs_main, pwalletMain->cs_wallet); THROW_IF_SYNCING(KOMODO_INSYNC); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a346a547f..725f04764 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4781,7 +4781,6 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) * These notes are decrypted and added to the output parameter vector, outEntries. */ void CWallet::GetFilteredNotes( - std::vector& sproutEntries, std::vector& saplingEntries, std::string address, int minDepth, @@ -4794,7 +4793,7 @@ void CWallet::GetFilteredNotes( filterAddresses.insert(DecodePaymentAddress(address)); } - GetFilteredNotes(sproutEntries, saplingEntries, filterAddresses, minDepth, INT_MAX, ignoreSpent, requireSpendingKey); + GetFilteredNotes(saplingEntries, filterAddresses, minDepth, INT_MAX, ignoreSpent, requireSpendingKey); } /** @@ -4803,7 +4802,6 @@ void CWallet::GetFilteredNotes( * These notes are decrypted and added to the output parameter vector, outEntries. */ void CWallet::GetFilteredNotes( - std::vector& sproutEntries, std::vector& saplingEntries, std::set& filterAddresses, int minDepth, From b5a0d3b8b7dab495cc67c02758fe4e7621586eba Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 14:11:30 -0400 Subject: [PATCH 149/220] desprout --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index c2e9c5bfb..2532dd2b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1368,6 +1368,7 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState if (!CheckTransactionWithoutProofVerification(tiptime,tx, state)) { return false; } + return true; } int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only From dd95b1471cefc19501631fc84875b5a919105e1f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 14:48:16 -0400 Subject: [PATCH 150/220] desprout --- src/coins.cpp | 33 ++-------------------- src/coins.h | 5 ---- src/main.cpp | 12 ++++---- src/rpc/blockchain.cpp | 7 +++-- src/txmempool.cpp | 4 ++- src/validationinterface.cpp | 4 ++- src/wallet/wallet.cpp | 55 ++----------------------------------- 7 files changed, 22 insertions(+), 98 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 602d153ec..03b046a70 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2012-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -65,7 +65,6 @@ bool CCoins::Spend(uint32_t nPos) Cleanup(); return true; } -bool CCoinsView::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return false; } bool CCoinsView::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return false; } bool CCoinsView::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return false; } bool CCoinsView::GetCoins(const uint256 &txid, CCoins &coins) const { return false; } @@ -85,7 +84,6 @@ bool CCoinsView::GetStats(CCoinsStats &stats) const { return false; } CCoinsViewBacked::CCoinsViewBacked(CCoinsView *viewIn) : base(viewIn) { } -bool CCoinsViewBacked::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { return base->GetSproutAnchorAt(rt, tree); } bool CCoinsViewBacked::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { return base->GetSaplingAnchorAt(rt, tree); } bool CCoinsViewBacked::GetNullifier(const uint256 &nullifier, ShieldedType type) const { return base->GetNullifier(nullifier, type); } bool CCoinsViewBacked::GetCoins(const uint256 &txid, CCoins &coins) const { return base->GetCoins(txid, coins); } @@ -139,30 +137,6 @@ CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const return ret; } - -bool CCoinsViewCache::GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const { - CAnchorsSproutMap::const_iterator it = cacheSproutAnchors.find(rt); - if (it != cacheSproutAnchors.end()) { - if (it->second.entered) { - tree = it->second.tree; - return true; - } else { - return false; - } - } - - if (!base->GetSproutAnchorAt(rt, tree)) { - return false; - } - - CAnchorsSproutMap::iterator ret = cacheSproutAnchors.insert(std::make_pair(rt, CAnchorsSproutCacheEntry())).first; - ret->second.entered = true; - ret->second.tree = tree; - cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); - - return true; -} - bool CCoinsViewCache::GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const { CAnchorsSaplingMap::const_iterator it = cacheSaplingAnchors.find(rt); if (it != cacheSaplingAnchors.end()) { @@ -271,7 +245,6 @@ void CCoinsViewCache::BringBestAnchorIntoCache( SproutMerkleTree &tree ) { - assert(GetSproutAnchorAt(currentRoot, tree)); } template<> @@ -550,9 +523,9 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, bool CCoinsViewCache::Flush() { bool fOk = base->BatchWrite(cacheCoins, hashBlock, hashSproutAnchor, hashSaplingAnchor, cacheSproutAnchors, cacheSaplingAnchors, cacheSproutNullifiers, cacheSaplingNullifiers); cacheCoins.clear(); - cacheSproutAnchors.clear(); + //cacheSproutAnchors.clear(); cacheSaplingAnchors.clear(); - cacheSproutNullifiers.clear(); + //cacheSproutNullifiers.clear(); cacheSaplingNullifiers.clear(); cachedCoinsUsage = 0; return fOk; diff --git a/src/coins.h b/src/coins.h index 1211e7e07..3e8f674fb 100644 --- a/src/coins.h +++ b/src/coins.h @@ -372,9 +372,6 @@ struct CCoinsStats class CCoinsView { public: - //! Retrieve the tree (Sprout) at a particular anchored root in the chain - virtual bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; - //! Retrieve the tree (Sapling) at a particular anchored root in the chain virtual bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; @@ -421,7 +418,6 @@ protected: public: CCoinsViewBacked(CCoinsView *viewIn); - bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; @@ -493,7 +489,6 @@ public: CNullifiersMap getNullifiers(); // Standard CCoinsView methods - bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; diff --git a/src/main.cpp b/src/main.cpp index 2532dd2b1..6ca7b68a2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3493,13 +3493,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // This should never fail: we should always be able to get the root // that is on the tip of our chain - assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree)); + //assert(view.GetSproutAnchorAt(old_sprout_tree_root, sprout_tree)); - { + //{ // Consistency check: the root of the tree we're given should // match what we asked for. - assert(sprout_tree.root() == old_sprout_tree_root); - } + //assert(sprout_tree.root() == old_sprout_tree_root); + //} SaplingMerkleTree sapling_tree; assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); @@ -3636,6 +3636,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight()); + /* BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) { // Insert the note commitments into our temporary tree. @@ -3643,6 +3644,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin sprout_tree.append(note_commitment); } } + */ BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) { sapling_tree.append(outputDescription.cm); @@ -3652,7 +3654,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - view.PushAnchor(sprout_tree); + //view.PushAnchor(sprout_tree); view.PushAnchor(sapling_tree); if (!fJustCheck) { pindex->hashFinalSproutRoot = sprout_tree.root(); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 76375b80c..faed5b957 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1668,9 +1668,10 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp, const CPubKey& my obj.push_back(Pair("chainwork", chainActive.LastTip()->chainPower.chainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); - SproutMerkleTree tree; - pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree); - obj.push_back(Pair("commitments", static_cast(tree.size()))); + //SproutMerkleTree tree; + //pcoinsTip->GetSproutAnchorAt(pcoinsTip->GetBestAnchor(SPROUT), tree); + //obj.push_back(Pair("commitments", static_cast(tree.size()))); + obj.push_back(Pair("commitments", 0)); CBlockIndex* tip = chainActive.LastTip(); UniValue valuePools(UniValue::VARR); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index ca0ed7f51..2f10856d4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -644,8 +644,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const i++; } - boost::unordered_map intermediates; + /* + boost::unordered_map intermediates; BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { assert(!pcoins->GetNullifier(nf, SPROUT)); @@ -666,6 +667,7 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const intermediates.insert(std::make_pair(tree.root(), tree)); } + */ for (const SpendDescription &spendDescription : tx.vShieldedSpend) { SaplingMerkleTree tree; diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 799a60ceb..44b5115d6 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . @@ -138,7 +139,8 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) while (pindex && pindex != pindexFork) { // Get the Sprout commitment tree as of the start of this block. SproutMerkleTree oldSproutTree; - assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, oldSproutTree)); + //TODO: how important is oldSproutTree ? + //assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, oldSproutTree)); // Get the Sapling commitment tree as of the start of this block. // We can get this from the `hashFinalSaplingRoot` of the last block diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 725f04764..b492ee8a2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2334,57 +2334,6 @@ void CWallet::WitnessNoteCommitment(std::vector commitments, std::vector>& witnesses, uint256 &final_anchor) { - witnesses.resize(commitments.size()); - CBlockIndex* pindex = chainActive.Genesis(); - SproutMerkleTree tree; - - while (pindex) { - CBlock block; - ReadBlockFromDisk(block, pindex,1); - - BOOST_FOREACH(const CTransaction& tx, block.vtx) - { - BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit) - { - BOOST_FOREACH(const uint256 ¬e_commitment, jsdesc.commitments) - { - tree.append(note_commitment); - - BOOST_FOREACH(boost::optional& wit, witnesses) { - if (wit) { - wit->append(note_commitment); - } - } - - size_t i = 0; - BOOST_FOREACH(uint256& commitment, commitments) { - if (note_commitment == commitment) { - witnesses.at(i) = tree.witness(); - } - i++; - } - } - } - } - - uint256 current_anchor = tree.root(); - - // Consistency check: we should be able to find the current tree - // in our CCoins view. - SproutMerkleTree dummy_tree; - assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree)); - - pindex = chainActive.Next(pindex); - } - - // TODO: #93; Select a root via some heuristic. - final_anchor = tree.root(); - - BOOST_FOREACH(boost::optional& wit, witnesses) { - if (wit) { - assert(final_anchor == wit->root()); - } - } } /** @@ -2697,11 +2646,11 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) } } - SproutMerkleTree sproutTree; + //SproutMerkleTree sproutTree; SaplingMerkleTree saplingTree; // This should never fail: we should always be able to get the tree // state on the path to the tip of our chain - assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree)); + //assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree)); if (pindex->pprev) { if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree)); From 0eec14fb01c6b5200398fe4262f8f42e55587438 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 20:28:02 -0400 Subject: [PATCH 151/220] desprout --- src/transaction_builder.cpp | 1 - src/transaction_builder.h | 1 + src/txdb.h | 2 +- src/zcash/IncrementalMerkleTree.cpp | 2 ++ src/zcash/IncrementalMerkleTree.hpp | 2 ++ src/zcash/JoinSplit.hpp | 2 ++ src/zcash/Proof.cpp | 2 ++ src/zcash/Proof.hpp | 2 ++ src/zcash/prf.cpp | 2 ++ src/zcash/util.cpp | 2 ++ src/zcash/zip32.cpp | 1 + 11 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 8b1acaca9..d821a266f 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -1,6 +1,5 @@ // Copyright (c) 2018 The Zcash developers // Copyright (c) 2019-2020 The Hush developers -// Released under the GPLv3 // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/transaction_builder.h b/src/transaction_builder.h index 49c09294d..39225433a 100644 --- a/src/transaction_builder.h +++ b/src/transaction_builder.h @@ -1,4 +1,5 @@ // Copyright (c) 2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/txdb.h b/src/txdb.h index e089d0190..81c0bb3ad 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -63,7 +63,7 @@ protected: public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); - bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; + //bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; bool GetNullifier(const uint256 &nf, ShieldedType type) const; bool GetCoins(const uint256 &txid, CCoins &coins) const; diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index b8b3cd183..4d3ff8c2b 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include #include diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 1ebb2b499..ab55e8ad4 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #ifndef ZC_INCREMENTALMERKLETREE_H_ #define ZC_INCREMENTALMERKLETREE_H_ diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index 27df05db0..e7aded3c1 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #ifndef ZC_JOINSPLIT_H_ #define ZC_JOINSPLIT_H_ diff --git a/src/zcash/Proof.cpp b/src/zcash/Proof.cpp index 7ab1298a8..1a0ebfe75 100644 --- a/src/zcash/Proof.cpp +++ b/src/zcash/Proof.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include "Proof.hpp" #include "crypto/common.h" diff --git a/src/zcash/Proof.hpp b/src/zcash/Proof.hpp index 7c9b7f7f5..0a3d0bb14 100644 --- a/src/zcash/Proof.hpp +++ b/src/zcash/Proof.hpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #ifndef ZC_PROOF_H_ #define ZC_PROOF_H_ diff --git a/src/zcash/prf.cpp b/src/zcash/prf.cpp index 2491de83e..9ab3d0f10 100644 --- a/src/zcash/prf.cpp +++ b/src/zcash/prf.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include "prf.h" #include "crypto/sha256.h" #include "hash.h" diff --git a/src/zcash/util.cpp b/src/zcash/util.cpp index 6f32bf79a..064e1cca9 100644 --- a/src/zcash/util.cpp +++ b/src/zcash/util.cpp @@ -1,3 +1,5 @@ +// Copyright (c) 2019-2020 The Hush developers + #include "zcash/util.h" #include #include diff --git a/src/zcash/zip32.cpp b/src/zcash/zip32.cpp index 15478843e..615c5896d 100644 --- a/src/zcash/zip32.cpp +++ b/src/zcash/zip32.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2018 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From f725a8362c138e3e75085c47788feefb1fe7db2e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 6 Jun 2020 23:17:49 -0400 Subject: [PATCH 152/220] desprout --- src/timedata.cpp | 1 + src/timedata.h | 1 + src/torcontrol.cpp | 1 + src/torcontrol.h | 1 + src/transaction_builder.cpp | 1 - 5 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/timedata.cpp b/src/timedata.cpp index 584e0db8c..64a3955ff 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/timedata.h b/src/timedata.h index 2296baf11..13cff12b3 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,4 +1,5 @@ // Copyright (c) 2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 99c76995b..c2eb490da 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2015-2017 The Bitcoin Core developers // Copyright (c) 2017 The Zcash developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/torcontrol.h b/src/torcontrol.h index 72dc82c5b..44611c7b6 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -1,4 +1,5 @@ // Copyright (c) 2015 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index d821a266f..08953ee02 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -1,6 +1,5 @@ // Copyright (c) 2018 The Zcash developers // Copyright (c) 2019-2020 The Hush developers - // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From 0c118eb129f06ec6a9ff5ca9750b75b3417a8a2d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 7 Jun 2020 00:04:15 -0400 Subject: [PATCH 153/220] delete --- src/Makefile.am | 2 -- src/komodo_bitcoind.h | 2 +- src/primitives/block.h | 2 +- src/primitives/nonce.cpp | 24 ------------------------ src/primitives/nonce.h | 29 ----------------------------- src/test/transaction_tests.cpp | 1 + 6 files changed, 3 insertions(+), 57 deletions(-) delete mode 100644 src/primitives/nonce.cpp delete mode 100644 src/primitives/nonce.h diff --git a/src/Makefile.am b/src/Makefile.am index ab04c24bc..a1cae78a2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -427,7 +427,6 @@ libbitcoin_common_a_SOURCES = \ metrics.cpp \ primitives/block.cpp \ primitives/transaction.cpp \ - primitives/nonce.cpp \ protocol.cpp \ pubkey.cpp \ scheduler.cpp \ @@ -652,7 +651,6 @@ libzcashconsensus_la_SOURCES = \ crypto/sha512.cpp \ hash.cpp \ primitives/transaction.cpp \ - primitives/nonce.cpp \ pubkey.cpp \ script/zcashconsensus.cpp \ script/interpreter.cpp \ diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 39cf5da63..e1748c191 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -20,7 +20,7 @@ #include #include #include "consensus/params.h" -#include "primitives/nonce.h" +//#include "primitives/nonce.h" #include "komodo_defs.h" #include "script/standard.h" #include "cc/CCinclude.h" diff --git a/src/primitives/block.h b/src/primitives/block.h index a2d0ba708..9a6ddf100 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -23,7 +23,7 @@ #define BITCOIN_PRIMITIVES_BLOCK_H #include "primitives/transaction.h" -#include "primitives/nonce.h" +//#include "primitives/nonce.h" #include "serialize.h" #include "uint256.h" #include "arith_uint256.h" diff --git a/src/primitives/nonce.cpp b/src/primitives/nonce.cpp deleted file mode 100644 index a1fbd667d..000000000 --- a/src/primitives/nonce.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2019 The Hush Developers -// Copyright (c) 2018 Michael Toutonghi -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "hash.h" -#include "nonce.h" -#include - diff --git a/src/primitives/nonce.h b/src/primitives/nonce.h deleted file mode 100644 index b17a9f01b..000000000 --- a/src/primitives/nonce.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2019 Hush Developers -// Copyright (c) 2018 Michael Toutonghi -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#ifndef BITCOIN_PRIMITIVES_NONCE_H -#define BITCOIN_PRIMITIVES_NONCE_H - -#include "serialize.h" -#include "uint256.h" -#include "arith_uint256.h" - - -#endif // BITCOIN_PRIMITIVES_NONCE_H diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index b6a6ebc26..eb948f92d 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers // Copyright (c) 2011-2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From b0ea67d5bea4e4692a9567a2f8dc7d41e1c89ec9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 7 Jun 2020 16:10:49 -0400 Subject: [PATCH 154/220] desprout --- src/Makefile.am | 11 +++++------ src/primitives/transaction.h | 1 + src/transaction_builder.cpp | 1 + src/wallet/rpchushwallet.cpp | 2 +- src/zcash/Note.cpp | 31 ------------------------------- 5 files changed, 8 insertions(+), 38 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index a1cae78a2..ec3f562f2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,5 @@ +# Copyright 2019-2020 The Hush developers + DIST_SUBDIRS = secp256k1 univalue cryptoconditions AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) @@ -186,7 +188,6 @@ BITCOIN_CORE_H = \ prevector.h \ primitives/block.h \ primitives/transaction.h \ - primitives/nonce.h \ protocol.h \ pubkey.h \ random.h \ @@ -486,7 +487,7 @@ libbitcoin_cli_a_SOURCES = \ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # -# bitcoind binary # +# komodod binary # komodod_SOURCES = bitcoind.cpp komodod_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) komodod_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -545,7 +546,7 @@ if TARGET_DARWIN komodod_LDFLAGS += -static-libgcc endif -# bitcoin-cli binary # +# komodo-cli binary # komodo_cli_SOURCES = bitcoin-cli.cpp komodo_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) komodo_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -593,7 +594,7 @@ wallet_utility_LDADD = \ $(LIBCRYPTOCONDITIONS) endif -# zcash-tx binary # +# komodo-tx binary # komodo_tx_SOURCES = komodo-tx.cpp komodo_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) komodo_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -603,7 +604,6 @@ if TARGET_WINDOWS komodo_tx_SOURCES += bitcoin-tx-res.rc endif -# FIXME: Is libzcash needed for hush-tx ? komodo_tx_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_COMMON) \ @@ -615,7 +615,6 @@ komodo_tx_LDADD = \ $(LIBCRYPTOCONDITIONS) komodo_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) -# # zcash protocol primitives # libzcash_a_SOURCES = \ diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 2ece7b255..7a46b9c00 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -44,6 +44,7 @@ #include "zcash/Zcash.h" #include "zcash/JoinSplit.hpp" #include "zcash/Proof.hpp" +#include "zcash/Note.hpp" extern uint32_t ASSETCHAINS_MAGIC; extern std::string ASSETCHAINS_SELFIMPORT; diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index 08953ee02..e1879e1d4 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -12,6 +12,7 @@ #include #include #include +#include "zcash/Note.hpp" SpendDescriptionInfo::SpendDescriptionInfo( libzcash::SaplingExpandedSpendingKey expsk, diff --git a/src/wallet/rpchushwallet.cpp b/src/wallet/rpchushwallet.cpp index 62b7a4fc9..64cd0e4a5 100644 --- a/src/wallet/rpchushwallet.cpp +++ b/src/wallet/rpchushwallet.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Copyright (c) 2019 Cryptoforge // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 9cd327d1b..e6d185a0e 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -13,37 +13,6 @@ using namespace libzcash; -/* -SproutNote::SproutNote() { - a_pk = random_uint256(); - rho = random_uint256(); - r = random_uint256(); -} - -uint256 SproutNote::cm() const { - unsigned char discriminant = 0xb0; - - CSHA256 hasher; - hasher.Write(&discriminant, 1); - hasher.Write(a_pk.begin(), 32); - - auto value_vec = convertIntToVectorLE(value_); - - hasher.Write(&value_vec[0], value_vec.size()); - hasher.Write(rho.begin(), 32); - hasher.Write(r.begin(), 32); - - uint256 result; - hasher.Finalize(result.begin()); - - return result; -} - -uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const { - return PRF_nf(a_sk, rho); -} -*/ - // Construct and populate Sapling note for a given payment address and value. SaplingNote::SaplingNote(const SaplingPaymentAddress& address, const uint64_t value) : BaseNote(value) { d = address.d; From 0ca0637323d6da126d127feea4ce50c0df2efadd Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 7 Jun 2020 17:31:27 -0400 Subject: [PATCH 155/220] Use our mirror of boost, bintray is returning 403 currently --- depends/packages/boost.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 48c60710d..3112ca7be 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,7 +1,7 @@ package=boost $(package)_version=1_72_0 -$(package)_download_path=https://dl.bintray.com/boostorg/release/1.72.0/source/ +$(package)_download_path=https://github.com/MyHush/boost/releases/download/v1.72.0/ $(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 $(package)_file_name=$(package)_$($(package)_version).tar.bz2 From 5a601d143196cf9dff7bc4a0beb28dbe890f8713 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 8 Jun 2020 11:13:17 -0400 Subject: [PATCH 156/220] desprout --- src/wallet/rpcwallet.cpp | 1 + src/wallet/wallet.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 66ab58f47..873d8eb87 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -38,6 +38,7 @@ #include "zcbenchmarks.h" #include "script/interpreter.h" #include "zcash/zip32.h" +#include "zcash/Note.hpp" #include "notaries_staked.h" #include "utiltime.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b492ee8a2..a7ca3d74d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -346,6 +346,14 @@ bool CWallet::LoadSaplingPaymentAddress( return CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr); } +bool CWallet::AddCScript(const CScript& redeemScript) +{ + if (!CCryptoKeyStore::AddCScript(redeemScript)) + return false; + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); +} bool CWallet::LoadCScript(const CScript& redeemScript) { From f4dd9fe3bbd6b57cd55d5b638322028e54dba3e9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 08:50:52 -0400 Subject: [PATCH 157/220] desprout --- src/paymentdisclosure.cpp | 9 +++++++++ src/paymentdisclosure.h | 19 +++++++++++++++++++ src/paymentdisclosuredb.cpp | 11 +++++++++++ src/paymentdisclosuredb.h | 21 +++++++++++++++++++++ src/primitives/nonce.cpp | 24 ++++++++++++++++++++++++ src/primitives/nonce.h | 29 +++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 src/paymentdisclosure.cpp create mode 100644 src/paymentdisclosure.h create mode 100644 src/paymentdisclosuredb.cpp create mode 100644 src/paymentdisclosuredb.h create mode 100644 src/primitives/nonce.cpp create mode 100644 src/primitives/nonce.h diff --git a/src/paymentdisclosure.cpp b/src/paymentdisclosure.cpp new file mode 100644 index 000000000..d442c40f6 --- /dev/null +++ b/src/paymentdisclosure.cpp @@ -0,0 +1,9 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "paymentdisclosure.h" + +#include "key_io.h" +#include "util.h" + diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h new file mode 100644 index 000000000..9855e1de0 --- /dev/null +++ b/src/paymentdisclosure.h @@ -0,0 +1,19 @@ +#ifndef ZCASH_PAYMENTDISCLOSURE_H +#define ZCASH_PAYMENTDISCLOSURE_H + +#include "uint256.h" +#include "clientversion.h" +#include "serialize.h" +#include "streams.h" +#include "version.h" + +// For JSOutPoint +#include "wallet/wallet.h" + +#include +#include +#include + + +// Ensure that the two different protocol messages, payment disclosure blobs and transactions, +#endif // ZCASH_PAYMENTDISCLOSURE_H diff --git a/src/paymentdisclosuredb.cpp b/src/paymentdisclosuredb.cpp new file mode 100644 index 000000000..559e5688b --- /dev/null +++ b/src/paymentdisclosuredb.cpp @@ -0,0 +1,11 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "paymentdisclosuredb.h" + +#include "util.h" +#include "dbwrapper.h" + +#include + diff --git a/src/paymentdisclosuredb.h b/src/paymentdisclosuredb.h new file mode 100644 index 000000000..f239c5118 --- /dev/null +++ b/src/paymentdisclosuredb.h @@ -0,0 +1,21 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_PAYMENTDISCLOSUREDB_H +#define ZCASH_PAYMENTDISCLOSUREDB_H + +#include "paymentdisclosure.h" + +#include +#include +#include +#include +#include + +#include + +#include + + +#endif // ZCASH_PAYMENTDISCLOSUREDB_H diff --git a/src/primitives/nonce.cpp b/src/primitives/nonce.cpp new file mode 100644 index 000000000..a1fbd667d --- /dev/null +++ b/src/primitives/nonce.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2019 The Hush Developers +// Copyright (c) 2018 Michael Toutonghi +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/****************************************************************************** + * Copyright © 2014-2019 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "hash.h" +#include "nonce.h" +#include + diff --git a/src/primitives/nonce.h b/src/primitives/nonce.h new file mode 100644 index 000000000..b17a9f01b --- /dev/null +++ b/src/primitives/nonce.h @@ -0,0 +1,29 @@ +// Copyright (c) 2019 Hush Developers +// Copyright (c) 2018 Michael Toutonghi +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +/****************************************************************************** + * Copyright © 2014-2019 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef BITCOIN_PRIMITIVES_NONCE_H +#define BITCOIN_PRIMITIVES_NONCE_H + +#include "serialize.h" +#include "uint256.h" +#include "arith_uint256.h" + + +#endif // BITCOIN_PRIMITIVES_NONCE_H From 89bfb4d4a61150790db9a014e9c0270048b7c814 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 08:51:59 -0400 Subject: [PATCH 158/220] desprout --- src/paymentdisclosure.cpp | 9 --------- src/paymentdisclosure.h | 19 ------------------- src/paymentdisclosuredb.cpp | 11 ----------- src/paymentdisclosuredb.h | 21 --------------------- src/primitives/nonce.cpp | 24 ------------------------ src/primitives/nonce.h | 29 ----------------------------- 6 files changed, 113 deletions(-) delete mode 100644 src/paymentdisclosure.cpp delete mode 100644 src/paymentdisclosure.h delete mode 100644 src/paymentdisclosuredb.cpp delete mode 100644 src/paymentdisclosuredb.h delete mode 100644 src/primitives/nonce.cpp delete mode 100644 src/primitives/nonce.h diff --git a/src/paymentdisclosure.cpp b/src/paymentdisclosure.cpp deleted file mode 100644 index d442c40f6..000000000 --- a/src/paymentdisclosure.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentdisclosure.h" - -#include "key_io.h" -#include "util.h" - diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h deleted file mode 100644 index 9855e1de0..000000000 --- a/src/paymentdisclosure.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ZCASH_PAYMENTDISCLOSURE_H -#define ZCASH_PAYMENTDISCLOSURE_H - -#include "uint256.h" -#include "clientversion.h" -#include "serialize.h" -#include "streams.h" -#include "version.h" - -// For JSOutPoint -#include "wallet/wallet.h" - -#include -#include -#include - - -// Ensure that the two different protocol messages, payment disclosure blobs and transactions, -#endif // ZCASH_PAYMENTDISCLOSURE_H diff --git a/src/paymentdisclosuredb.cpp b/src/paymentdisclosuredb.cpp deleted file mode 100644 index 559e5688b..000000000 --- a/src/paymentdisclosuredb.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentdisclosuredb.h" - -#include "util.h" -#include "dbwrapper.h" - -#include - diff --git a/src/paymentdisclosuredb.h b/src/paymentdisclosuredb.h deleted file mode 100644 index f239c5118..000000000 --- a/src/paymentdisclosuredb.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_PAYMENTDISCLOSUREDB_H -#define ZCASH_PAYMENTDISCLOSUREDB_H - -#include "paymentdisclosure.h" - -#include -#include -#include -#include -#include - -#include - -#include - - -#endif // ZCASH_PAYMENTDISCLOSUREDB_H diff --git a/src/primitives/nonce.cpp b/src/primitives/nonce.cpp deleted file mode 100644 index a1fbd667d..000000000 --- a/src/primitives/nonce.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2019 The Hush Developers -// Copyright (c) 2018 Michael Toutonghi -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "hash.h" -#include "nonce.h" -#include - diff --git a/src/primitives/nonce.h b/src/primitives/nonce.h deleted file mode 100644 index b17a9f01b..000000000 --- a/src/primitives/nonce.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2019 Hush Developers -// Copyright (c) 2018 Michael Toutonghi -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -/****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#ifndef BITCOIN_PRIMITIVES_NONCE_H -#define BITCOIN_PRIMITIVES_NONCE_H - -#include "serialize.h" -#include "uint256.h" -#include "arith_uint256.h" - - -#endif // BITCOIN_PRIMITIVES_NONCE_H From 96c50683e9baca74d0cd23feba43ccc7c1e6baa4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 09:01:06 -0400 Subject: [PATCH 159/220] Fix the fucking linker bug --- src/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index ec3f562f2..b44dd13c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -340,7 +340,7 @@ libbitcoin_proton_a_SOURCES = \ amqp/amqppublishnotifier.cpp endif -# wallet: zcashd, but only linked when wallet enabled +# wallet: komodod, but only linked when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ @@ -352,6 +352,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/asyncrpcoperation_shieldcoinbase.cpp \ wallet/crypter.cpp \ wallet/db.cpp \ + zcash/Note.cpp \ transaction_builder.cpp \ wallet/rpcdump.cpp \ cc/CCtokens.cpp \ From f7a9db724a6180594921c03d5764f0dd385753f9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 09:24:58 -0400 Subject: [PATCH 160/220] More error detection --- contrib/block_time.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contrib/block_time.pl b/contrib/block_time.pl index dff43ea4e..b4b039a60 100755 --- a/contrib/block_time.pl +++ b/contrib/block_time.pl @@ -9,6 +9,11 @@ my $block = shift || die "Usage: $0 123"; my $hush = "./src/hush-cli"; my $blockcount = qx{$hush getblockcount}; +unless ($blockcount = int($blockcount)) { + print "Invalid response from hush-cli\n"; + exit 1; +} + if ($block <= $blockcount) { die "That block has already happened!"; } else { From cc3ae8164493320a24b165f101444109a28d5ff3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 09:29:24 -0400 Subject: [PATCH 161/220] 2020 --- contrib/block_time.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/block_time.pl b/contrib/block_time.pl index b4b039a60..17da3c461 100755 --- a/contrib/block_time.pl +++ b/contrib/block_time.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# Copyright 2019 The Hush developers +# Copyright 2019-2020 The Hush developers # Released under the GPLv3 use warnings; use strict; From 6a4c86e3cd9d477122a0a209623890118123fa4f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 10:14:41 -0400 Subject: [PATCH 162/220] define next hardfork height --- src/komodo_defs.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 6d867b229..97a21969f 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -54,13 +54,19 @@ // Hush Block 166250 will happen at roughly: // Wed Jan 29 08:14:12 2020 Eastern # 1580303652 // Wed Jan 29 13:14:12 2020 GMT # 1580303652 -const uint32_t nHushHardforkHeight = 166250; +const uint32_t nHushHardforkHeight = 166250; +// $ ./contrib/block_time.pl 255555 +// Hush Block 255555 will happen at roughly: +// Sat Jul 11 21:41:12 2020 Eastern # 1594518072 +// Sun Jul 12 01:41:12 2020 GMT # 1594518072 +const uint32_t nHushHardforkHeight2 = 255555; // No coins/code are currently using timestamp activated fork -const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT +const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT +const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT -static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, 1751328000}; -static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, 5*nHushHardforkHeight}; +static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5}; +static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, 5*nHushHardforkHeight2}; // Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = From 2fbcca4167cf41fa7f6f553046a3f113e2b60d14 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 10:14:51 -0400 Subject: [PATCH 163/220] add rescan rpc --- src/rpc/server.h | 1 + src/wallet/rpcdump.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/wallet/rpcwallet.cpp | 3 +++ 3 files changed, 41 insertions(+) diff --git a/src/rpc/server.h b/src/rpc/server.h index 1cd4e993d..6568977d7 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -489,6 +489,7 @@ extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp, const C extern UniValue z_getoperationresult(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_listoperationids(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue opreturn_burn(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp +extern UniValue rescan(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcwallet.cpp extern UniValue z_validateaddress(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcmisc.cpp extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp extern UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp, const CPubKey& mypk); // in rpcdisclosure.cpp diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 1499a58b9..72af5d930 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -149,6 +149,43 @@ UniValue convertpassphrase(const UniValue& params, bool fHelp, const CPubKey& my return ret; } +UniValue rescan(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + //LOCK2(cs_main, pwalletMain->cs_wallet); + + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() > 1) + throw runtime_error( + "rescan \"height\"\n" + "\nRescan all transactions from genesis or given block height.\n" + "\nArguments:\n" + "1. \"height\" (integer, optional) The block height to rescan from\n" + "\nExamples:\n" + "\nRescan from block height 555\n" + + HelpExampleCli("rescan", "\"555\"") + + "\nRescan from genesis block\n" + + HelpExampleCli("rescan","") + ); + + // Height to rescan from + int nRescanHeight = 0; + if (params.size() > 0) + nRescanHeight = params[0].get_int(); + if (nRescanHeight < 0 || nRescanHeight > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + } + + LogPrintf("Rescanning from height=%d\n", nRescanHeight); + //pwalletMain->ScanForWalletTransactions(chainActive[nRescanHeight],true); + bool update = false; + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(),update); + //TODO: can we return something more useful? + return NullUniValue; +} + + UniValue importprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 873d8eb87..867de51a7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -8228,6 +8228,8 @@ extern UniValue z_exportviewingkey(const UniValue& params, bool fHelp, const CPu extern UniValue z_importviewingkey(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue z_exportwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue z_importwallet(const UniValue& params, bool fHelp, const CPubKey& mypk); +extern UniValue rescan(const UniValue& params, bool fHelp, const CPubKey& mypk); + static const CRPCCommand commands[] = { // category name actor (function) okSafeMode @@ -8266,6 +8268,7 @@ static const CRPCCommand commands[] = { "wallet", "listunspent", &listunspent, false }, { "wallet", "lockunspent", &lockunspent, true }, { "wallet", "move", &movecmd, false }, + { "wallet", "rescan", &rescan, false }, { "wallet", "sendfrom", &sendfrom, false }, { "wallet", "sendmany", &sendmany, false }, { "wallet", "sendtoaddress", &sendtoaddress, false }, From 3a28e7bab8e10edcf87573844fbef891fae04aac Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 11:09:00 -0400 Subject: [PATCH 164/220] bump version to 3.4.0 --- configure.ac | 4 ++-- src/clientversion.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index cf712cc67..e3be0c9dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) -define(_CLIENT_VERSION_MINOR, 3) -define(_CLIENT_VERSION_REVISION, 2) +define(_CLIENT_VERSION_MINOR, 4) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/src/clientversion.h b/src/clientversion.h index 71fcee16f..c62e6d3e0 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -33,8 +33,8 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it // Must be kept in sync with configure.ac ! #define CLIENT_VERSION_MAJOR 3 -#define CLIENT_VERSION_MINOR 3 -#define CLIENT_VERSION_REVISION 2 +#define CLIENT_VERSION_MINOR 4 +#define CLIENT_VERSION_REVISION 0 #define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build From 717533f7115001bb759742170ef65f93fdc9798f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 11:09:41 -0400 Subject: [PATCH 165/220] Update unix man pages --- doc/man/hush-cli.1 | 8 ++++---- doc/man/hush-tx.1 | 8 ++++---- doc/man/hushd.1 | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/doc/man/hush-cli.1 b/doc/man/hush-cli.1 index 0c9080b59..5d87d8205 100644 --- a/doc/man/hush-cli.1 +++ b/doc/man/hush-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSH-CLI "1" "March 2020" "hush-cli v3.3.2" "User Commands" +.TH HUSH-CLI "1" "June 2020" "hush-cli v3.4.0" "User Commands" .SH NAME -hush-cli \- manual page for hush-cli v3.3.2 +hush-cli \- manual page for hush-cli v3.4.0 .SH DESCRIPTION -Komodo RPC client version v3.3.2\-699b59037 +Komodo RPC client version v3.4.0\-2fbcca416\-dirty .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . @@ -71,7 +71,7 @@ Timeout in seconds during HTTP requests, or 0 for no timeout. (default: Read extra arguments from standard input, one per line until EOF/Ctrl\-D (recommended for sensitive information such as passphrases) .SH COPYRIGHT -Hush Daemon version v3.3.2-699b59037 +Hush Daemon version v3.4.0-2fbcca416-dirty In order to ensure you are adequately protecting your privacy when using Hush, please see . diff --git a/doc/man/hush-tx.1 b/doc/man/hush-tx.1 index 9004dcade..a6d3be7ef 100644 --- a/doc/man/hush-tx.1 +++ b/doc/man/hush-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSH-TX "1" "March 2020" "hush-tx v3.3.2" "User Commands" +.TH HUSH-TX "1" "June 2020" "hush-tx v3.4.0" "User Commands" .SH NAME -hush-tx \- manual page for hush-tx v3.3.2 +hush-tx \- manual page for hush-tx v3.4.0 .SH DESCRIPTION -Hush komodo\-tx utility version v3.3.2\-699b59037 +Hush komodo\-tx utility version v3.4.0\-2fbcca416\-dirty .SS "Usage:" .TP komodo\-tx [options] [commands] @@ -84,7 +84,7 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT -Hush Daemon version v3.3.2-699b59037 +Hush Daemon version v3.4.0-2fbcca416-dirty In order to ensure you are adequately protecting your privacy when using Hush, please see . diff --git a/doc/man/hushd.1 b/doc/man/hushd.1 index 0cde080df..6e57386b7 100644 --- a/doc/man/hushd.1 +++ b/doc/man/hushd.1 @@ -1,10 +1,10 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.10. -.TH HUSHD "1" "March 2020" "hushd v3.3.2" "User Commands" +.TH HUSHD "1" "June 2020" "hushd v3.4.0" "User Commands" .SH NAME -hushd \- manual page for hushd v3.3.2 +hushd \- manual page for hushd v3.4.0 .SH DESCRIPTION Found binary: ./komodod -Hush Daemon version v3.3.2\-699b59037 +Hush Daemon version v3.4.0\-2fbcca416\-dirty .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . @@ -87,6 +87,11 @@ leave that many cores free, default: 0) .IP Specify pid file (default: komodod.pid) .HP +\fB\-txexpirynotify=\fR +.IP +Execute command when transaction expires (%s in cmd is replaced by +transaction id) +.HP \fB\-prune=\fR .IP Reduce storage requirements by pruning (deleting) old blocks. This mode @@ -295,6 +300,11 @@ Keep the last transactions (default: 200) .IP Keep transactions for at least blocks (default: 10000) .HP +\fB\-opretmintxfee=\fR +.IP +Minimum fee (in KMD/kB) to allow for OP_RETURN transactions (default: +400000) +.HP \fB\-paytxfee=\fR .IP Fee (in KMD/kB) to add to transactions you send (default: 0.00) @@ -629,7 +639,7 @@ Starting supply, default is 0 .IP Enforce transaction\-rate limit, default 0 .SH COPYRIGHT -Hush Daemon version v3.3.2-699b59037 +Hush Daemon version v3.4.0-2fbcca416-dirty In order to ensure you are adequately protecting your privacy when using Hush, please see . From a053d212b8e22d1d8ffe08a2e0955f1854055702 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 21:34:20 -0400 Subject: [PATCH 166/220] Randomize sietch memos and increase min zouts to 3 --- src/wallet/rpcwallet.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 867de51a7..221bef44e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4590,6 +4590,15 @@ UniValue z_getoperationstatus_IMPL(const UniValue& params, bool fRemoveFinishedO #define CTXIN_SPEND_DUST_SIZE 148 #define CTXOUT_REGULAR_SIZE 34 +void random_hex(char str[], int len) +{ + char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + for(int i=0;iMAX_ZOUTS)) { - fprintf(stderr,"%s: Sietch min zouts must be >=2 and <= 25, setting to default value of %d\n", __FUNCTION__, DEFAULT_MIN_ZOUTS ); + if((MIN_ZOUTSMAX_ZOUTS)) { + fprintf(stderr,"%s: Sietch min zouts must be >=%d and <= %d, setting to default value of %d\n", __FUNCTION__, ABSOLUTE_MIN_ZOUTS, MAX_ZOUTS, DEFAULT_MIN_ZOUTS ); MIN_ZOUTS=DEFAULT_MIN_ZOUTS; } @@ -4739,8 +4748,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically int nAmount = 0; int decider = 1 + GetRandInt(100); // random int between 1 and 100 - string memo = "f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - + char *str; + random_hex(str,512); + string memo = string(str); string zdust1, zdust2; // Which zaddr we send to is non-deterministically chosen from two zpools... From a9d04b1e3f7d62c78e4c80f4d9f0e92394947bf9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 22:38:38 -0400 Subject: [PATCH 167/220] Include z2z fork height in our future seasons --- src/komodo_defs.h | 13 +++++++------ src/main.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 97a21969f..17d276c4e 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -42,12 +42,12 @@ // KMD Notary Seasons // 1: May 1st 2018 1530921600 // 2: July 15th 2019 1563148800 -> estimated height 1444000 -// 3: 3rd season ending isnt known, so use very far times in future. +// 3: 3rd season // 1751328000 = dummy timestamp, 1 July 2025! // 7113400 = 5x current KMD blockheight. -// to add 4th season, change NUM_KMD_SEASONS to 4, and add timestamp and height of activation to these arrays. +// to add seasons, change NUM_KMD_SEASONS, and add timestamp and height of activation to these arrays. -#define NUM_KMD_SEASONS 5 +#define NUM_KMD_SEASONS 6 #define NUM_KMD_NOTARIES 64 // $ ./contrib/block_time.pl 166250 @@ -64,9 +64,10 @@ const uint32_t nHushHardforkHeight2 = 255555; // No coins/code are currently using timestamp activated fork const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT +extern const uint32_t z2zForkHeight; -static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5}; -static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, 5*nHushHardforkHeight2}; +static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5, nHushHardforkTimestamp2*6}; +static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)z2zForkHeight, 5*nHushHardforkHeight2}; // Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = diff --git a/src/main.cpp b/src/main.cpp index 291706141..d5afa5baf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; -unsigned int z2zForkHeight = GetArg("-z2zforkheight",340000); +const uint32_t z2zForkHeight = GetArg("-z2zforkheight",340000); unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1735,9 +1735,9 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree,bool* pfMissingInputs, bool fRejectAbsurdFee, int dosLevel) { AssertLockHeld(cs_main); - uint32_t z2zTransitionWindow = 10; - uint32_t z2zTransitionStart = z2zForkHeight - z2zTransitionWindow; - uint32_t nHeight = chainActive.Height(); + const uint32_t z2zTransitionWindow = 10; + const uint32_t z2zTransitionStart = z2zForkHeight - z2zTransitionWindow; + const uint32_t nHeight = chainActive.Height(); // This only applies to HUSH3, other chains can start off z2z via ac_private=1 if(ishush3) { From 500dcabf53536e051751015bc301fde6f6507d3e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 22:43:08 -0400 Subject: [PATCH 168/220] Fix a compiler warning in cc and add some copyrights --- src/cryptoconditions/src/anon.c | 1 + src/cryptoconditions/src/cryptoconditions.c | 1 + src/cryptoconditions/src/ed25519.c | 1 + src/cryptoconditions/src/eval.c | 1 + src/cryptoconditions/src/internal.h | 1 + src/cryptoconditions/src/json_rpc.c | 1 + src/cryptoconditions/src/prefix.c | 1 + src/cryptoconditions/src/preimage.c | 1 + src/cryptoconditions/src/secp256k1.c | 1 + src/cryptoconditions/src/threshold.c | 1 + src/cryptoconditions/src/utils.c | 5 ++--- 11 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/cryptoconditions/src/anon.c b/src/cryptoconditions/src/anon.c index 6a4de4b0b..a1bd6b4a3 100644 --- a/src/cryptoconditions/src/anon.c +++ b/src/cryptoconditions/src/anon.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/cryptoconditions.c b/src/cryptoconditions/src/cryptoconditions.c index 303b9aa41..6642b0345 100644 --- a/src/cryptoconditions/src/cryptoconditions.c +++ b/src/cryptoconditions/src/cryptoconditions.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/ed25519.c b/src/cryptoconditions/src/ed25519.c index e4d090d1e..33b332071 100644 --- a/src/cryptoconditions/src/ed25519.c +++ b/src/cryptoconditions/src/ed25519.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/eval.c b/src/cryptoconditions/src/eval.c index a18d51202..a017d181d 100644 --- a/src/cryptoconditions/src/eval.c +++ b/src/cryptoconditions/src/eval.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/internal.h b/src/cryptoconditions/src/internal.h index 7cfcaa225..3d24214ce 100644 --- a/src/cryptoconditions/src/internal.h +++ b/src/cryptoconditions/src/internal.h @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/json_rpc.c b/src/cryptoconditions/src/json_rpc.c index 150bcb12b..c4fde8080 100644 --- a/src/cryptoconditions/src/json_rpc.c +++ b/src/cryptoconditions/src/json_rpc.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/prefix.c b/src/cryptoconditions/src/prefix.c index 67dc6f644..ea339df35 100644 --- a/src/cryptoconditions/src/prefix.c +++ b/src/cryptoconditions/src/prefix.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/preimage.c b/src/cryptoconditions/src/preimage.c index a45e621d4..2fee86b88 100644 --- a/src/cryptoconditions/src/preimage.c +++ b/src/cryptoconditions/src/preimage.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/secp256k1.c b/src/cryptoconditions/src/secp256k1.c index 44ff1f0e2..d5319d32b 100644 --- a/src/cryptoconditions/src/secp256k1.c +++ b/src/cryptoconditions/src/secp256k1.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/threshold.c b/src/cryptoconditions/src/threshold.c index e94666c3d..e8e12435e 100644 --- a/src/cryptoconditions/src/threshold.c +++ b/src/cryptoconditions/src/threshold.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * diff --git a/src/cryptoconditions/src/utils.c b/src/cryptoconditions/src/utils.c index ebb2bd143..ac2256f18 100644 --- a/src/cryptoconditions/src/utils.c +++ b/src/cryptoconditions/src/utils.c @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -216,7 +217,7 @@ void hashFingerprintContents(asn_TYPE_descriptor_t *asnType, void *fp, uint8_t * ASN_STRUCT_FREE(*asnType, fp); if (rc.encoded < 1) { fprintf(stderr, "Encoding fingerprint failed\n"); - return 0; + return; } sha256(buf, rc.encoded, out); } @@ -299,5 +300,3 @@ int jsonGetHexOptional(const cJSON *params, char *key, char *err, unsigned char } return checkDecodeHex(item, key, err, data, size); } - - From 53172831d8dc5a39aeccdb862b4a1d77ed413601 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 13 Jun 2020 23:05:51 -0400 Subject: [PATCH 169/220] Delete sprout tests --- qa/pull-tester/rpc-tests.sh | 2 - qa/rpc-tests/zcjoinsplit.py | 59 -------- qa/rpc-tests/zcjoinsplitdoublespend.py | 182 ------------------------- 3 files changed, 243 deletions(-) delete mode 100755 qa/rpc-tests/zcjoinsplit.py delete mode 100755 qa/rpc-tests/zcjoinsplitdoublespend.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 94429cb7f..8c4ad0277 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -64,8 +64,6 @@ testScripts=( 'decodescript.py' 'blockchain.py' 'disablewallet.py' - 'zcjoinsplit.py' - 'zcjoinsplitdoublespend.py' 'ivk_import_export.py' 'zkey_import_export.py' 'getblocktemplate.py' diff --git a/qa/rpc-tests/zcjoinsplit.py b/qa/rpc-tests/zcjoinsplit.py deleted file mode 100755 index b3ca745f8..000000000 --- a/qa/rpc-tests/zcjoinsplit.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python2 - -# -# Test joinsplit semantics -# - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, start_node, \ - gather_inputs - - -class JoinSplitTest(BitcoinTestFramework): - def setup_network(self): - self.nodes = [] - self.is_network_split = False - self.nodes.append(start_node(0, self.options.tmpdir)) - - def run_test(self): - zckeypair = self.nodes[0].zcrawkeygen() - zcsecretkey = zckeypair["zcsecretkey"] - zcaddress = zckeypair["zcaddress"] - - (total_in, inputs) = gather_inputs(self.nodes[0], 40) - protect_tx = self.nodes[0].createrawtransaction(inputs, {}) - joinsplit_result = self.nodes[0].zcrawjoinsplit(protect_tx, {}, {zcaddress:39.99}, 39.99, 0) - - receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) - assert_equal(receive_result["exists"], False) - - protect_tx = self.nodes[0].signrawtransaction(joinsplit_result["rawtxn"]) - self.nodes[0].sendrawtransaction(protect_tx["hex"]) - self.nodes[0].generate(1) - self.sync_all() - - receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) - assert_equal(receive_result["exists"], True) - - # The pure joinsplit we create should be mined in the next block - # despite other transactions being in the mempool. - addrtest = self.nodes[0].getnewaddress() - for xx in range(0,10): - self.nodes[0].generate(1) - self.sync_all() - for x in range(0,50): - self.nodes[0].sendtoaddress(addrtest, 0.01); - - joinsplit_tx = self.nodes[0].createrawtransaction([], {}) - joinsplit_result = self.nodes[0].zcrawjoinsplit(joinsplit_tx, {receive_result["note"] : zcsecretkey}, {zcaddress: 39.98}, 0, 0.01) - - self.nodes[0].sendrawtransaction(joinsplit_result["rawtxn"]) - self.nodes[0].generate(1) - self.sync_all() - - print "Done!" - receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) - assert_equal(receive_result["exists"], True) - -if __name__ == '__main__': - JoinSplitTest().main() diff --git a/qa/rpc-tests/zcjoinsplitdoublespend.py b/qa/rpc-tests/zcjoinsplitdoublespend.py deleted file mode 100755 index b56e7475a..000000000 --- a/qa/rpc-tests/zcjoinsplitdoublespend.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python2 - -# -# Tests a joinsplit double-spend and a subsequent reorg. -# - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException -from test_framework.util import assert_equal, connect_nodes, \ - gather_inputs, sync_blocks - -import time - -class JoinSplitTest(BitcoinTestFramework): - def setup_network(self): - # Start with split network: - return super(JoinSplitTest, self).setup_network(True) - - def txid_in_mempool(self, node, txid): - exception_triggered = False - - try: - node.getrawtransaction(txid) - except JSONRPCException: - exception_triggered = True - - return not exception_triggered - - def cannot_joinsplit(self, node, txn): - exception_triggered = False - - try: - node.sendrawtransaction(txn) - except JSONRPCException: - exception_triggered = True - - return exception_triggered - - def expect_cannot_joinsplit(self, node, txn): - assert_equal(self.cannot_joinsplit(node, txn), True) - - def run_test(self): - # All nodes should start with 250 HUSH: - starting_balance = 250 - for i in range(4): - assert_equal(self.nodes[i].getbalance(), starting_balance) - self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress! - - # Generate zcaddress keypairs - zckeypair = self.nodes[0].zcrawkeygen() - zcsecretkey = zckeypair["zcsecretkey"] - zcaddress = zckeypair["zcaddress"] - - pool = [0, 1, 2, 3] - for i in range(4): - (total_in, inputs) = gather_inputs(self.nodes[i], 40) - pool[i] = self.nodes[i].createrawtransaction(inputs, {}) - pool[i] = self.nodes[i].zcrawjoinsplit(pool[i], {}, {zcaddress:39.99}, 39.99, 0) - signed = self.nodes[i].signrawtransaction(pool[i]["rawtxn"]) - - # send the tx to both halves of the network - self.nodes[0].sendrawtransaction(signed["hex"]) - self.nodes[0].generate(1) - self.nodes[2].sendrawtransaction(signed["hex"]) - self.nodes[2].generate(1) - pool[i] = pool[i]["encryptednote1"] - - sync_blocks(self.nodes[0:2]) - sync_blocks(self.nodes[2:4]) - - # Confirm that the protects have taken place - for i in range(4): - enc_note = pool[i] - receive_result = self.nodes[0].zcrawreceive(zcsecretkey, enc_note) - assert_equal(receive_result["exists"], True) - pool[i] = receive_result["note"] - - # Extra confirmations - receive_result = self.nodes[1].zcrawreceive(zcsecretkey, enc_note) - assert_equal(receive_result["exists"], True) - - receive_result = self.nodes[2].zcrawreceive(zcsecretkey, enc_note) - assert_equal(receive_result["exists"], True) - - receive_result = self.nodes[3].zcrawreceive(zcsecretkey, enc_note) - assert_equal(receive_result["exists"], True) - - blank_tx = self.nodes[0].createrawtransaction([], {}) - # Create joinsplit {A, B}->{*} - joinsplit_AB = self.nodes[0].zcrawjoinsplit(blank_tx, - {pool[0] : zcsecretkey, pool[1] : zcsecretkey}, - {zcaddress:(39.99*2)-0.01}, - 0, 0.01) - - # Create joinsplit {B, C}->{*} - joinsplit_BC = self.nodes[0].zcrawjoinsplit(blank_tx, - {pool[1] : zcsecretkey, pool[2] : zcsecretkey}, - {zcaddress:(39.99*2)-0.01}, - 0, 0.01) - - # Create joinsplit {C, D}->{*} - joinsplit_CD = self.nodes[0].zcrawjoinsplit(blank_tx, - {pool[2] : zcsecretkey, pool[3] : zcsecretkey}, - {zcaddress:(39.99*2)-0.01}, - 0, 0.01) - - # Create joinsplit {A, D}->{*} - joinsplit_AD = self.nodes[0].zcrawjoinsplit(blank_tx, - {pool[0] : zcsecretkey, pool[3] : zcsecretkey}, - {zcaddress:(39.99*2)-0.01}, - 0, 0.01) - - # (a) Node 0 will spend joinsplit AB, then attempt to - # double-spend it with BC. It should fail before and - # after Node 0 mines blocks. - # - # (b) Then, Node 2 will spend BC, and mine 5 blocks. - # Node 1 connects, and AB will be reorg'd from the chain. - # Any attempts to spend AB or CD should fail for - # both nodes. - # - # (c) Then, Node 0 will spend AD, which should work - # because the previous spend for A (AB) is considered - # invalid due to the reorg. - - # (a) - - AB_txid = self.nodes[0].sendrawtransaction(joinsplit_AB["rawtxn"]) - - self.expect_cannot_joinsplit(self.nodes[0], joinsplit_BC["rawtxn"]) - - # Wait until node[1] receives AB before we attempt to double-spend - # with BC. - print "Waiting for AB_txid...\n" - while True: - if self.txid_in_mempool(self.nodes[1], AB_txid): - break - time.sleep(0.2) - print "Done!\n" - - self.expect_cannot_joinsplit(self.nodes[1], joinsplit_BC["rawtxn"]) - - # Generate a block - self.nodes[0].generate(1) - sync_blocks(self.nodes[0:2]) - - self.expect_cannot_joinsplit(self.nodes[0], joinsplit_BC["rawtxn"]) - self.expect_cannot_joinsplit(self.nodes[1], joinsplit_BC["rawtxn"]) - - # (b) - self.nodes[2].sendrawtransaction(joinsplit_BC["rawtxn"]) - self.nodes[2].generate(5) - - # Connect the two nodes - - connect_nodes(self.nodes[1], 2) - sync_blocks(self.nodes) - - # AB and CD should all be impossible to spend for each node. - self.expect_cannot_joinsplit(self.nodes[0], joinsplit_AB["rawtxn"]) - self.expect_cannot_joinsplit(self.nodes[0], joinsplit_CD["rawtxn"]) - - self.expect_cannot_joinsplit(self.nodes[1], joinsplit_AB["rawtxn"]) - self.expect_cannot_joinsplit(self.nodes[1], joinsplit_CD["rawtxn"]) - - self.expect_cannot_joinsplit(self.nodes[2], joinsplit_AB["rawtxn"]) - self.expect_cannot_joinsplit(self.nodes[2], joinsplit_CD["rawtxn"]) - - self.expect_cannot_joinsplit(self.nodes[3], joinsplit_AB["rawtxn"]) - self.expect_cannot_joinsplit(self.nodes[3], joinsplit_CD["rawtxn"]) - - # (c) - # AD should be possible to send due to the reorg that - # tossed out AB. - - self.nodes[0].sendrawtransaction(joinsplit_AD["rawtxn"]) - self.nodes[0].generate(1) - - sync_blocks(self.nodes) - -if __name__ == '__main__': - JoinSplitTest().main() From ede0f21e6745fe2368dfc91bd8b2f231d9cabecd Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 09:32:48 -0400 Subject: [PATCH 170/220] desprout --- qa/pull-tester/rpc-tests.sh | 2 - qa/rpc-tests/p2p_nu_peer_management.py | 192 ------------------------- qa/rpc-tests/wallet_listnotes.py | 81 +---------- 3 files changed, 1 insertion(+), 274 deletions(-) delete mode 100755 qa/rpc-tests/p2p_nu_peer_management.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 8c4ad0277..35bf5a7e9 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -23,7 +23,6 @@ testScripts=( 'wallet_changeindicator.py' 'wallet_import_export.py' 'wallet_protectcoinbase.py' - 'wallet_shieldcoinbase_sprout.py' 'wallet_shieldcoinbase_sapling.py' 'wallet_listreceived.py' 'wallet_mergetoaddress.py' @@ -69,7 +68,6 @@ testScripts=( 'getblocktemplate.py' 'bip65-cltv-p2p.py' 'bipdersig-p2p.py' - 'p2p_nu_peer_management.py' 'rewind_index.py' 'p2p_txexpiry_dos.py' 'p2p_node_bloom.py' diff --git a/qa/rpc-tests/p2p_nu_peer_management.py b/qa/rpc-tests/p2p_nu_peer_management.py deleted file mode 100755 index 6cedf66bb..000000000 --- a/qa/rpc-tests/p2p_nu_peer_management.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2018 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -from test_framework.mininode import ( - NodeConn, - NodeConnCB, - NetworkThread, - msg_ping, - SPROUT_PROTO_VERSION, - OVERWINTER_PROTO_VERSION, - SAPLING_PROTO_VERSION, -) -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import initialize_chain_clean, start_nodes, \ - p2p_port, assert_equal - -import time - -# -# In this test we connect Sprout, Overwinter, and Sapling mininodes to a Zcashd -# node which will activate Overwinter at block 10 and Sapling at block 15. -# -# We test: -# 1. the mininodes stay connected to Zcash with Sprout consensus rules -# 2. when Overwinter activates, the Sprout mininodes are dropped -# 3. new Overwinter and Sapling nodes can connect to Zcash -# 4. new Sprout nodes cannot connect to Zcash -# 5. when Sapling activates, the Overwinter mininodes are dropped -# 6. new Sapling nodes can connect to Zcash -# 7. new Sprout and Overwinter nodes cannot connect to Zcash -# -# This test *does not* verify that prior to each activation, the Zcashd -# node will prefer connections with NU-aware nodes, with an eviction process -# that prioritizes non-NU-aware connections. -# - - -class TestManager(NodeConnCB): - def __init__(self): - NodeConnCB.__init__(self) - self.create_callback_map() - - def on_close(self, conn): - pass - - def on_reject(self, conn, message): - conn.rejectMessage = message - - -class NUPeerManagementTest(BitcoinTestFramework): - - def setup_chain(self): - print "Initializing test directory "+self.options.tmpdir - initialize_chain_clean(self.options.tmpdir, 1) - - def setup_network(self): - self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[[ - '-nuparams=5ba81b19:10', # Overwinter - '-nuparams=76b809bb:15', # Sapling - '-debug', - '-whitelist=127.0.0.1', - ]]) - - def run_test(self): - test = TestManager() - - # Launch Sprout, Overwinter, and Sapling mininodes - nodes = [] - for x in xrange(10): - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], - test, "regtest", SPROUT_PROTO_VERSION)) - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], - test, "regtest", OVERWINTER_PROTO_VERSION)) - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], - test, "regtest", SAPLING_PROTO_VERSION)) - - # Start up network handling in another thread - NetworkThread().start() - - # Sprout consensus rules apply at block height 9 - self.nodes[0].generate(9) - assert_equal(9, self.nodes[0].getblockcount()) - - # Verify mininodes are still connected to zcashd node - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(10, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) - assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) - - # Overwinter consensus rules activate at block height 10 - self.nodes[0].generate(1) - assert_equal(10, self.nodes[0].getblockcount()) - print('Overwinter active') - - # Mininodes send ping message to zcashd node. - pingCounter = 1 - for node in nodes: - node.send_message(msg_ping(pingCounter)) - pingCounter = pingCounter + 1 - - time.sleep(3) - - # Verify Sprout mininodes have been dropped, while Overwinter and - # Sapling mininodes are still connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) - assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) - - # Extend the Overwinter chain with another block. - self.nodes[0].generate(1) - - # Connect a new Overwinter mininode to the zcashd node, which is accepted. - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION)) - time.sleep(3) - assert_equal(21, len(self.nodes[0].getpeerinfo())) - - # Connect a new Sapling mininode to the zcashd node, which is accepted. - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) - time.sleep(3) - assert_equal(22, len(self.nodes[0].getpeerinfo())) - - # Try to connect a new Sprout mininode to the zcashd node, which is rejected. - sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) - nodes.append(sprout) - time.sleep(3) - assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) - - # Verify that only Overwinter and Sapling mininodes are connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) - assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) - - # Sapling consensus rules activate at block height 15 - self.nodes[0].generate(4) - assert_equal(15, self.nodes[0].getblockcount()) - print('Sapling active') - - # Mininodes send ping message to zcashd node. - pingCounter = 1 - for node in nodes: - node.send_message(msg_ping(pingCounter)) - pingCounter = pingCounter + 1 - - time.sleep(3) - - # Verify Sprout and Overwinter mininodes have been dropped, while - # Sapling mininodes are still connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) - assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) - - # Extend the Sapling chain with another block. - self.nodes[0].generate(1) - - # Connect a new Sapling mininode to the zcashd node, which is accepted. - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) - time.sleep(3) - assert_equal(12, len(self.nodes[0].getpeerinfo())) - - # Try to connect a new Sprout mininode to the zcashd node, which is rejected. - sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) - nodes.append(sprout) - time.sleep(3) - assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) - - # Try to connect a new Overwinter mininode to the zcashd node, which is rejected. - sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION) - nodes.append(sprout) - time.sleep(3) - assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) - - # Verify that only Sapling mininodes are connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) - assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) - assert_equal(12, versions.count(SAPLING_PROTO_VERSION)) - - for node in nodes: - node.disconnect_node() - -if __name__ == '__main__': - NUPeerManagementTest().main() diff --git a/qa/rpc-tests/wallet_listnotes.py b/qa/rpc-tests/wallet_listnotes.py index 5cd89c661..90fbcced1 100755 --- a/qa/rpc-tests/wallet_listnotes.py +++ b/qa/rpc-tests/wallet_listnotes.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2 +# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2018 The Zcash developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -20,89 +21,9 @@ class WalletListNotes(BitcoinTestFramework): def run_test(self): # Current height = 200 -> Sprout assert_equal(200, self.nodes[0].getblockcount()) - sproutzaddr = self.nodes[0].z_getnewaddress('sprout') # test that we can create a sapling zaddr before sapling activates saplingzaddr = self.nodes[0].z_getnewaddress('sapling') - - # we've got lots of coinbase (taddr) but no shielded funds yet - assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private'])) - - # Set current height to 201 -> Sprout - self.nodes[0].generate(1) - self.sync_all() - assert_equal(201, self.nodes[0].getblockcount()) - - mining_addr = self.nodes[0].listunspent()[0]['address'] - - # Shield coinbase funds (must be a multiple of 10, no change allowed pre-sapling) - receive_amount_10 = Decimal('10.0') - Decimal('0.0001') - recipients = [{"address":sproutzaddr, "amount":receive_amount_10}] - myopid = self.nodes[0].z_sendmany(mining_addr, recipients) - txid_1 = wait_and_assert_operationid_status(self.nodes[0], myopid) - self.sync_all() - - # No funds (with (default) one or more confirmations) in sproutzaddr yet - assert_equal(0, len(self.nodes[0].z_listunspent())) - assert_equal(0, len(self.nodes[0].z_listunspent(1))) - - # no private balance because no confirmations yet - assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private'])) - - # list private unspent, this time allowing 0 confirmations - unspent_cb = self.nodes[0].z_listunspent(0) - assert_equal(1, len(unspent_cb)) - assert_equal(False, unspent_cb[0]['change']) - assert_equal(txid_1, unspent_cb[0]['txid']) - assert_equal(True, unspent_cb[0]['spendable']) - assert_equal(sproutzaddr, unspent_cb[0]['address']) - assert_equal(receive_amount_10, unspent_cb[0]['amount']) - - # list unspent, filtering by address, should produce same result - unspent_cb_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr]) - assert_equal(unspent_cb, unspent_cb_filter) - - # Generate a block to confirm shield coinbase tx - self.nodes[0].generate(1) - self.sync_all() - - # Current height = 202 -> Overwinter. Default address type remains Sprout - assert_equal(202, self.nodes[0].getblockcount()) - - # Send 1.0 (actually 0.9999) from sproutzaddr to a new zaddr - sproutzaddr2 = self.nodes[0].z_getnewaddress() - receive_amount_1 = Decimal('1.0') - Decimal('0.0001') - change_amount_9 = receive_amount_10 - Decimal('1.0') - assert_equal('sprout', self.nodes[0].z_validateaddress(sproutzaddr2)['type']) - recipients = [{"address": sproutzaddr2, "amount":receive_amount_1}] - myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients) - txid_2 = wait_and_assert_operationid_status(self.nodes[0], myopid) - self.sync_all() - - # list unspent, allowing 0conf txs - unspent_tx = self.nodes[0].z_listunspent(0) - assert_equal(len(unspent_tx), 2) - # sort low-to-high by amount (order of returned entries is not guaranteed) - unspent_tx = sorted(unspent_tx, key=lambda k: k['amount']) - assert_equal(False, unspent_tx[0]['change']) - assert_equal(txid_2, unspent_tx[0]['txid']) - assert_equal(True, unspent_tx[0]['spendable']) - assert_equal(sproutzaddr2, unspent_tx[0]['address']) - assert_equal(receive_amount_1, unspent_tx[0]['amount']) - - assert_equal(True, unspent_tx[1]['change']) - assert_equal(txid_2, unspent_tx[1]['txid']) - assert_equal(True, unspent_tx[1]['spendable']) - assert_equal(sproutzaddr, unspent_tx[1]['address']) - assert_equal(change_amount_9, unspent_tx[1]['amount']) - - unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr2]) - assert_equal(1, len(unspent_tx_filter)) - assert_equal(unspent_tx[0], unspent_tx_filter[0]) - - unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr]) - assert_equal(1, len(unspent_tx_filter)) - assert_equal(unspent_tx[1], unspent_tx_filter[0]) # Set current height to 204 -> Sapling self.nodes[0].generate(2) From 9b6bc6cf1437e72711e458b3bad77e44b39a5ccd Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 09:34:30 -0400 Subject: [PATCH 171/220] desprout --- qa/rpc-tests/regtest_signrawtransaction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qa/rpc-tests/regtest_signrawtransaction.py b/qa/rpc-tests/regtest_signrawtransaction.py index 2e0273677..78ec1fbc8 100755 --- a/qa/rpc-tests/regtest_signrawtransaction.py +++ b/qa/rpc-tests/regtest_signrawtransaction.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2 +# Copyright (c) 2019-2020 The Hush developers # Copyright (c) 2018 The Zcash developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -18,7 +19,7 @@ class RegtestSignrawtransactionTest (BitcoinTestFramework): self.nodes[0].generate(1) self.sync_all() taddr = self.nodes[1].getnewaddress() - zaddr1 = self.nodes[1].z_getnewaddress('sprout') + zaddr1 = self.nodes[1].z_getnewaddress('sapling') self.nodes[0].sendtoaddress(taddr, 2.0) self.nodes[0].generate(1) From b5c9453129d68a7bd4537bdfeb7114aa28b7fcf9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 10:46:25 -0400 Subject: [PATCH 172/220] Declare S4 to have happened already. This is now now --- src/komodo_defs.h | 8 +++----- src/komodo_notary.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 17d276c4e..423d556d0 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -55,11 +55,9 @@ // Wed Jan 29 08:14:12 2020 Eastern # 1580303652 // Wed Jan 29 13:14:12 2020 GMT # 1580303652 const uint32_t nHushHardforkHeight = 166250; -// $ ./contrib/block_time.pl 255555 -// Hush Block 255555 will happen at roughly: -// Sat Jul 11 21:41:12 2020 Eastern # 1594518072 -// Sun Jul 12 01:41:12 2020 GMT # 1594518072 -const uint32_t nHushHardforkHeight2 = 255555; +// $ ./contrib/block_time.pl 245555 +// Hush Block 245555 will happen at roughly... now +const uint32_t nHushHardforkHeight2 = 245055; // No coins/code are currently using timestamp activated fork const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT diff --git a/src/komodo_notary.h b/src/komodo_notary.h index 8114a86af..d5591aa29 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * From 07d7aacd901d7d40a30ecee9e3219fabc46c331a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 11:24:12 -0400 Subject: [PATCH 173/220] destake --- src/komodo_defs.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 423d556d0..3a4af6f48 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -34,9 +34,6 @@ #define KOMODO_FIRSTFUNGIBLEID 100 #define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018 #define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019 -#define ASSETCHAINS_STAKED_BLOCK_FUTURE_MAX 57 -#define ASSETCHAINS_STAKED_BLOCK_FUTURE_HALF 27 -#define ASSETCHAINS_STAKED_MIN_POW_DIFF 536900000 // 537000000 537300000 #define _COINBASE_MATURITY 100 // KMD Notary Seasons From 40f68d0d0581aab8eaba17ec19c3a3b689cb7f6b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 11:43:18 -0400 Subject: [PATCH 174/220] HUSH dpow --- src/komodo_defs.h | 74 +++++++++-------------------------------------- 1 file changed, 14 insertions(+), 60 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 3a4af6f48..0b51c09af 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -333,71 +333,25 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" } }, { - // Season 4 https://github.com/KomodoPlatform/dPoW/blob/s4/iguana/3rd_party - {"alien_AR", "024f20c096b085308e21893383f44b4faf1cdedea9ad53cc7d7e7fbfa0c30c1e71" }, - {"alien_EU", "022b85908191788f409506ebcf96a892f3274f352864c3ed566c5a16de63953236" }, - {"alien_NA", "022f62b56ddfd07c9860921c701285ac39bb3ac8f6f083d1b59c8f4943be3de162" }, - {"alright_DEV", "03b6f9493658bdd102503585a08ae642b49d6a68fb69ac3626f9737cd7581abdfa" }, - {"artemii235_DEV", "037a20916d2e9ea575300ac9d729507c23a606b9a200c8e913d7c9832f912a1fa7" }, - {"chainmakers_NA", "028803e07bcc521fde264b7191a944f9b3612e8ee4e24a99bcd903f6976240839a" }, - {"chainzilla_SH", "0311dde03c2dd654ce78323b718ed3ad73a464d1bde97820f3395f54788b5420dd" }, - {"chmex_AR", "030cd487e10fbf142e0e8d582e702ecb775f378569c3cb5acd0ff97b6b12803588" }, - {"chmex_EU", "030bf7bd7ad0515c33b5d5d9a91e0729baf801b9002f80495ae535ea1cebb352cb" }, + // Season 4 HUSH notaries. A new DPoW network is born. {"cipi_EU", "026f4f66385daaf8313ef30ffe4988e7db497132682dca185a70763d93e1417d9d" }, {"cipi_NA", "03f4e69edcb4fa3b2095cb8cb1ca010f4ec4972eac5d8822397e5c8d87aa21a739" }, - {"daemonfox_NA", "023c7584b1006d4a62a4b4c9c1ede390a3789316547897d5ed49ff9385a3acb411" }, - {"dappvader_SH", "025199bc04bcb8a17976d9fe8bc87763a6150c2727321aa59bf34a2b49f2f3a0ce" }, - {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" }, - {"decker_DEV", "02fca8ee50e49f480de275745618db7b0b3680b0bdcce7dcae7d2e0fd5c3345744" }, - {"decker_EU", "027777775b89ff548c3be54fb0c9455437d87f38bfce83bdef113899881b219c9e" }, - {"dragonhound_NA", "029912212d370ee0fb4d38eefd8bfcd8ab04e2c3b0354020789c29ddf2a35c72d6" }, - {"dudezmobi_AR", "033c121d3f8d450174674a73f3b7f140b2717a7d51ea19ee597e2e8e8f9d5ed87f" }, - {"etszombi_AR", "03bfcbca83f11e622fa4eed9a1fa25dba377981ea3b22e3d0a4015f9a932af9272" }, - {"etszombi_EU", "03a5c083c78ba397970f20b544a01c13e7ed36ca8a5ae26d5fe7bd38b92b6a0c94" }, - {"fullmoon_AR", "03639bc56d3fecf856f17759a441c5893668e7c2d460f3d216798a413cd6766bb2" }, - {"fullmoon_NA", "03e388bcc579ac2675f8fadfa921eec186dcea8d2b43de1eed6caba23d5a962b74" }, - {"fullmoon_SH", "03a5cfda2b097c808834ccdd805828c811b519611feabdfe6b3644312e53f6748f" }, - {"gcharang_SH", "02a654037d12cdd609f4fad48e15ec54538e03f61fdae1acb855f16ebacac6bd73" }, - {"greer_NA", "0262da6aaa0b295b8e2f120035924758a4a630f899316dc63ee15ef03e9b7b2b23" }, - {"indenodes_AR", "0242778789986d614f75bcf629081651b851a12ab1cc10c73995b27b90febb75a2" }, - {"indenodes_EU", "03a416533cace0814455a1bb1cd7861ce825a543c6f6284a432c4c8d8875b7ace9" }, - {"indenodes_NA", "02b3908eda4078f0e9b6704451cdc24d418e899c0f515fab338d7494da6f0a647b" }, - {"indenodes_SH", "031d1584cf0eb4a2d314465e49e2677226b1615c3718013b8d6b4854c15676a58c" }, - {"karasugoi_NA", "02f803e6f159824a181cc5d709f3d1e7ff65f19e1899920724aeb4e3d2d869f911" }, - {"madmax_AR", "027afddbcf690230dd8d435ec16a7bfb0083e6b77030f763437f291dfc40a579d0" }, - {"madmax_EU", "0397ec3a4ad84b3009566d260c89f1c4404e86e5d044964747c9371277e38f5995" }, - {"madmax_NA", "036d3afebe1eab09f4c38c3ee6a4659ad390f3df92787c11437a58c59a29e408e6" }, - {"marmarachain_AR", "028690ca1e3afdf8a38b421f6a41f5ff407afc96d5a7a6a488330aae26c8b086bb" }, - {"mcrypt_SH", "027a4ca7b11d3456ff558c08bb04483a89c7f383448461fd0b6b3b07424aabe9a4" }, - {"metaphilibert_AR", "0239e34ad22957bbf4c8df824401f237b2afe8d40f7a645ecd43e8f27dde1ab0da" }, - {"metaphilibert_SH", "03b21ff042bf1730b28bde43f44c064578b41996117ac7634b567c3773089e3be3" }, - {"mihailo_EU", "036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252" }, - {"mrlynch_AR", "03e67440141f53a08684c329ebc852b018e41f905da88e52aa4a6dc5aa4b12447a" }, - {"mylo_SH", "026d5f29d09ff3f33e14db4811606249b2438c6bcf964876714f81d1f2d952acde" }, {"node9_EU", "0392e4c9400e69f28c6b9e89d586da69d5a6af7702f1045eaa6ebc1996f0496e1f" }, - {"nodeone_NA", "0310a249c6c2dcc29f2135715138a9ddb8e01c0eab701cbd0b96d9cec660dbdc58" }, - {"nutellalicka_SH", "0284c4d3cb97dd8a32d10fb32b1855ae18cf845dad542e3b8937ca0e998fb54ecc" }, - {"oszy_EU", "03c53bd421de4a29ce68c8cc83f802e1181e77c08f8f16684490d61452ea8d023a" }, - {"patchkez_SH", "028c08db6e7242681f50db6c234fe3d6e12fb1a915350311be26373bac0d457d49" }, - {"pbca26_NA", "03c18431bb6bc95672f640f19998a196becd2851d5dcba4795fe8d85b7d77eab81" }, - {"peer2cloud_AR", "0243958faf9ae4d43b598b859ddc595c170c4cf50f8e4517d660ae5bc72aeb821b" }, - {"phba2061_EU", "03369187ce134bd7793ee34af7756fe1ab27202e09306491cdd5d8ad2c71697937" }, {"phm87_SH", "03889a10f9df2caef57220628515693cf25316fe1b0693b0241419e75d0d0e66ed" }, - {"pirate_EU", "0240011b95cde819f298fe0f507b2260c9fecdab784924076d4d1e54c522103cb1" }, - {"pirate_NA", "02ad7ef25d2dd461e361120cd3efe7cbce5e9512c361e9185aac33dd303d758613" }, - {"pungocloud_SH", "02641c36ae6747b88150a463a1fe65cf7a9d1c00a64387c73f296f0b64e77c7d3f" }, - {"smdmitry_AR", "0397b7584cb29717b721c0c587d4462477efc1f36a56921f133c9d17b0cd7f278a" }, - {"starfleet_EU", "03c6e047218f34644ccba67e317b9da5d28e68bbbb6b9973aef1281d2bafa46496" }, - {"strob_NA", "02285bf2f9e96068ecac14bc6f770e394927b4da9f5ba833eaa9468b5d47f203a3" }, - {"strob_SH", "0213751a1c59d3489ca85b3d62a3d606dcef7f0428aa021c1978ea16fb38a2fad6" }, - {"swisscertifiers_EU", "02e7722ebba9f8b5ebfb4e87d4fa58cc75aef677535b9cfc060c7d9471aacd9c9e" }, - {"titomane_AR", "03958bd8d13fe6946b8d0d0fbbc3861c72542560d0276e80a4c6b5fe55bc758b81" }, - {"titomane_EU", "02276090e483db1a01a802456b10831b3b6e0a6ad3ece9b2a01f4aad0e480c8edc" }, - {"titomane_SH", "02abf206bafc8048dbdc042b8eb6b1e356ea5dbe149eae3532b4811d4905e5cf01" }, - {"tonyl_AR", "0229e499e3f2e065ced402ceb8aaf3d5ab8bd3793aa074305e9fa30772ce604908" }, - {"tonyl_DEV", "0258b77d7dcfc6c2628b0b6b438951a6e74201fb2cd180a795e4c37fcf8e78a678" }, {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"zatjum_SH", "0241c5660ca540780be66603b1791127a1261d56abbcb7562c297eec8e4fc078fb" } + + //TODO: placeholders so we have 16 NNs, details to be filled soon + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, } }; From 94134862e5c9021eb86dab1dcb071521287b03c8 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 11:44:38 -0400 Subject: [PATCH 175/220] try to make linker happy --- src/cc/cclib.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index 364953148..e8b4a32b2 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -1,3 +1,4 @@ +// Copyright © 2019-2020 The Hush Developers /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -34,6 +35,9 @@ #define EVAL_ROGUE 17 std::string MYCCLIBNAME = (char *)"rogue"; +extern const uint32_t z2zForkHeight; + + #elif BUILD_CUSTOMCC #include "customcc.h" From 0c5923d7492f3d5452eeb5b9bc62479c0a1a77d9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 12:04:12 -0400 Subject: [PATCH 176/220] Revert "HUSH dpow" This reverts commit 40f68d0d0581aab8eaba17ec19c3a3b689cb7f6b. --- src/komodo_defs.h | 74 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 0b51c09af..3a4af6f48 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -333,25 +333,71 @@ static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" } }, { - // Season 4 HUSH notaries. A new DPoW network is born. + // Season 4 https://github.com/KomodoPlatform/dPoW/blob/s4/iguana/3rd_party + {"alien_AR", "024f20c096b085308e21893383f44b4faf1cdedea9ad53cc7d7e7fbfa0c30c1e71" }, + {"alien_EU", "022b85908191788f409506ebcf96a892f3274f352864c3ed566c5a16de63953236" }, + {"alien_NA", "022f62b56ddfd07c9860921c701285ac39bb3ac8f6f083d1b59c8f4943be3de162" }, + {"alright_DEV", "03b6f9493658bdd102503585a08ae642b49d6a68fb69ac3626f9737cd7581abdfa" }, + {"artemii235_DEV", "037a20916d2e9ea575300ac9d729507c23a606b9a200c8e913d7c9832f912a1fa7" }, + {"chainmakers_NA", "028803e07bcc521fde264b7191a944f9b3612e8ee4e24a99bcd903f6976240839a" }, + {"chainzilla_SH", "0311dde03c2dd654ce78323b718ed3ad73a464d1bde97820f3395f54788b5420dd" }, + {"chmex_AR", "030cd487e10fbf142e0e8d582e702ecb775f378569c3cb5acd0ff97b6b12803588" }, + {"chmex_EU", "030bf7bd7ad0515c33b5d5d9a91e0729baf801b9002f80495ae535ea1cebb352cb" }, {"cipi_EU", "026f4f66385daaf8313ef30ffe4988e7db497132682dca185a70763d93e1417d9d" }, {"cipi_NA", "03f4e69edcb4fa3b2095cb8cb1ca010f4ec4972eac5d8822397e5c8d87aa21a739" }, + {"daemonfox_NA", "023c7584b1006d4a62a4b4c9c1ede390a3789316547897d5ed49ff9385a3acb411" }, + {"dappvader_SH", "025199bc04bcb8a17976d9fe8bc87763a6150c2727321aa59bf34a2b49f2f3a0ce" }, + {"decker_AR", "02a85540db8d41c7e60bf0d33d1364b4151cad883dd032878ea4c037f67b769635" }, + {"decker_DEV", "02fca8ee50e49f480de275745618db7b0b3680b0bdcce7dcae7d2e0fd5c3345744" }, + {"decker_EU", "027777775b89ff548c3be54fb0c9455437d87f38bfce83bdef113899881b219c9e" }, + {"dragonhound_NA", "029912212d370ee0fb4d38eefd8bfcd8ab04e2c3b0354020789c29ddf2a35c72d6" }, + {"dudezmobi_AR", "033c121d3f8d450174674a73f3b7f140b2717a7d51ea19ee597e2e8e8f9d5ed87f" }, + {"etszombi_AR", "03bfcbca83f11e622fa4eed9a1fa25dba377981ea3b22e3d0a4015f9a932af9272" }, + {"etszombi_EU", "03a5c083c78ba397970f20b544a01c13e7ed36ca8a5ae26d5fe7bd38b92b6a0c94" }, + {"fullmoon_AR", "03639bc56d3fecf856f17759a441c5893668e7c2d460f3d216798a413cd6766bb2" }, + {"fullmoon_NA", "03e388bcc579ac2675f8fadfa921eec186dcea8d2b43de1eed6caba23d5a962b74" }, + {"fullmoon_SH", "03a5cfda2b097c808834ccdd805828c811b519611feabdfe6b3644312e53f6748f" }, + {"gcharang_SH", "02a654037d12cdd609f4fad48e15ec54538e03f61fdae1acb855f16ebacac6bd73" }, + {"greer_NA", "0262da6aaa0b295b8e2f120035924758a4a630f899316dc63ee15ef03e9b7b2b23" }, + {"indenodes_AR", "0242778789986d614f75bcf629081651b851a12ab1cc10c73995b27b90febb75a2" }, + {"indenodes_EU", "03a416533cace0814455a1bb1cd7861ce825a543c6f6284a432c4c8d8875b7ace9" }, + {"indenodes_NA", "02b3908eda4078f0e9b6704451cdc24d418e899c0f515fab338d7494da6f0a647b" }, + {"indenodes_SH", "031d1584cf0eb4a2d314465e49e2677226b1615c3718013b8d6b4854c15676a58c" }, + {"karasugoi_NA", "02f803e6f159824a181cc5d709f3d1e7ff65f19e1899920724aeb4e3d2d869f911" }, + {"madmax_AR", "027afddbcf690230dd8d435ec16a7bfb0083e6b77030f763437f291dfc40a579d0" }, + {"madmax_EU", "0397ec3a4ad84b3009566d260c89f1c4404e86e5d044964747c9371277e38f5995" }, + {"madmax_NA", "036d3afebe1eab09f4c38c3ee6a4659ad390f3df92787c11437a58c59a29e408e6" }, + {"marmarachain_AR", "028690ca1e3afdf8a38b421f6a41f5ff407afc96d5a7a6a488330aae26c8b086bb" }, + {"mcrypt_SH", "027a4ca7b11d3456ff558c08bb04483a89c7f383448461fd0b6b3b07424aabe9a4" }, + {"metaphilibert_AR", "0239e34ad22957bbf4c8df824401f237b2afe8d40f7a645ecd43e8f27dde1ab0da" }, + {"metaphilibert_SH", "03b21ff042bf1730b28bde43f44c064578b41996117ac7634b567c3773089e3be3" }, + {"mihailo_EU", "036494e7c9467c8c7ff3bf29e841907fb0fa24241866569944ea422479ec0e6252" }, + {"mrlynch_AR", "03e67440141f53a08684c329ebc852b018e41f905da88e52aa4a6dc5aa4b12447a" }, + {"mylo_SH", "026d5f29d09ff3f33e14db4811606249b2438c6bcf964876714f81d1f2d952acde" }, {"node9_EU", "0392e4c9400e69f28c6b9e89d586da69d5a6af7702f1045eaa6ebc1996f0496e1f" }, + {"nodeone_NA", "0310a249c6c2dcc29f2135715138a9ddb8e01c0eab701cbd0b96d9cec660dbdc58" }, + {"nutellalicka_SH", "0284c4d3cb97dd8a32d10fb32b1855ae18cf845dad542e3b8937ca0e998fb54ecc" }, + {"oszy_EU", "03c53bd421de4a29ce68c8cc83f802e1181e77c08f8f16684490d61452ea8d023a" }, + {"patchkez_SH", "028c08db6e7242681f50db6c234fe3d6e12fb1a915350311be26373bac0d457d49" }, + {"pbca26_NA", "03c18431bb6bc95672f640f19998a196becd2851d5dcba4795fe8d85b7d77eab81" }, + {"peer2cloud_AR", "0243958faf9ae4d43b598b859ddc595c170c4cf50f8e4517d660ae5bc72aeb821b" }, + {"phba2061_EU", "03369187ce134bd7793ee34af7756fe1ab27202e09306491cdd5d8ad2c71697937" }, {"phm87_SH", "03889a10f9df2caef57220628515693cf25316fe1b0693b0241419e75d0d0e66ed" }, + {"pirate_EU", "0240011b95cde819f298fe0f507b2260c9fecdab784924076d4d1e54c522103cb1" }, + {"pirate_NA", "02ad7ef25d2dd461e361120cd3efe7cbce5e9512c361e9185aac33dd303d758613" }, + {"pungocloud_SH", "02641c36ae6747b88150a463a1fe65cf7a9d1c00a64387c73f296f0b64e77c7d3f" }, + {"smdmitry_AR", "0397b7584cb29717b721c0c587d4462477efc1f36a56921f133c9d17b0cd7f278a" }, + {"starfleet_EU", "03c6e047218f34644ccba67e317b9da5d28e68bbbb6b9973aef1281d2bafa46496" }, + {"strob_NA", "02285bf2f9e96068ecac14bc6f770e394927b4da9f5ba833eaa9468b5d47f203a3" }, + {"strob_SH", "0213751a1c59d3489ca85b3d62a3d606dcef7f0428aa021c1978ea16fb38a2fad6" }, + {"swisscertifiers_EU", "02e7722ebba9f8b5ebfb4e87d4fa58cc75aef677535b9cfc060c7d9471aacd9c9e" }, + {"titomane_AR", "03958bd8d13fe6946b8d0d0fbbc3861c72542560d0276e80a4c6b5fe55bc758b81" }, + {"titomane_EU", "02276090e483db1a01a802456b10831b3b6e0a6ad3ece9b2a01f4aad0e480c8edc" }, + {"titomane_SH", "02abf206bafc8048dbdc042b8eb6b1e356ea5dbe149eae3532b4811d4905e5cf01" }, + {"tonyl_AR", "0229e499e3f2e065ced402ceb8aaf3d5ab8bd3793aa074305e9fa30772ce604908" }, + {"tonyl_DEV", "0258b77d7dcfc6c2628b0b6b438951a6e74201fb2cd180a795e4c37fcf8e78a678" }, {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - - //TODO: placeholders so we have 16 NNs, details to be filled soon - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, - {"webworker01_NA", "02de90c720c007229374772505a43917a84ed129d5fbcfa4949cc2e9b563351124" }, + {"zatjum_SH", "0241c5660ca540780be66603b1791127a1261d56abbcb7562c297eec8e4fc078fb" } } }; From a470c4e2510be7c232b4830e7701cebbdf3624a5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 12:21:30 -0400 Subject: [PATCH 177/220] get rid of z2zforkheight which causes linker bugz --- src/cc/cclib.cpp | 3 --- src/komodo_defs.h | 3 +-- src/main.cpp | 10 +++++----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/cc/cclib.cpp b/src/cc/cclib.cpp index e8b4a32b2..67440f3da 100644 --- a/src/cc/cclib.cpp +++ b/src/cc/cclib.cpp @@ -35,9 +35,6 @@ #define EVAL_ROGUE 17 std::string MYCCLIBNAME = (char *)"rogue"; -extern const uint32_t z2zForkHeight; - - #elif BUILD_CUSTOMCC #include "customcc.h" diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 3a4af6f48..e482390bb 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -59,10 +59,9 @@ const uint32_t nHushHardforkHeight2 = 245055; // No coins/code are currently using timestamp activated fork const uint32_t nHushHardforkTimestamp = 1580303652; // Jan 29nd 1pm GMT const uint32_t nHushHardforkTimestamp2 = 1594425600; // Jul 11th 12a GMT -extern const uint32_t z2zForkHeight; static const uint32_t KMD_SEASON_TIMESTAMPS[NUM_KMD_SEASONS] = {1525132800, 1563148800, nHushHardforkTimestamp, nHushHardforkTimestamp2, nHushHardforkTimestamp2*5, nHushHardforkTimestamp2*6}; -static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)z2zForkHeight, 5*nHushHardforkHeight2}; +static const int32_t KMD_SEASON_HEIGHTS[NUM_KMD_SEASONS] = {1,2,nHushHardforkHeight, nHushHardforkHeight2, (int)340000, 5*nHushHardforkHeight2}; // Era array of pubkeys. Add extra seasons to bottom as requried, after adding appropriate info above. static const char *notaries_elected[NUM_KMD_SEASONS][NUM_KMD_NOTARIES][2] = diff --git a/src/main.cpp b/src/main.cpp index d5afa5baf..f0bc7793a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; -const uint32_t z2zForkHeight = GetArg("-z2zforkheight",340000); +const uint32_t 340000 = GetArg("-z2zforkheight",340000); unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -1736,12 +1736,12 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa { AssertLockHeld(cs_main); const uint32_t z2zTransitionWindow = 10; - const uint32_t z2zTransitionStart = z2zForkHeight - z2zTransitionWindow; + const uint32_t z2zTransitionStart = 340000 - z2zTransitionWindow; const uint32_t nHeight = chainActive.Height(); // This only applies to HUSH3, other chains can start off z2z via ac_private=1 if(ishush3) { - if((nHeight >= z2zTransitionStart) || (nHeight <= z2zForkHeight)) { + if((nHeight >= z2zTransitionStart) || (nHeight <= 340000)) { // During the z2z transition window, only coinbase tx's as part of blocks are allowed // Theory: We want an empty mempool at our fork block height, and the only way to assure that // is to have an empty mempool for a few previous blocks, to take care of potential re-orgs @@ -3364,7 +3364,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; if(!ASSETCHAINS_PRIVATE && ishush3) { unsigned int nHeight = pindex->GetHeight(); - if(nHeight >= z2zForkHeight) { + if(nHeight >= 340000) { // At startup, HUSH3 doesn't know a block height yet and so we must wait until // connecting a block fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,nHeight); @@ -6337,7 +6337,7 @@ bool static LoadBlockIndexDB() // Try to detect if we are z2z based on height of blocks on disk // This helps to set it correctly on startup before a new block is connected - if(ishush3 && chainActive.Height() >= z2zForkHeight) { + if(ishush3 && chainActive.Height() >= 340000) { LogPrintf("%s: enabled ac_private=1 at height=%d\n", __func__, chainActive.Height()); ASSETCHAINS_PRIVATE = 1; } From 7f7876d2084daebc89b1914c870fa407c4fbef4e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 16 Jun 2020 12:25:47 -0400 Subject: [PATCH 178/220] oops --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index f0bc7793a..317be206d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,6 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; -const uint32_t 340000 = GetArg("-z2zforkheight",340000); unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; From 4de60497c866c82330defd63b11884ab8991f973 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 00:04:55 -0400 Subject: [PATCH 179/220] Refactor GetSaplingWitnesses code and add some logging --- src/wallet/wallet.cpp | 13 ++++++++----- src/zcash/Zcash.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a7ca3d74d..b9ad1919d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1719,16 +1719,19 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, boost::optional rt; int i = 0; for (SaplingOutPoint note : notes) { - if (mapWallet.count(note.hash) && - mapWallet[note.hash].mapSaplingNoteData.count(note) && - mapWallet[note.hash].mapSaplingNoteData[note].witnesses.size() > 0) { - witnesses[i] = mapWallet[note.hash].mapSaplingNoteData[note].witnesses.front(); + fprintf(stderr,"%s: i=%d\n", __func__,i); + auto noteData = mapWallet[note.hash].mapSaplingNoteData; + auto witnessess = noteData[note].witnesses; + if (mapWallet.count(note.hash) && noteData.count(note) && witnesses.size() > 0) { + fprintf(stderr,"%s: Found %lu witnesses for note %s\n", __func__, witnesses.size(), note.hash.ToString().c_str() ); + witnesses[i] = witnesses.front(); if (!rt) { rt = witnesses[i]->root(); } else { if(*rt == witnesses[i]->root()) { // Something is fucky - std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root!"; + std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root! i="; + err += i; throw std::logic_error(err); } diff --git a/src/zcash/Zcash.h b/src/zcash/Zcash.h index 84dfe9525..e45aa1d02 100644 --- a/src/zcash/Zcash.h +++ b/src/zcash/Zcash.h @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers #ifndef ZC_ZCASH_H_ #define ZC_ZCASH_H_ From d0dade1d2c76d43cc8c7f245718e11997b2fc59d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 10:13:57 -0400 Subject: [PATCH 180/220] desprout --- src/zcash/JoinSplit.cpp | 68 ----------------------------------------- 1 file changed, 68 deletions(-) diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index db51ff1fd..5cd7627dc 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -28,73 +28,5 @@ class JoinSplitCircuit : public JoinSplit { public: JoinSplitCircuit() {} ~JoinSplitCircuit() {} - - /* - SproutProof prove( - const std::array& inputs, - const std::array& outputs, - std::array& out_notes, - std::array& out_ciphertexts, - uint256& out_ephemeralKey, - const uint256& joinSplitPubKey, - uint256& out_randomSeed, - std::array& out_macs, - std::array& out_nullifiers, - std::array& out_commitments, - uint64_t vpub_old, - uint64_t vpub_new, - const uint256& rt, - bool computeProof, - uint256 *out_esk // Payment disclosure - ) { - GrothProof proof; - return proof; - } - */ }; - -/* -template -JoinSplit* JoinSplit::Prepared() -{ - return new JoinSplitCircuit(); -} - -template -uint256 JoinSplit::h_sig( - const uint256& randomSeed, - const std::array& nullifiers, - const uint256& joinSplitPubKey -) { - const unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] - = {'Z','c','a','s','h','C','o','m','p','u','t','e','h','S','i','g'}; - - std::vector block(randomSeed.begin(), randomSeed.end()); - - for (size_t i = 0; i < NumInputs; i++) { - block.insert(block.end(), nullifiers[i].begin(), nullifiers[i].end()); - } - - block.insert(block.end(), joinSplitPubKey.begin(), joinSplitPubKey.end()); - - uint256 output; - - if (crypto_generichash_blake2b_salt_personal(output.begin(), 32, - &block[0], block.size(), - NULL, 0, // No key. - NULL, // No salt. - personalization - ) != 0) - { - throw std::logic_error("hash function failure"); - } - - return output; -} - - -template class JoinSplit; - -*/ } From 6e31ee3b1d3a790f5603ccbc1a1c3f6fa0c2d45b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 10:41:33 -0400 Subject: [PATCH 181/220] fix --- src/wallet/wallet.cpp | 11 +++++++---- src/zcash/IncrementalMerkleTree.cpp | 1 + src/zcash/util.h | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b9ad1919d..b3d759f83 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1721,14 +1721,17 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, for (SaplingOutPoint note : notes) { fprintf(stderr,"%s: i=%d\n", __func__,i); auto noteData = mapWallet[note.hash].mapSaplingNoteData; - auto witnessess = noteData[note].witnesses; - if (mapWallet.count(note.hash) && noteData.count(note) && witnesses.size() > 0) { - fprintf(stderr,"%s: Found %lu witnesses for note %s\n", __func__, witnesses.size(), note.hash.ToString().c_str() ); - witnesses[i] = witnesses.front(); + auto nWitnesses = noteData[note].witnesses.size(); + if (mapWallet.count(note.hash) && noteData.count(note) && nWitnesses > 0) { + fprintf(stderr,"%s: Found %lu witnesses for note %s\n", __func__, nWitnesses, note.hash.ToString().c_str() ); + witnesses[i] = noteData[note].witnesses.front(); if (!rt) { + fprintf(stderr,"%s: Setting witness root\n",__func__); rt = witnesses[i]->root(); } else { if(*rt == witnesses[i]->root()) { + //fprintf(stderr,"%s: rt=%s\n",__func__,rt.GetHash().ToString().c_str()); + //fprintf(stderr,"%s: witnesses[%d]->root()=%s\n",__func__,i,witnesses[i]->root().GetHash().ToString().c_str()); // Something is fucky std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root! i="; err += i; diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index 4d3ff8c2b..247eaf80c 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -1018,6 +1018,7 @@ size_t IncrementalMerkleTree::next_depth(size_t skip) const { template Hash IncrementalMerkleTree::root(size_t depth, std::deque filler_hashes) const { + fprintf(stderr,"%s: depth=%d\n",__func__,depth); PathFiller filler(filler_hashes); Hash combine_left = left ? *left : filler.next(0); diff --git a/src/zcash/util.h b/src/zcash/util.h index 10886e3ca..0c04a5aac 100644 --- a/src/zcash/util.h +++ b/src/zcash/util.h @@ -1,3 +1,4 @@ +// Copyright (c) 2019-2020 The Hush developers #ifndef ZC_UTIL_H_ #define ZC_UTIL_H_ From 280cc4cfdad1e0a6053b643142e56fa4092629e0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 12:36:08 -0400 Subject: [PATCH 182/220] oops --- src/zcash/IncrementalMerkleTree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zcash/IncrementalMerkleTree.cpp b/src/zcash/IncrementalMerkleTree.cpp index 247eaf80c..d4411c11b 100644 --- a/src/zcash/IncrementalMerkleTree.cpp +++ b/src/zcash/IncrementalMerkleTree.cpp @@ -1018,7 +1018,7 @@ size_t IncrementalMerkleTree::next_depth(size_t skip) const { template Hash IncrementalMerkleTree::root(size_t depth, std::deque filler_hashes) const { - fprintf(stderr,"%s: depth=%d\n",__func__,depth); + //fprintf(stderr,"%s: depth=%d\n",__func__,depth); PathFiller filler(filler_hashes); Hash combine_left = left ? *left : filler.next(0); From f8972d4150318631b19ab3abff9ce237783ac034 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 17:49:18 -0400 Subject: [PATCH 183/220] Remove mention of joinsplit from some error messages --- src/coins.h | 4 ++-- src/main.cpp | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/coins.h b/src/coins.h index 3e8f674fb..2d08be42c 100644 --- a/src/coins.h +++ b/src/coins.h @@ -545,7 +545,7 @@ public: size_t DynamicMemoryUsage() const; /** - * Amount of bitcoins coming in to a transaction + * Amount of HUSH coming in to a transaction * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. * @@ -557,7 +557,7 @@ public: //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - //! Check whether all joinsplit requirements (anchors/nullifiers) are satisfied + //! Check whether all shielded requirements (anchors/nullifiers) are satisfied bool HaveShieldedRequirements(const CTransaction& tx) const; //! Return priority of tx at height nHeight diff --git a/src/main.cpp b/src/main.cpp index 317be206d..ada7ab8a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1907,7 +1907,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (!view.HaveShieldedRequirements(tx)) { //fprintf(stderr,"accept failure.2\n"); - return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); + return state.Invalid(error("AcceptToMemoryPool: shielded requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); } // Bring the best block into scope @@ -2728,9 +2728,9 @@ namespace Consensus { if (!inputs.HaveInputs(tx)) return state.Invalid(error("CheckInputs(): %s inputs unavailable", tx.GetHash().ToString())); - // are the JoinSplit's requirements met? + // are the shielded requirements met? if (!inputs.HaveShieldedRequirements(tx)) - return state.Invalid(error("CheckInputs(): %s JoinSplit requirements not met", tx.GetHash().ToString())); + return state.Invalid(error("CheckInputs(): %s shielded requirements not met", tx.GetHash().ToString())); CAmount nValueIn = 0; CAmount nFees = 0; @@ -3464,7 +3464,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Before the genesis block, there was an empty tree SproutMerkleTree tree; pindex->hashSproutAnchor = tree.root(); - // The genesis block contained no JoinSplits + // The genesis block contained no JoinSplits, lulz pindex->hashFinalSproutRoot = pindex->hashSproutAnchor; } return true; @@ -3557,10 +3557,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin return state.DoS(100, error("ConnectBlock(): inputs missing/spent"), REJECT_INVALID, "bad-txns-inputs-missingorspent"); } - // are the JoinSplit's requirements met? + // are the shielded requirements met? if (!view.HaveShieldedRequirements(tx)) - return state.DoS(100, error("ConnectBlock(): JoinSplit requirements not met"), - REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met"); + return state.DoS(100, error("ConnectBlock(): shielded requirements not met"), REJECT_INVALID, "bad-txns-joinsplit-requirements-not-met"); if (fAddressIndex || fSpentIndex) { @@ -6403,7 +6402,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth CBlockIndex* pindexFailure = NULL; int nGoodTransactions = 0; CValidationState state; - // No need to verify JoinSplits twice + // No need to verify shielded req's twice auto verifier = libzcash::ProofVerifier::Disabled(); //fprintf(stderr,"start VerifyDB %u\n",(uint32_t)time(NULL)); for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) From 646c68490b5aa87ef50db127fa1ef7dd425425a7 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 17:53:12 -0400 Subject: [PATCH 184/220] cleanup --- src/main.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ada7ab8a6..fb53e2c28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1578,6 +1578,7 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio else if ( joinsplit.vpub_new != 0 && joinsplit.vpub_old == 0 ) z_t++; } + if ( ASSETCHAINS_PRIVATE != 0 && invalid_private_taddr != 0 ) { static uint32_t counter; @@ -3657,23 +3658,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } - //if ( ASSETCHAINS_SYMBOL[0] == 0 ) - // komodo_earned_interest(pindex->GetHeight(),sum); CTxUndo undoDummy; if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); } UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->GetHeight()); - /* - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { - BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) { - // Insert the note commitments into our temporary tree. - - sprout_tree.append(note_commitment); - } - } - */ BOOST_FOREACH(const OutputDescription &outputDescription, tx.vShieldedOutput) { sapling_tree.append(outputDescription.cm); From 36e917f1d3e1d014deb53e7ec178f13afa954312 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 20:43:58 -0400 Subject: [PATCH 185/220] copyright --- src/rpc/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index cfe21a6d5..56c038596 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. From 83be5195e93b4977d602ad8f055320858a25e07f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 20:44:54 -0400 Subject: [PATCH 186/220] Revert "Randomize sietch memos and increase min zouts to 3" This reverts commit a053d212b8e22d1d8ffe08a2e0955f1854055702. --- src/wallet/rpcwallet.cpp | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 221bef44e..867de51a7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4590,15 +4590,6 @@ UniValue z_getoperationstatus_IMPL(const UniValue& params, bool fRemoveFinishedO #define CTXIN_SPEND_DUST_SIZE 148 #define CTXOUT_REGULAR_SIZE 34 -void random_hex(char str[], int len) -{ - char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - for(int i=0;iMAX_ZOUTS)) { - fprintf(stderr,"%s: Sietch min zouts must be >=%d and <= %d, setting to default value of %d\n", __FUNCTION__, ABSOLUTE_MIN_ZOUTS, MAX_ZOUTS, DEFAULT_MIN_ZOUTS ); + if((MIN_ZOUTS<2) || (MIN_ZOUTS>MAX_ZOUTS)) { + fprintf(stderr,"%s: Sietch min zouts must be >=2 and <= 25, setting to default value of %d\n", __FUNCTION__, DEFAULT_MIN_ZOUTS ); MIN_ZOUTS=DEFAULT_MIN_ZOUTS; } @@ -4748,9 +4739,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk) // OK, we identify this xtn as needing privacy zdust, we must decide how much, non-deterministically int nAmount = 0; int decider = 1 + GetRandInt(100); // random int between 1 and 100 - char *str; - random_hex(str,512); - string memo = string(str); + string memo = "f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + string zdust1, zdust2; // Which zaddr we send to is non-deterministically chosen from two zpools... From 4800f497aa9d7f6a496985ecf4756f0c354bd040 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 17 Jun 2020 22:32:00 -0400 Subject: [PATCH 187/220] Fix copyright --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 11 +++++++++-- src/wallet/asyncrpcoperation_saplingconsolidation.h | 2 +- src/wallet/wallet.cpp | 3 +-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index 477545348..0c6cae7c1 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -95,15 +95,22 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { // an anchor at height N-10 for each SpendDescription // Consider, should notes be sorted? pwalletMain->GetFilteredNotes(saplingEntries, "", 11); + + if(saplingEntries.size() == 0) { + LogPrint("zrpcunsafe", "%s: Nothing to consolidate, done.\n",opid); + return true; + } + if (fConsolidationMapUsed) { const vector& v = mapMultiArgs["-consolidatesaplingaddress"]; for(int i = 0; i < v.size(); i++) { auto zAddress = DecodePaymentAddress(v[i]); if (boost::get(&zAddress) != nullptr) { libzcash::SaplingPaymentAddress saplingAddress = boost::get(zAddress); - addresses.insert(saplingAddress ); + addresses.insert(saplingAddress); } else { - //TODO: how to handle invalid zaddrs? + LogPrint("zrpcunsafe", "%s: Invalid zaddr, exiting\n", opid); + return false; } } } else { diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.h b/src/wallet/asyncrpcoperation_saplingconsolidation.h index 9a80ff7c7..5d14b9335 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.h +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.h @@ -1,5 +1,5 @@ // Copyright (c) 2020 The Hush developers -// TODO: Forge should add his preferred copyright line here +// Copyright (c) 2019 CryptoForge // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b3d759f83..c0f449a56 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1733,8 +1733,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, //fprintf(stderr,"%s: rt=%s\n",__func__,rt.GetHash().ToString().c_str()); //fprintf(stderr,"%s: witnesses[%d]->root()=%s\n",__func__,i,witnesses[i]->root().GetHash().ToString().c_str()); // Something is fucky - std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root! i="; - err += i; + std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root!"; throw std::logic_error(err); } From 9bcf13bf4a7ef40a0a177aee5eb6b0a9a2769f03 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 18 Jun 2020 05:40:04 -0400 Subject: [PATCH 188/220] report invalid roots --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c0f449a56..4581dae00 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1733,7 +1733,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, //fprintf(stderr,"%s: rt=%s\n",__func__,rt.GetHash().ToString().c_str()); //fprintf(stderr,"%s: witnesses[%d]->root()=%s\n",__func__,i,witnesses[i]->root().GetHash().ToString().c_str()); // Something is fucky - std::string err = "CWallet::GetSaplingNoteWitnesses: Invalid witness root!"; + std::string err = std::string("CWallet::GetSaplingNoteWitnesses: Invalid witness root! rt=") + rt.get().ToString(); throw std::logic_error(err); } From a7cd2b375096149f9793a4c5788af237b7b2be68 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 18 Jun 2020 06:41:26 -0400 Subject: [PATCH 189/220] Chill out on the logspam --- src/wallet/wallet.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4581dae00..ae845cb21 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1719,22 +1719,24 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, boost::optional rt; int i = 0; for (SaplingOutPoint note : notes) { - fprintf(stderr,"%s: i=%d\n", __func__,i); + //fprintf(stderr,"%s: i=%d\n", __func__,i); auto noteData = mapWallet[note.hash].mapSaplingNoteData; auto nWitnesses = noteData[note].witnesses.size(); if (mapWallet.count(note.hash) && noteData.count(note) && nWitnesses > 0) { fprintf(stderr,"%s: Found %lu witnesses for note %s\n", __func__, nWitnesses, note.hash.ToString().c_str() ); witnesses[i] = noteData[note].witnesses.front(); if (!rt) { - fprintf(stderr,"%s: Setting witness root\n",__func__); + //fprintf(stderr,"%s: Setting witness root\n",__func__); rt = witnesses[i]->root(); } else { if(*rt == witnesses[i]->root()) { //fprintf(stderr,"%s: rt=%s\n",__func__,rt.GetHash().ToString().c_str()); //fprintf(stderr,"%s: witnesses[%d]->root()=%s\n",__func__,i,witnesses[i]->root().GetHash().ToString().c_str()); // Something is fucky - std::string err = std::string("CWallet::GetSaplingNoteWitnesses: Invalid witness root! rt=") + rt.get().ToString(); - throw std::logic_error(err); + std::string err = string("CWallet::GetSaplingNoteWitnesses: Invalid witness root! rt=") + rt.get().ToString(); + err += string("\n!= witness[i]->root()=") + witnesses[i]->root().ToString(); + //throw std::logic_error(err); + fprintf(stderr,"%s: IGNORING %s\n", __func__,err.c_str()); } } @@ -1744,6 +1746,7 @@ void CWallet::GetSaplingNoteWitnesses(std::vector notes, // All returned witnesses have the same anchor if (rt) { final_anchor = *rt; + //fprintf(stderr,"%s: final_anchor=%s\n", __func__, rt.get().ToString().c_str() ); } } From 8c0faf62efb1eb3b4163d41b6c2e7b4127fbaf86 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 18 Jun 2020 10:06:35 -0400 Subject: [PATCH 190/220] Update build instructions --- INSTALL.md | 6 ++---- README.md | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index c47c6ddfe..bb667b7be 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -39,7 +39,7 @@ sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \ git clone https://github.com/MyHush/hush3.git cd hush3 # Build -./zcutil/build.sh -j$(nproc) +./build.sh -j$(nproc) ``` ## Run a HUSH Node @@ -63,10 +63,8 @@ Downloading Git source repo, building and running Hush: # pull git clone https://github.com/MyHush/hush3.git cd hush -# fetch key -./zcutil/fetch-params.sh # Build -./zcutil/build-win.sh -j$(nproc) +./build-win.sh -j$(nproc) # Run a HUSH node ./src/hushd ``` diff --git a/README.md b/README.md index 1ec5dd7b1..95c8999fe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HUSH 3 +# HUSH ## What is HUSH? From 9db4440ec18d1c558628ecd9e9e6de49df4e50ff Mon Sep 17 00:00:00 2001 From: crackfoo Date: Thu, 18 Jun 2020 14:05:58 -0300 Subject: [PATCH 191/220] Update funcs.mk fix tar permissions/ownership on linux for depends Cheers http://zpool.ca --- depends/funcs.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/funcs.mk b/depends/funcs.mk index 3d89de8a7..5d3939348 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -92,7 +92,7 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source) +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= $(1)_build_cmds ?= $(1)_config_cmds ?= From 920667dd73a64958b9aa8ce26b0938db892dceb6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 23 Jun 2020 12:48:29 -0400 Subject: [PATCH 192/220] Delete tests from ZEC that do not apply to us --- src/Makefile.gtest.include | 4 +- src/gtest/test_foundersreward.cpp | 194 ------------------------------ 2 files changed, 2 insertions(+), 196 deletions(-) delete mode 100644 src/gtest/test_foundersreward.cpp diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 1f1b511db..66105ca70 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -1,4 +1,5 @@ - +# Copyright (c) 2019-2020 Hush developers +# Released under the GPLv3 TESTS += komodo-gtest bin_PROGRAMS += komodo-gtest @@ -9,7 +10,6 @@ komodo_gtest_SOURCES = \ gtest/test_checktransaction.cpp \ gtest/json_test_vectors.cpp \ gtest/json_test_vectors.h \ - # gtest/test_foundersreward.cpp \ gtest/test_wallet_zkeys.cpp \ # These tests are order-dependent, because they # depend on global state (see #1539) diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp deleted file mode 100644 index 7e5a3cf05..000000000 --- a/src/gtest/test_foundersreward.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include - -#include "main.h" -#include "utilmoneystr.h" -#include "chainparams.h" -#include "utilstrencodings.h" -#include "zcash/Address.hpp" -#include "wallet/wallet.h" -#include "amount.h" -#include -#include -#include -#include -#include -#include "util.h" - -#ifndef disable_founders -// To run tests: -// ./zcash-gtest --gtest_filter="founders_reward_test.*" - -// -// Enable this test to generate and print 48 testnet 2-of-3 multisig addresses. -// The output can be copied into chainparams.cpp. -// The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd. -// -#if 0 -TEST(founders_reward_test, create_testnet_2of3multisig) { - SelectParams(CBaseChainParams::TESTNET); - boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); - boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); - bool fFirstRun; - auto pWallet = std::make_shared("wallet.dat"); - ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); - pWallet->TopUpKeyPool(); - std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl; - - int numKeys = 48; - std::vector pubkeys; - pubkeys.resize(3); - CPubKey newKey; - std::vector addresses; - for (int i = 0; i < numKeys; i++) { - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[0] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[1] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); - pubkeys[2] = newKey; - pWallet->SetAddressBook(newKey.GetID(), "", "receive"); - - CScript result = GetScriptForMultisig(2, pubkeys); - ASSERT_FALSE(result.size() > MAX_SCRIPT_ELEMENT_SIZE); - CScriptID innerID(result); - pWallet->AddCScript(result); - pWallet->SetAddressBook(innerID, "", "receive"); - - std::string address = EncodeDestination(innerID); - addresses.push_back(address); - } - - // Print out the addresses, 4 on each line. - std::string s = "vFoundersRewardAddress = {\n"; - int i=0; - int colsPerRow = 4; - ASSERT_TRUE(numKeys % colsPerRow == 0); - int numRows = numKeys/colsPerRow; - for (int row=0; rowFlush(true); -} -#endif - - -// Utility method to check the number of unique addresses from height 1 to maxHeight -void checkNumberOfUniqueAddresses(int nUnique) { - int maxHeight = Params().GetConsensus().GetLastFoundersRewardBlockHeight(); - std::set addresses; - for (int i = 1; i <= maxHeight; i++) { - addresses.insert(Params().GetFoundersRewardAddressAtHeight(i)); - } - ASSERT_TRUE(addresses.size() == nUnique); -} - - -TEST(founders_reward_test, general) { - SelectParams(CBaseChainParams::TESTNET); - - CChainParams params = Params(); - - // Fourth testnet reward: - // address = t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy - // script.ToString() = OP_HASH160 55d64928e69829d9376c776550b6cc710d427153 OP_EQUAL - // HexStr(script) = a91455d64928e69829d9376c776550b6cc710d42715387 - EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(1)), "a914ef775f1f997f122a062fff1a2d7443abd1f9c64287"); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi"); - EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53126)), "a914ac67f4c072668138d88a86ff21b27207b283212f87"); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53126), "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2"); - EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53127)), "a91455d64928e69829d9376c776550b6cc710d42715387"); - EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53127), "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy"); - - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - - // If the block height parameter is out of bounds, there is an assert. - EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(0), "nHeight"); - EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(maxHeight+1), "nHeight"); - EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(0), "nHeight"); - EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight"); -} - - -#define NUM_MAINNET_FOUNDER_ADDRESSES 48 - -TEST(founders_reward_test, mainnet) { - SelectParams(CBaseChainParams::MAIN); - checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES); -} - - -#define NUM_TESTNET_FOUNDER_ADDRESSES 48 - -TEST(founders_reward_test, testnet) { - SelectParams(CBaseChainParams::TESTNET); - checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES); -} - - -#define NUM_REGTEST_FOUNDER_ADDRESSES 1 - -TEST(founders_reward_test, regtest) { - SelectParams(CBaseChainParams::REGTEST); - checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES); -} - - - -// Test that 10% founders reward is fully rewarded after the first halving and slow start shift. -// On Mainnet, this would be 2,100,000 ZEC after 850,000 blocks (840,000 + 10,000). -TEST(founders_reward_test, slow_start_subsidy) { - SelectParams(CBaseChainParams::MAIN); - CChainParams params = Params(); - - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - CAmount totalSubsidy = 0; - for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; - totalSubsidy += nSubsidy; - } - - ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); -} - - -// For use with mainnet and testnet which each have 48 addresses. -// Verify the number of rewards each individual address receives. -void verifyNumberOfRewards() { - CChainParams params = Params(); - int maxHeight = params.GetConsensus().GetLastFoundersRewardBlockHeight(); - std::multiset ms; - for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { - ms.insert(params.GetFoundersRewardAddressAtHeight(nHeight)); - } - - ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(0)) == 17708); - for (int i = 1; i <= 46; i++) { - ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(i)) == 17709); - } - ASSERT_TRUE(ms.count(params.GetFoundersRewardAddressAtIndex(47)) == 17677); -} - -// Verify the number of rewards going to each mainnet address -TEST(founders_reward_test, per_address_reward_mainnet) { - SelectParams(CBaseChainParams::MAIN); - verifyNumberOfRewards(); -} - -// Verify the number of rewards going to each testnet address -TEST(founders_reward_test, per_address_reward_testnet) { - SelectParams(CBaseChainParams::TESTNET); - verifyNumberOfRewards(); -} -#endif From f03a7b0e7e5ebc87f999376b7ba3df1b10ea81b9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 23 Jun 2020 12:48:36 -0400 Subject: [PATCH 193/220] Copyright --- src/hush-cli | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hush-cli b/src/hush-cli index bf4511073..9cc47207a 100755 --- a/src/hush-cli +++ b/src/hush-cli @@ -1,5 +1,6 @@ #!/bin/bash -# Copyright (c) 2019 Hush developers +# Copyright (c) 2019-2020 Hush developers +# Released under the GPLv3 # set working directory to the location of this script # readlink -f does not always exist From 828fff6168b4ddce5d430294864136dbe8747ad1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 23 Jun 2020 12:59:32 -0400 Subject: [PATCH 194/220] Update some tests --- qa/hush/full_test_suite.py | 30 ++++++++++++++++-------------- src/hush-tx | 3 ++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/qa/hush/full_test_suite.py b/qa/hush/full_test_suite.py index fcbdf0cd8..deee55881 100755 --- a/qa/hush/full_test_suite.py +++ b/qa/hush/full_test_suite.py @@ -1,6 +1,8 @@ #!/usr/bin/env python2 +# Copyright (c) 2019-2020 Hush developers +# Released under the GPLv3 # -# Execute all of the automated tests related to Zcash. +# Execute all of the automated tests related to Hush # import argparse @@ -32,7 +34,7 @@ RE_FORTIFY_USED = re.compile('Binary compiled with FORTIFY_SOURCE support.*Yes') def test_rpath_runpath(filename): output = subprocess.check_output( - [repofile('qa/zcash/checksec.sh'), '--file', repofile(filename)] + [repofile('qa/hush/checksec.sh'), '--file', repofile(filename)] ) if RE_RPATH_RUNPATH.search(output): print('PASS: %s has no RPATH or RUNPATH.' % filename) @@ -44,7 +46,7 @@ def test_rpath_runpath(filename): def test_fortify_source(filename): proc = subprocess.Popen( - [repofile('qa/zcash/checksec.sh'), '--fortify-file', repofile(filename)], + [repofile('qa/hush/checksec.sh'), '--fortify-file', repofile(filename)], stdout=subprocess.PIPE, ) line1 = proc.stdout.readline() @@ -64,24 +66,24 @@ def check_security_hardening(): ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 # The remaining checks are only for ELF binaries - # Assume that if zcashd is an ELF binary, they all are - with open(repofile('src/zcashd'), 'rb') as f: + # Assume that if hushd is an ELF binary, they all are + with open(repofile('src/hushd'), 'rb') as f: magic = f.read(4) if not magic.startswith(b'\x7fELF'): return ret - ret &= test_rpath_runpath('src/zcashd') - ret &= test_rpath_runpath('src/zcash-cli') - ret &= test_rpath_runpath('src/zcash-gtest') - ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/hushd') + ret &= test_rpath_runpath('src/hush-cli') + ret &= test_rpath_runpath('src/hush-gtest') + ret &= test_rpath_runpath('src/hush-tx') ret &= test_rpath_runpath('src/test/test_bitcoin') # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE # is enabled for the entire binary. See issue #915. - ret &= test_fortify_source('src/zcashd') - ret &= test_fortify_source('src/zcash-cli') - ret &= test_fortify_source('src/zcash-gtest') - ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/hushd') + ret &= test_fortify_source('src/hush-cli') + ret &= test_fortify_source('src/hush-gtest') + ret &= test_fortify_source('src/hush-tx') ret &= test_fortify_source('src/test/test_bitcoin') return ret @@ -144,7 +146,7 @@ STAGES = [ STAGE_COMMANDS = { 'btest': [repofile('src/test/test_bitcoin'), '-p'], - 'gtest': [repofile('src/zcash-gtest')], + 'gtest': [repofile('src/komodo-gtest')], 'sec-hard': check_security_hardening, 'no-dot-so': ensure_no_dot_so_in_depends, 'util-test': util_test, diff --git a/src/hush-tx b/src/hush-tx index 2152315ad..17f8bc6b8 100755 --- a/src/hush-tx +++ b/src/hush-tx @@ -1,5 +1,6 @@ #!/bin/bash -# Copyright (c) 2019 Hush developers +# Copyright (c) 2019-2020 Hush developers +# Released under the GPLv3 # set working directory to the location of this script DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" From 2cf9b80b8c98ebc008993f3d618d96e687940389 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 24 Jun 2020 17:56:50 -0400 Subject: [PATCH 195/220] cleanup --- src/main.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index fb53e2c28..f7e3fb74e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3976,33 +3976,6 @@ void static UpdateTip(CBlockIndex *pindexNew) { pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); cvBlockChange.notify_all(); - - /* - // https://github.com/zcash/zcash/issues/3992 -> https://github.com/zcash/zcash/commit/346d11d3eb2f8162df0cb00b1d1f49d542495198 - - // Check the version of the last 100 blocks to see if we need to upgrade: - static bool fWarned = false; - if (!IsInitialBlockDownload() && !fWarned) - { - int nUpgraded = 0; - const CBlockIndex* pindex = chainActive.Tip(); - for (int i = 0; i < 100 && pindex != NULL; i++) - { - if (pindex->nVersion > CBlock::CURRENT_VERSION) - ++nUpgraded; - pindex = pindex->pprev; - } - if (nUpgraded > 0) - LogPrintf("%s: %d of last 100 blocks above version %d\n", __func__, nUpgraded, (int)CBlock::CURRENT_VERSION); - if (nUpgraded > 100/2) - { - // strMiscWarning is read by GetWarnings(), called by the JSON-RPC code to warn the user: - strMiscWarning = _("Warning: This version is obsolete; upgrade required!"); - CAlert::Notify(strMiscWarning, true); - fWarned = true; - } - } - */ } /** From e4d2ada7282b36921a9b460fc8fa8e5d01b1d104 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 24 Jun 2020 17:58:03 -0400 Subject: [PATCH 196/220] formatting --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f7e3fb74e..73f49eb38 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3964,8 +3964,8 @@ void static UpdateTip(CBlockIndex *pindexNew) { if ( ASSETCHAINS_SYMBOL[0] == 0 ) { progress = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip()); } else { - int32_t longestchain = komodo_longestchain(); - progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; + int32_t longestchain = komodo_longestchain(); + progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; } LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, From bb6565d9661e2405f6ff543ef5256bc8932709f3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 24 Jun 2020 20:49:53 -0400 Subject: [PATCH 197/220] Block time halving at height 340000 --- src/main.cpp | 22 ++++++++++++++++++---- src/pow.cpp | 5 ++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 73f49eb38..5b70ed2fd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3350,6 +3350,8 @@ static int64_t nTimeTotal = 0; bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false); bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); +int32_t nFirstHalvingHeight = 340000; + bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW) { CDiskBlockPos blockPos; @@ -3362,15 +3364,20 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin AssertLockHeld(cs_main); bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; + + // At startup, HUSH3 doesn't know a block height yet and so we must wait until + // connecting a block to set our private/blocktime flags, which are height-dependent if(!ASSETCHAINS_PRIVATE && ishush3) { unsigned int nHeight = pindex->GetHeight(); - if(nHeight >= 340000) { - // At startup, HUSH3 doesn't know a block height yet and so we must wait until - // connecting a block - fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,nHeight); + if(nHeight >= nFirstHalvingHeight) { + fprintf(stderr, "%s: Going full z2z at height %d!\n",__func__,pindex->GetHeight()); ASSETCHAINS_PRIVATE = 1; } } + if (ishush3 && (ASSETCHAINS_BLOCKTIME != 75) && (chainActive.Height() >= nFirstHalvingHeight)) { + LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,pindex->GetHeight()); + ASSETCHAINS_BLOCKTIME = 75; + } bool fExpensiveChecks = true; if (fCheckpointsEnabled) { @@ -3968,6 +3975,13 @@ void static UpdateTip(CBlockIndex *pindexNew) { progress = (longestchain > 0 ) ? (double) chainActive.Height() / longestchain : 1.0; } + if(ishush3) { + if (ASSETCHAINS_BLOCKTIME != 75 && (chainActive.Height() >= nFirstHalvingHeight)) { + LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,chainActive.Height()); + ASSETCHAINS_BLOCKTIME = 75; + } + } + LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%.1fMiB(%utx)\n", __func__, chainActive.LastTip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->chainPower.chainWork.getdouble())/log(2.0), diff --git a/src/pow.cpp b/src/pow.cpp index 79c41feb4..6d0262699 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -298,6 +298,9 @@ arith_uint256 zawy_TSA_EMA(int32_t height,int32_t tipdiff,arith_uint256 prevTarg unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { + if (pindexLast->GetHeight() == 340000) { + LogPrintf("%s: Using blocktime=%d\n",__func__,ASSETCHAINS_BLOCKTIME); + } if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH && ASSETCHAINS_STAKED == 0) return lwmaGetNextWorkRequired(pindexLast, pblock, params); From eb935e3c93c98fba5ca0f37dc0fbc4e7b8aee816 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 9 Jul 2020 07:22:33 -0400 Subject: [PATCH 198/220] Set correct blocktime when disconnecting a block and rewinding before our block time halving --- src/main.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 5b70ed2fd..2681723c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,6 +115,7 @@ bool fAlerts = DEFAULT_ALERTS; */ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; bool ishush3 = strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ? true : false; +int32_t nFirstHalvingHeight = 340000; unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -3227,6 +3228,15 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex // move best block pointer to prevout block view.SetBestBlock(pindex->pprev->GetBlockHash()); + // If disconnecting a block brings us back before our blocktime halving height, go back + // to our original blocktime so our DAA has the correct target for that height + int nHeight = pindex->pprev->GetHeight(); + if (ishush3 && (ASSETCHAINS_BLOCKTIME != 150) && (nHeight < nFirstHalvingHeight)) { + LogPrintf("%s: Setting blocktime to 150s at height %d!\n",__func__,nHeight); + ASSETCHAINS_BLOCKTIME = 150; + } + + if (pfClean) { *pfClean = fClean; return true; @@ -3350,7 +3360,6 @@ static int64_t nTimeTotal = 0; bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false); bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); -int32_t nFirstHalvingHeight = 340000; bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck,bool fCheckPOW) { From e959ea976839041c0d287b7f3e865754596fc1e9 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 9 Jul 2020 08:35:04 -0400 Subject: [PATCH 199/220] Timedata changes from KMD 0.6 --- src/timedata.cpp | 149 +++++++++++++++-------------------------------- src/timedata.h | 78 +++++++------------------ 2 files changed, 66 insertions(+), 161 deletions(-) diff --git a/src/timedata.cpp b/src/timedata.cpp index 64a3955ff..246159a50 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,10 +1,11 @@ // Copyright (c) 2014 The Bitcoin Core developers // Copyright (c) 2019-2020 The Hush developers +// Copyright (c) 2020 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** - * Copyright © 2014-2019 The SuperNET Developers. * + * Copyright © 2014-2020 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -26,114 +27,56 @@ #include "util.h" #include "utilstrencodings.h" -#include - -using namespace std; - -static CCriticalSection cs_nTimeOffset; -static int64_t nTimeOffset = 0; -#define KOMODO_ASSETCHAIN_MAXLEN 65 -extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; +CTimeWarning timeWarning; /** - * "Never go to sea with two chronometers; take one or three." - * Our three time sources are: - * - System clock - * - Median of other nodes clocks - * - The user (asking the user to fix the system clock if the first two disagree) + * Warn if we have seen TIMEDATA_WARNING_SAMPLES peer times, in the version messages of the + * first TIMEDATA_MAX_SAMPLES unique (by IP address) peers that connect, that are more than + * TIMEDATA_WARNING_THRESHOLD seconds but less than TIMEDATA_IGNORE_THRESHOLD seconds away + * from local time. */ -int64_t GetTimeOffset() + +int64_t CTimeWarning::AddTimeData(const CNetAddr& ip, int64_t nTime, int64_t now) { - LOCK(cs_nTimeOffset); + assert(now >= 0 && now <= INT64_MAX - TIMEDATA_IGNORE_THRESHOLD); + + if (nTime <= now - TIMEDATA_IGNORE_THRESHOLD || nTime >= now + TIMEDATA_IGNORE_THRESHOLD) { + return 0; + } + + int64_t nTimeOffset = nTime - now; + + LOCK(cs); + // Ignore duplicate IPs. + if (setKnown.size() == TIMEDATA_MAX_SAMPLES || !setKnown.insert(ip).second) { + return nTimeOffset; + } + + LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", setKnown.size(), nTimeOffset, nTimeOffset/60); + + if (nPeersBehind + nPeersAhead < TIMEDATA_WARNING_SAMPLES) { + if (nTimeOffset < -TIMEDATA_WARNING_THRESHOLD) { + nPeersBehind++; + } else if (nTimeOffset > TIMEDATA_WARNING_THRESHOLD) { + nPeersAhead++; + } + if (nPeersBehind + nPeersAhead == TIMEDATA_WARNING_SAMPLES) { + Warn(nPeersAhead, nPeersBehind); + } + } return nTimeOffset; } -int64_t GetAdjustedTime() +void CTimeWarning::Warn(size_t peersAhead, size_t peersBehind) { - return GetTime() + GetTimeOffset(); -} - -static int64_t abs64(int64_t n) -{ - return (n >= 0 ? n : -n); -} - -#define BITCOIN_TIMEDATA_MAX_SAMPLES 200 - -void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) -{ - LOCK(cs_nTimeOffset); - // Ignore duplicates - static set setKnown; - if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES) - return; - if (!setKnown.insert(ip).second) - return; - - // Add data - static CMedianFilter vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0); - vTimeOffsets.input(nOffsetSample); - LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); - - // There is a known issue here (see issue #4521): - // - // - The structure vTimeOffsets contains up to 200 elements, after which - // any new element added to it will not increase its size, replacing the - // oldest element. - // - // - The condition to update nTimeOffset includes checking whether the - // number of elements in vTimeOffsets is odd, which will never happen after - // there are 200 elements. - // - // But in this case the 'bug' is protective against some attacks, and may - // actually explain why we've never seen attacks which manipulate the - // clock offset. - // - // So we should hold off on fixing this and clean it up as part of - // a timing cleanup that strengthens it in a number of other ways. - // - if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) - { - int64_t nMedian = vTimeOffsets.median(); - std::vector vSorted = vTimeOffsets.sorted(); - // Only let other nodes change our time by so much - if (abs64(nMedian) < 30) // thanks to zawy for pointing this out!! zcash issues 4021 //70 * 60) - { - nTimeOffset = nMedian; - } - else - { - nTimeOffset = 0; - - static bool fDone; - if (!fDone) - { - // If nobody has a time different than ours but within 5 minutes of ours, give a warning - bool fMatch = false; - BOOST_FOREACH(int64_t nOffset, vSorted) - if (nOffset != 0 && abs64(nOffset) < 5 * 60) - fMatch = true; - - if (!fMatch) - { - fDone = true; - string strMessage; - if( strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ) { - strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Hush will not work properly."); - } else { - strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Komodo will not work properly."); - } - strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); - } - } - } - if (fDebug) { - BOOST_FOREACH(int64_t n, vSorted) - LogPrintf("%+d ", n); - LogPrintf("| "); - } - LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); + std::string strMessage; + if (peersBehind >= TIMEDATA_WARNING_MAJORITY) { + strMessage = _("Warning: Your computer's date and time may be ahead of the rest of the network! If your clock is wrong Hush will not work properly."); + } else if (peersAhead >= TIMEDATA_WARNING_MAJORITY) { + strMessage = _("Warning: Your computer's date and time may be behind the rest of the network! If your clock is wrong Hush will not work properly."); + } else { + strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Hush will not work properly."); } + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); } diff --git a/src/timedata.h b/src/timedata.h index 13cff12b3..4ced093b6 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,77 +1,39 @@ // Copyright (c) 2014 The Bitcoin Core developers // Copyright (c) 2019-2020 The Hush developers +// Copyright (c) 2020 The Zcash developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php #ifndef BITCOIN_TIMEDATA_H #define BITCOIN_TIMEDATA_H -#include -#include +#include #include -#include +#include "netbase.h" +#include "sync.h" -class CNetAddr; - -/** - * Median filter over a stream of values. - * Returns the median of the last N numbers - */ -template -class CMedianFilter +class CTimeWarning { private: - std::vector vValues; - std::vector vSorted; - unsigned int nSize; + CCriticalSection cs; + std::set setKnown; + size_t nPeersAhead; + size_t nPeersBehind; public: - CMedianFilter(unsigned int size, T initial_value) : nSize(size) - { - vValues.reserve(size); - vValues.push_back(initial_value); - vSorted = vValues; - } + static const size_t TIMEDATA_WARNING_SAMPLES = 8; + static const size_t TIMEDATA_WARNING_MAJORITY = 6; + static const size_t TIMEDATA_MAX_SAMPLES = 20; + static const int64_t TIMEDATA_WARNING_THRESHOLD = 10 * 60; + static const int64_t TIMEDATA_IGNORE_THRESHOLD = 10 * 24 * 60 * 60; - void input(T value) - { - if (vValues.size() == nSize) { - vValues.erase(vValues.begin()); - } - vValues.push_back(value); + CTimeWarning() : nPeersBehind(0), nPeersAhead(0) {} + virtual ~CTimeWarning() {} - vSorted.resize(vValues.size()); - std::copy(vValues.begin(), vValues.end(), vSorted.begin()); - std::sort(vSorted.begin(), vSorted.end()); - } - - T median() const - { - int size = vSorted.size(); - assert(size > 0); - if (size & 1) // Odd number of elements - { - return vSorted[size / 2]; - } else // Even number of elements - { - return (vSorted[size / 2 - 1] + vSorted[size / 2]) / 2; - } - } - - int size() const - { - return vValues.size(); - } - - std::vector sorted() const - { - return vSorted; - } + int64_t AddTimeData(const CNetAddr& ip, int64_t nTime, int64_t now); + virtual void Warn(size_t peersAhead, size_t peersBehind); }; -/** Functions to keep track of adjusted P2P time */ -int64_t GetTimeOffset(); -int64_t GetAdjustedTime(); -void AddTimeData(const CNetAddr& ip, int64_t nTime); +extern CTimeWarning timeWarning; #endif // BITCOIN_TIMEDATA_H From d4883bce7c94499fee425ebe472d1b6d9ce36d25 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 9 Jul 2020 10:31:12 -0400 Subject: [PATCH 200/220] More timedate changes from KMD 0.6 --- src/addrman.cpp | 3 ++- src/addrman.h | 13 +++++++------ src/alert.cpp | 7 ++++--- src/komodo_bitcoind.h | 4 ++-- src/main.cpp | 39 +++++++++++++++++++------------------- src/miner.cpp | 28 +++++++++++++-------------- src/net.cpp | 10 +++++----- src/rpc/misc.cpp | 4 ++-- src/rpc/net.cpp | 11 ++++++----- src/test/addrman_tests.cpp | 12 ++++++------ src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 15 +++++++-------- 12 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/addrman.cpp b/src/addrman.cpp index 1c8bf4b7c..3ff108c44 100644 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2012 Pieter Wuille +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -268,7 +269,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP if (pinfo) { // periodically update nTime - bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60); + bool fCurrentlyOnline = (GetTime() - addr.nTime < 24 * 60 * 60); int64_t nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); if (addr.nTime && (!pinfo->nTime || pinfo->nTime < addr.nTime - nUpdateInterval - nTimePenalty)) pinfo->nTime = std::max((int64_t)0, addr.nTime - nTimePenalty); diff --git a/src/addrman.h b/src/addrman.h index 0390b4e9b..b23ab5aa3 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -1,6 +1,7 @@ // Copyright (c) 2012 Pieter Wuille +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -112,10 +113,10 @@ public: int GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const; //! Determine whether the statistics about this entry are bad enough so that it can just be deleted - bool IsTerrible(int64_t nNow = GetAdjustedTime()) const; + bool IsTerrible(int64_t nNow = GetTime()) const; //! Calculate the relative chance this entry should be given when selecting nodes to connect to - double GetChance(int64_t nNow = GetAdjustedTime()) const; + double GetChance(int64_t nNow = GetTime()) const; }; @@ -530,7 +531,7 @@ public: } //! Mark an entry as accessible. - void Good(const CService &addr, int64_t nTime = GetAdjustedTime()) + void Good(const CService &addr, int64_t nTime = GetTime()) { { LOCK(cs); @@ -541,7 +542,7 @@ public: } //! Mark an entry as connection attempted to. - void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime()) + void Attempt(const CService &addr, int64_t nTime = GetTime()) { { LOCK(cs); @@ -580,7 +581,7 @@ public: } //! Mark an entry as currently-connected-to. - void Connected(const CService &addr, int64_t nTime = GetAdjustedTime()) + void Connected(const CService &addr, int64_t nTime = GetTime()) { { LOCK(cs); diff --git a/src/alert.cpp b/src/alert.cpp index 99f6472e9..db70cd620 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -1,7 +1,8 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -117,7 +118,7 @@ uint256 CAlert::GetHash() const bool CAlert::IsInEffect() const { - return (GetAdjustedTime() < nExpiration); + return (GetTime() < nExpiration); } bool CAlert::Cancels(const CAlert& alert) const @@ -152,7 +153,7 @@ bool CAlert::RelayTo(CNode* pnode) const { if (AppliesTo(pnode->nVersion, pnode->strSubVer) || AppliesToMe() || - GetAdjustedTime() < nRelayUntil) + GetTime() < nRelayUntil) { pnode->PushMessage("alert", *this); return true; diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e1748c191..930d7ddf8 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1535,8 +1535,8 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh //fprintf(stderr,"blocktime.%u -> ",blocktime); if ( blocktime < prevtime+3 ) blocktime = prevtime+3; - if ( blocktime < GetAdjustedTime()-60 ) - blocktime = GetAdjustedTime()+30; + if ( blocktime < GetTime()-60 ) + blocktime = GetTime()+30; //fprintf(stderr,"blocktime.%u txtime.%u\n",blocktime,txtime); } if ( value == 0 || txtime == 0 || blocktime == 0 || prevtime == 0 ) diff --git a/src/main.cpp b/src/main.cpp index 2681723c9..ea7fa7a1f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1000,7 +1000,7 @@ bool CheckFinalTx(const CTransaction &tx, int flags) // However this changes once median past time-locks are enforced: const int64_t nBlockTime = (flags & LOCKTIME_MEDIAN_TIME_PAST) ? chainActive.Tip()->GetMedianTimePast() - : GetAdjustedTime(); + : GetTime(); return IsFinalTx(tx, nBlockHeight, nBlockTime); } @@ -3297,7 +3297,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const if (bestHeader == NULL || initialDownloadCheck()) return; static int64_t lastAlertTime = 0; - int64_t now = GetAdjustedTime(); + int64_t now = GetTime(); if (lastAlertTime > now-60*60*24) return; // Alert at most once per day const int SPAN_HOURS=4; @@ -3307,7 +3307,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const boost::math::poisson_distribution poisson(BLOCKS_EXPECTED); std::string strWarning; - int64_t startTime = GetAdjustedTime()-SPAN_SECONDS; + int64_t startTime = GetTime()-SPAN_SECONDS; LOCK(cs); const CBlockIndex* i = bestHeader; @@ -5119,28 +5119,28 @@ bool CheckBlockHeader(int32_t *futureblockp,int32_t height,CBlockIndex *pindex, *futureblockp = 0; if ( ASSETCHAINS_ADAPTIVEPOW > 0 ) { - if (blockhdr.GetBlockTime() > GetAdjustedTime() + 4) + if (blockhdr.GetBlockTime() > GetTime() + 4) { - //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime()); + //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetTime()); return false; } } - else if (blockhdr.GetBlockTime() > GetAdjustedTime() + 60) + else if (blockhdr.GetBlockTime() > GetTime() + 60) { /*CBlockIndex *tipindex; - //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetAdjustedTime()); - if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetAdjustedTime() + 60 + 5 ) + //fprintf(stderr,"ht.%d future block %u vs time.%u + 60\n",height,(uint32_t)blockhdr.GetBlockTime(),(uint32_t)GetTime()); + if ( (tipindex= chainActive.Tip()) != 0 && tipindex->GetBlockHash() == blockhdr.hashPrevBlock && blockhdr.GetBlockTime() < GetTime() + 60 + 5 ) { - //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetAdjustedTime() + 60 - blockhdr.GetBlockTime()); - while ( blockhdr.GetBlockTime() > GetAdjustedTime() + 60 ) + //fprintf(stderr,"it is the next block, let's wait for %d seconds\n",GetTime() + 60 - blockhdr.GetBlockTime()); + while ( blockhdr.GetBlockTime() > GetTime() + 60 ) sleep(1); //fprintf(stderr,"now its valid\n"); } else*/ { - if (blockhdr.GetBlockTime() < GetAdjustedTime() + 300) + if (blockhdr.GetBlockTime() < GetTime() + 300) *futureblockp = 1; - //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetAdjustedTime()); + //LogPrintf("CheckBlockHeader block from future %d error",blockhdr.GetBlockTime() - GetTime()); return false; //state.Invalid(error("CheckBlockHeader(): block timestamp too far in the future"),REJECT_INVALID, "time-too-new"); } } @@ -5388,7 +5388,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta } // Check that timestamp is not too far in the future - if (block.GetBlockTime() > GetAdjustedTime() + consensusParams.nMaxFutureBlockTime) + if (block.GetBlockTime() > GetTime() + consensusParams.nMaxFutureBlockTime) { return state.Invalid(error("%s: block timestamp too far in the future", __func__), REJECT_INVALID, "time-too-new"); @@ -7406,9 +7406,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, remoteAddr); - int64_t nTimeOffset = nTime - GetTime(); - pfrom->nTimeOffset = nTimeOffset; - AddTimeData(pfrom->addr, nTimeOffset); + //int64_t nTimeOffset = nTime - GetTime(); + //pfrom->nTimeOffset = nTimeOffset; + //AddTimeData(pfrom->addr, nTimeOffset); + pfrom->nTimeOffset = timeWarning.AddTimeData(pfrom->addr, nTime, GetTime()); } @@ -7484,7 +7485,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Store the new addresses vector vAddrOk; - int64_t nNow = GetAdjustedTime(); + int64_t nNow = GetTime(); int64_t nSince = nNow - 10 * 60; BOOST_FOREACH(CAddress& addr, vAddr) { @@ -7694,7 +7695,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // not a direct successor. pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && + if (chainActive.Tip()->GetBlockTime() > GetTime() - chainparams.GetConsensus().nPowTargetSpacing * 20 && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { vToFetch.push_back(inv); // Mark block as in flight already, even though the actual "getdata" message only goes out @@ -8457,7 +8458,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && pindexBestHeader!=0) { // Only actively request headers from a single peer, unless we're close to today. - if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { + if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetTime() - 24 * 60 * 60) { state.fSyncStarted = true; nSyncStarted++; CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; diff --git a/src/miner.cpp b/src/miner.cpp index a91fa9527..4ab19638b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1,8 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -126,8 +126,8 @@ extern int8_t ASSETCHAINS_ADAPTIVEPOW; void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) - pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - else pblock->nTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime()); + pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); + else pblock->nTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime()); // Updating time can change work required on testnet: if (ASSETCHAINS_ADAPTIVEPOW > 0 || consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) @@ -239,7 +239,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); - uint32_t proposedTime = GetAdjustedTime(); + uint32_t proposedTime = GetTime(); voutsum = GetBlockSubsidy(nHeight,consensusParams) + 10000*COIN; // approx fees if (proposedTime == nMedianTimePast) @@ -248,12 +248,12 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 // forward as quickly as possible for (int i; i < 100; i++) { - proposedTime = GetAdjustedTime(); + proposedTime = GetTime(); if (proposedTime == nMedianTimePast) MilliSleep(10); } } - pblock->nTime = GetAdjustedTime(); + pblock->nTime = GetTime(); // Now we have the block time + height, we can get the active notaries. int8_t numSN = 0; uint8_t notarypubkeys[64][33] = {0}; if ( ASSETCHAINS_NOTARY_PAY[0] != 0 ) @@ -603,8 +603,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) - blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime()); + blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); + else blocktime = 1 + std::max((int64_t)(pindexPrev->nTime+1), GetTime()); //pblock->nTime = blocktime + 1; pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); @@ -624,8 +624,8 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 //fprintf(stderr,"mine ht.%d with %.8f\n",nHeight,(double)txNew.vout[0].nValue/COIN); txNew.nExpiryHeight = 0; if ( ASSETCHAINS_ADAPTIVEPOW <= 0 ) - txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetAdjustedTime()); + txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetTime()); + else txNew.nLockTime = std::max((int64_t)(pindexPrev->nTime+1), GetTime()); if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 ) @@ -1368,10 +1368,10 @@ void static BitcoinMiner() // MilliSleep(30); return false; } - if ( IS_KOMODO_NOTARY != 0 && B.nTime > GetAdjustedTime() ) + if ( IS_KOMODO_NOTARY != 0 && B.nTime > GetTime() ) { - //fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetAdjustedTime())); - while ( GetAdjustedTime() < B.nTime-2 ) + //fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetTime())); + while ( GetTime() < B.nTime-2 ) { sleep(1); if ( chainActive.LastTip()->GetHeight() >= Mining_height ) diff --git a/src/net.cpp b/src/net.cpp index efb69bfe9..5be64b291 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -193,7 +193,7 @@ CAddress GetLocalAddress(const CNetAddr *paddrPeer) ret = CAddress(addr); } ret.nServices = nLocalServices; - ret.nTime = GetAdjustedTime(); + ret.nTime = GetTime(); return ret; } @@ -393,7 +393,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) /// debug print LogPrint("net", "trying connection %s lastseen=%.1fhrs\n", pszDest ? pszDest : addrConnect.ToString(), - pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); + pszDest ? 0.0 : (double)(GetTime() - addrConnect.nTime)/3600.0); // Connect SOCKET hSocket; @@ -458,7 +458,7 @@ void CNode::PushVersion() { int nBestHeight = g_signals.GetHeight().get_value_or(0); - int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime()); + int64_t nTime = (fInbound ? GetTime() : GetTime()); CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0))); CAddress addrMe = GetLocalAddress(&addr); GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); @@ -1429,7 +1429,7 @@ void ThreadOpenConnections() } } - int64_t nANow = GetAdjustedTime(); + int64_t nANow = GetTime(); int nTries = 0; while (true) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index a41a8169d..d741a9748 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -206,7 +206,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"walletversion\": xxxxx, (numeric) the wallet version\n" " \"balance\": xxxxxxx, (numeric) the total Hush balance of the wallet\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" - " \"timeoffset\": xxxxx, (numeric) the time offset\n" + " \"timeoffset\": xxxxx, (numeric) the time offset (deprecated, always 0)\n" " \"connections\": xxxxx, (numeric) the number of connections\n" " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" @@ -286,7 +286,7 @@ UniValue getinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) #endif obj.push_back(Pair("sapling", ASSETCHAINS_SAPLING)); } - obj.push_back(Pair("timeoffset", GetTimeOffset())); + obj.push_back(Pair("timeoffset", 0)); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()))); obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 39e080d86..c93f6a409 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * @@ -108,7 +109,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"bytessent\": n, (numeric) The total bytes sent\n" " \"bytesrecv\": n, (numeric) The total bytes received\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" - " \"timeoffset\": ttt, (numeric) The time offset in seconds\n" + " \"timeoffset\": ttt, (numeric) The time offset in seconds (deprecated, always 0)\n" " \"pingtime\": n, (numeric) ping time\n" " \"pingwait\": n, (numeric) ping wait\n" " \"version\": v, (numeric) The peer version, such as 170002\n" @@ -151,7 +152,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("bytessent", stats.nSendBytes)); obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); obj.push_back(Pair("conntime", stats.nTimeConnected)); - obj.push_back(Pair("timeoffset", stats.nTimeOffset)); + obj.push_back(Pair("timeoffset", 0)); obj.push_back(Pair("pingtime", stats.dPingTime)); if (stats.dPingWait > 0.0) obj.push_back(Pair("pingwait", stats.dPingWait)); @@ -502,7 +503,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n" - " \"timeoffset\": xxxxx, (numeric) the time offset\n" + " \"timeoffset\": xxxxx, (numeric) the time offset (deprecated, always 0)\n" " \"connections\": xxxxx, (numeric) the number of connections\n" " \"networks\": [ (array) information per network\n" " {\n" @@ -536,7 +537,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("subversion", strSubVersion)); obj.push_back(Pair("protocolversion",PROTOCOL_VERSION)); obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices))); - obj.push_back(Pair("timeoffset", GetTimeOffset())); + obj.push_back(Pair("timeoffset", 0)); obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index fc0600dfc..612802445 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -345,15 +345,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(vAddr1.size() == 0); CAddress addr1 = CAddress(CService("250.250.2.1", 8333)); - addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false + addr1.nTime = GetTime(); // Set time so isTerrible = false CAddress addr2 = CAddress(CService("250.251.2.2", 9999)); - addr2.nTime = GetAdjustedTime(); + addr2.nTime = GetTime(); CAddress addr3 = CAddress(CService("251.252.2.3", 8333)); - addr3.nTime = GetAdjustedTime(); + addr3.nTime = GetTime(); CAddress addr4 = CAddress(CService("252.253.3.4", 8333)); - addr4.nTime = GetAdjustedTime(); + addr4.nTime = GetTime(); CAddress addr5 = CAddress(CService("252.254.4.5", 8333)); - addr5.nTime = GetAdjustedTime(); + addr5.nTime = GetTime(); CNetAddr source1 = CNetAddr("250.1.2.1"); CNetAddr source2 = CNetAddr("250.2.3.3"); @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) CAddress addr = CAddress(CService(strAddr)); // Ensure that for all addrs in addrman, isTerrible == false. - addr.nTime = GetAdjustedTime(); + addr.nTime = GetTime(); addrman.Add(addr, CNetAddr(strAddr)); if (i % 8 == 0) addrman.Good(addr); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 867de51a7..ed4d64f31 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1345,7 +1345,7 @@ UniValue movecmd(const UniValue& params, bool fHelp, const CPubKey& mypk) if (!walletdb.TxnBegin()) throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); - int64_t nNow = GetAdjustedTime(); + int64_t nNow = GetTime(); // Debit CAccountingEntry debit; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ae845cb21..ad52964be 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -472,12 +472,13 @@ void CWallet::ChainTip(const CBlockIndex *pindex, boost::optional> added) { if (added) { - // Prevent witness cache building && consolidation transactions + bool initialDownloadCheck = IsInitialBlockDownload(); + // Prevent witness cache building && consolidation transactions // from being created when node is syncing after launch, // and also when node wakes up from suspension/hibernation and incoming blocks are old. - bool initialDownloadCheck = IsInitialBlockDownload(); + // 144 blocks = 3hrs @ 75s blocktime if (!initialDownloadCheck && - pblock->GetBlockTime() > GetAdjustedTime() - 8640) //Last 144 blocks 2.4 * 60 * 60 + pblock->GetBlockTime() > GetTime() - 144*ASSETCHAINS_BLOCKTIME) { BuildWitnessCache(pindex, false); RunSaplingConsolidation(pindex->GetHeight()); @@ -1373,10 +1374,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD bool fInsertedNew = ret.second; if (fInsertedNew) { - wtx.nTimeReceived = GetAdjustedTime(); - wtx.nOrderPos = IncOrderPosNext(pwalletdb); - - wtx.nTimeSmart = wtx.nTimeReceived; + wtx.nTimeReceived = GetTime(); + wtx.nOrderPos = IncOrderPosNext(pwalletdb); + wtx.nTimeSmart = wtx.nTimeReceived; if (!wtxIn.hashBlock.IsNull()) { if (mapBlockIndex.count(wtxIn.hashBlock)) @@ -1385,7 +1385,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletD int64_t latestEntry = 0; { // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future - // TODO: this is 2 blocktimes, which will become 150? int64_t latestTolerated = latestNow + 300; std::list acentries; TxItems txOrdered = OrderedTxItems(acentries); From 55890a05430c2ec3a500d71b2a983918c1312ac3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 11 Jul 2020 01:19:08 -0400 Subject: [PATCH 201/220] Set various chain params when changing blocktime --- src/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index ea7fa7a1f..00d470573 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3234,6 +3234,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex if (ishush3 && (ASSETCHAINS_BLOCKTIME != 150) && (nHeight < nFirstHalvingHeight)) { LogPrintf("%s: Setting blocktime to 150s at height %d!\n",__func__,nHeight); ASSETCHAINS_BLOCKTIME = 150; + Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; + Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; } @@ -3386,6 +3388,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (ishush3 && (ASSETCHAINS_BLOCKTIME != 75) && (chainActive.Height() >= nFirstHalvingHeight)) { LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,pindex->GetHeight()); ASSETCHAINS_BLOCKTIME = 75; + Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; + Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; } bool fExpensiveChecks = true; @@ -3988,6 +3992,8 @@ void static UpdateTip(CBlockIndex *pindexNew) { if (ASSETCHAINS_BLOCKTIME != 75 && (chainActive.Height() >= nFirstHalvingHeight)) { LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,chainActive.Height()); ASSETCHAINS_BLOCKTIME = 75; + Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; + Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; } } From d516a21d54aed18aa678b4f556fe28758b6b286b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 11 Jul 2020 11:10:15 -0400 Subject: [PATCH 202/220] Create setter to modify blocktime consensus params at run-time --- src/chainparams.cpp | 8 ++++++++ src/chainparams.h | 1 + src/main.cpp | 12 +++++------- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 0a2b819e7..f14e2d9ef 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -544,6 +544,14 @@ int32_t MAX_BLOCK_SIZE(int32_t height) else return(2000000); } +// Change the Hush blocktime at run-time(!) +void hush_changeblocktime() +{ + pCurrentParams->consensus.nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; + pCurrentParams->consensus.nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; + fprintf(stderr,"HUSH blocktime changing to %d seconds\n",ASSETCHAINS_BLOCKTIME); +} + void komodo_setactivation(int32_t height) { pCurrentParams->consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = height; diff --git a/src/chainparams.h b/src/chainparams.h index daa16af8c..7bd1057ec 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index 00d470573..d4426e181 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,6 +85,7 @@ int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); //void komodo_broadcast(CBlock *pblock,int32_t limit); bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); void komodo_setactivation(int32_t height); +void hush_changeblocktime(); void komodo_pricesupdate(int32_t height,CBlock *pblock); BlockMap mapBlockIndex; @@ -3233,9 +3234,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex int nHeight = pindex->pprev->GetHeight(); if (ishush3 && (ASSETCHAINS_BLOCKTIME != 150) && (nHeight < nFirstHalvingHeight)) { LogPrintf("%s: Setting blocktime to 150s at height %d!\n",__func__,nHeight); - ASSETCHAINS_BLOCKTIME = 150; - Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; - Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; + ASSETCHAINS_BLOCKTIME = 150; + hush_changeblocktime(); } @@ -3388,8 +3388,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (ishush3 && (ASSETCHAINS_BLOCKTIME != 75) && (chainActive.Height() >= nFirstHalvingHeight)) { LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,pindex->GetHeight()); ASSETCHAINS_BLOCKTIME = 75; - Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; - Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; + hush_changeblocktime(); } bool fExpensiveChecks = true; @@ -3992,8 +3991,7 @@ void static UpdateTip(CBlockIndex *pindexNew) { if (ASSETCHAINS_BLOCKTIME != 75 && (chainActive.Height() >= nFirstHalvingHeight)) { LogPrintf("%s: Blocktime halving to 75s at height %d!\n",__func__,chainActive.Height()); ASSETCHAINS_BLOCKTIME = 75; - Params.GetConsensus().nMaxFutureBlockTime = 7 * ASSETCHAINS_BLOCKTIME; - Params.GetConsensus().nPowTargetSpacing = ASSETCHAINS_BLOCKTIME; + hush_changeblocktime(); } } From 40f0745fabdd46a7b79b94e981caa7c6c2af18f0 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 11 Jul 2020 11:11:14 -0400 Subject: [PATCH 203/220] Track shielded spends on disk so we can calculate anonset in real-time correctly --- src/chain.h | 15 ++++++++++++--- src/consensus/params.h | 3 ++- src/komodo-tx.cpp | 1 + src/main.cpp | 6 ++++-- src/rpc/blockchain.cpp | 3 ++- src/txdb.cpp | 1 + 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/chain.h b/src/chain.h index 03fc75660..77d17114e 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -276,9 +276,12 @@ public: //! inputs and outputs. int64_t nShieldedTx; - //! (memory only) Number of shielded outputs in the block up to and including this block. + //! (memory only) Number of shielded outputs int64_t nShieldedOutputs; + //! (memory only) Number of shielded spends + int64_t nShieldedSpends; + //! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined //! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent // inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc... @@ -332,6 +335,9 @@ public: //! (memory only) Number of shielded outputs in the chain up to and including this block. int64_t nChainShieldedOutputs; + //! (memory only) Number of shielded spends in the chain up to and including this block. + int64_t nChainShieldedSpends; + //! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined //! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent // inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc... @@ -429,18 +435,20 @@ public: nChainNotarizations = 0; nChainFullyShieldedTx = 0; nChainShieldedOutputs = 0; + nChainShieldedSpends = 0; nChainShieldedPayments = 0; nChainShieldingPayments = 0; nChainDeshieldingPayments = 0; nChainFullyShieldedPayments = 0; - // Shieldex Index stats + // Shielded Index stats nPayments = 0; nShieldedTx = 0; nShieldingTx = 0; nNotarizations = 0; nDeshieldingTx = 0; nShieldedOutputs = 0; + nShieldedSpends = 0; nFullyShieldedTx = 0; nShieldedPayments = 0; nShieldingPayments = 0; @@ -679,6 +687,7 @@ public: READWRITE(nDeshieldingPayments); READWRITE(nFullyShieldedPayments); READWRITE(nShieldedOutputs); + READWRITE(nShieldedSpends); } } diff --git a/src/consensus/params.h b/src/consensus/params.h index 67d84af0b..e4242ad33 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -1,7 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or https://www.opensource.org/licenses/mit-license.php /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * diff --git a/src/komodo-tx.cpp b/src/komodo-tx.cpp index 7e0477eb7..0f0b59421 100644 --- a/src/komodo-tx.cpp +++ b/src/komodo-tx.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/src/main.cpp b/src/main.cpp index d4426e181..0dc0cf87e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4734,7 +4734,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl CAmount sproutValue = 0; CAmount saplingValue = 0; bool isShieldedTx = false; - unsigned int nShieldedSpends=0,nShieldedOutputs=0,nPayments=0, nShieldedOutputsInBlock=0; + unsigned int nShieldedSpends=0,nShieldedSpendsInBlock=0,nShieldedOutputs=0,nPayments=0, nShieldedOutputsInBlock=0; unsigned int nShieldedTx=0,nFullyShieldedTx=0,nDeshieldingTx=0,nShieldingTx=0; unsigned int nShieldedPayments=0,nFullyShieldedPayments=0,nShieldingPayments=0,nDeshieldingPayments=0; unsigned int nNotarizations=0; @@ -4822,8 +4822,9 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl // No shielded payments, add transparent payments minus a change address nPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size(); } - // To calculate the anonset we must track the sum of zouts in every tx, in every block. -- Duke + // To calculate the anonset we must track the sum of spends and zouts in every tx, in every block. -- Duke nShieldedOutputsInBlock += nShieldedOutputs; + nShieldedSpendsInBlock += nShieldedSpends; } pindexNew->nSproutValue = sproutValue; @@ -4840,6 +4841,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindexNew->nPayments = nPayments; pindexNew->nShieldedTx = nShieldedTx; pindexNew->nShieldedOutputs = nShieldedOutputsInBlock; + pindexNew->nShieldedSpends = nShieldedSpendsInBlock; pindexNew->nFullyShieldedTx = nFullyShieldedTx; pindexNew->nDeshieldingTx = nDeshieldingTx; pindexNew->nShieldingTx = nShieldingTx; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index faed5b957..3bdce7eb2 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2003,8 +2003,9 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk ret.pushKV("shielding_payments", (int64_t)pindex->nChainShieldingPayments); int64_t nullifierCount = pwalletMain->NullifierCount(); + //TODO: this is unreliable, is only a cache or subset of total nullifiers ret.pushKV("nullifiers", (int64_t)nullifierCount); - ret.pushKV("shielded_pool_size", (int64_t)pindex->nChainShieldedOutputs - nullifierCount); + ret.pushKV("shielded_pool_size", (int64_t)(pindex->nChainShieldedOutputs - pindex->nChainShieldedSpends)); ret.pushKV("shielded_outputs", (int64_t)pindex->nChainShieldedOutputs); } diff --git a/src/txdb.cpp b/src/txdb.cpp index 6fe8bd575..78769c07c 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -723,6 +723,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nPayments = diskindex.nPayments; pindexNew->nShieldedTx = diskindex.nShieldedTx; pindexNew->nShieldedOutputs = diskindex.nShieldedOutputs; + pindexNew->nShieldedSpends = diskindex.nShieldedSpends; pindexNew->nShieldedPayments = diskindex.nShieldedPayments; pindexNew->nShieldingTx = diskindex.nShieldingTx; pindexNew->nShieldingPayments = diskindex.nShieldingPayments; From 9544bd0ffcb60165ec1efc8f25aeb6dfc1521ea7 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Sun, 12 Jul 2020 11:47:00 +0200 Subject: [PATCH 204/220] adjustments for cross build of aarch64 binaries on x86_64 linux --- configure.ac | 47 +- depends/.gitignore | 1 + depends/Makefile | 1 + depends/config.site.in | 3 + depends/funcs.mk | 11 +- depends/packages/bdb.mk | 5 + depends/packages/libcurl.mk | 2 +- depends/packages/librustzcash.mk | 18 +- depends/packages/packages.mk | 2 - depends/packages/proton.mk | 7 +- depends/packages/rust.mk | 51 +- depends/patches/proton/minimal-build.patch | 530 +++++++++--------- src/Makefile.am | 6 +- src/cc/Makefile_custom | 5 + src/cc/makecustom | 2 +- src/cryptoconditions/Makefile.am | 2 +- .../src/include/secp256k1/Makefile.am | 2 +- zcutil/build-cross-aarch64.sh | 64 +++ 18 files changed, 450 insertions(+), 309 deletions(-) mode change 100755 => 100644 src/cc/Makefile_custom mode change 100755 => 100644 src/cc/makecustom create mode 100644 zcutil/build-cross-aarch64.sh diff --git a/configure.ac b/configure.ac index e3be0c9dd..f0474aec0 100644 --- a/configure.ac +++ b/configure.ac @@ -334,11 +334,11 @@ case $host in dnl AC_CHECK_PROG([BREW],brew, brew) dnl if test x$BREW = xbrew; then - dnl These Homebrew packages may be keg-only, meaning that they won't be found - dnl in expected paths because they may conflict with system files. Ask - dnl Homebrew where each one is located, then adjust paths accordingly. - dnl It's safe to add these paths even if the functionality is disabled by - dnl the user (--without-wallet for example). + dnl These Homebrew packages may be keg-only, meaning that they won't be found + dnl in expected paths because they may conflict with system files. Ask + dnl Homebrew where each one is located, then adjust paths accordingly. + dnl It's safe to add these paths even if the functionality is disabled by + dnl the user (--without-wallet for example). dnl openssl_prefix=`$BREW --prefix openssl 2>/dev/null` dnl bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` @@ -507,15 +507,24 @@ if test x$use_hardening != xno; then HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" ],[AC_MSG_ERROR(Cannot enable -D_FORTIFY_SOURCE=2)]) - #AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"],[AC_MSG_ERROR(Cannot enable RELRO)]) - #AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"],[AC_MSG_ERROR(Cannot enable BIND_NOW)]) + if test x$BUILD_OS = xdarwin || test x$TARGET_OS = xwindows; then + # Xcode's ld (at least ld64-302.3) doesn't support -z + # mingw-w64's ld (at least mingw-w64 4.0.4-2) also appears to not support -z + AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"],[AC_MSG_WARN(Cannot enable RELRO)]) + AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"],[AC_MSG_WARN(Cannot enable BIND_NOW)]) + else + AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"],[AC_MSG_ERROR(Cannot enable RELRO)]) + AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"],[AC_MSG_ERROR(Cannot enable BIND_NOW)]) + fi if test x$TARGET_OS != xwindows; then # All windows code is PIC, forcing it on just adds useless compile warnings - AX_CHECK_LINK_FLAG([[-Wl,-z,relro]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"],[AC_MSG_ERROR(Cannot enable RELRO)]) - AX_CHECK_LINK_FLAG([[-Wl,-z,now]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"],[AC_MSG_ERROR(Cannot enable BIND_NOW)]) - AX_CHECK_COMPILE_FLAG([-fPIE],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fPIE"],[AC_MSG_ERROR(Cannot enable -fPIE)]) - AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"],[AC_MSG_ERROR(Cannot enable -pie)]) + AX_CHECK_COMPILE_FLAG([-fPIE],[PIE_FLAGS="-fPIE"],[AC_MSG_ERROR(Cannot enable -fPIE)]) + if test x$BUILD_OS = xdarwin; then + AX_CHECK_LINK_FLAG([[-Wl,-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-pie"],[AC_MSG_ERROR(Cannot enable -Wl,-pie)]) + else + AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"],[AC_MSG_ERROR(Cannot enable -pie)]) + fi else # These are only available on Windows. AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"],[AC_MSG_ERROR(Cannot enable --dynamicbase)]) @@ -700,7 +709,7 @@ if test x$use_pkgconfig = xyes; then ) else # BUG: Fix this: - echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, gmp' + echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, libgmp' AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -756,6 +765,14 @@ fi fi fi +# These packages don't provide pkgconfig config files across all +# platforms, so we use older autoconf detection mechanisms: +AC_CHECK_HEADER([gmp.h],,AC_MSG_ERROR(libgmp headers missing)) +AC_CHECK_LIB([gmp],[[__gmpn_sub_n]],GMP_LIBS=-lgmp, [AC_MSG_ERROR(libgmp missing)]) + +AC_CHECK_HEADER([gmpxx.h],,AC_MSG_ERROR(libgmpxx headers missing)) +AC_CHECK_LIB([gmpxx],[main],GMPXX_LIBS=-lgmpxx, [AC_MSG_ERROR(libgmpxx missing)]) + RUST_LIBS="-lrustzcash" case $host in *mingw*) @@ -950,7 +967,7 @@ case $host in ;; esac -echo +echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" echo " with proton = $use_proton" @@ -958,7 +975,7 @@ echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " debug enabled = $enable_debug" echo " werror = $enable_werror" -echo +echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" echo @@ -969,4 +986,4 @@ echo " CXX = $CXX" echo " CXXFLAGS = $CXXFLAGS" echo " LDFLAGS = $LDFLAGS" echo " ARFLAGS = $ARFLAGS" -echo +echo diff --git a/depends/.gitignore b/depends/.gitignore index 1f163897b..3cb4b9ac1 100644 --- a/depends/.gitignore +++ b/depends/.gitignore @@ -7,3 +7,4 @@ x86_64* i686* mips* arm* +aarch64* diff --git a/depends/Makefile b/depends/Makefile index 636577d13..9d53bd1be 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -112,6 +112,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ + -e 's|@rust_target@|$(call rust_target,rust,$(canonical_host),$(host_os))|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ diff --git a/depends/config.site.in b/depends/config.site.in index 8cdbcd2e4..dbcb7a6e4 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -13,6 +13,9 @@ if test -z $enable_wallet && test -n "@no_wallet@"; then enable_wallet=no fi +RUST_TARGET="@rust_target@" +RUST_VENDORED_SOURCES="$depends_prefix/vendored-sources" + if test x@host_os@ = xdarwin; then BREW=no PORT=no diff --git a/depends/funcs.mk b/depends/funcs.mk index 3d89de8a7..35ca5abcf 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -40,7 +40,7 @@ endef define vendor_crate_source mkdir -p $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY) && \ -cp -r $($(1)_extract_dir) $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY)/$($(1)_crate_name) && \ +cp -r $($(1)_extract_dir) $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY)/$($(1)_crate_versioned_name) && \ cd $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY)/$($(1)_crate_versioned_name) && \ rm -r `basename $($(1)_patch_dir)` .stamp_* .$($(1)_file_name).hash endef @@ -59,8 +59,8 @@ $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SU final_build_id_long+=$($(package)_build_id_long) #override platform specific files and hashes -$(eval $(1)_file_name=$(if $($(1)_file_name_$(host_os)),$($(1)_file_name_$(host_os)),$($(1)_file_name))) -$(eval $(1)_sha256_hash=$(if $($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash))) +$(eval $(1)_file_name=$(if $($(1)_exact_file_name),$($(1)_exact_file_name),$(if $($(1)_file_name_$(host_os)),$($(1)_file_name_$(host_os)),$($(1)_file_name)))) +$(eval $(1)_sha256_hash=$(if $($(1)_exact_sha256_hash),$($(1)_exact_sha256_hash),$(if $($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash)))) #compute package-specific paths $(1)_build_subdir?=. @@ -91,8 +91,9 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands +# The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --strip-components=1 -xf $$($(1)_source) +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) $(1)_preprocess_cmds ?= $(1)_build_cmds ?= $(1)_config_cmds ?= @@ -193,7 +194,7 @@ $($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted) $(AT)touch $$@ $($(1)_configured): | $($(1)_preprocessed) $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar xf $($(package)_cached); ) + $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar --no-same-owner -xf $($(package)_cached); ) $(AT)mkdir -p $$(@D) $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) $(AT)touch $$@ diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 404d94c51..c8f677490 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -9,6 +9,11 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_config_opts_freebsd=--with-pic +ifneq ($(build_os),darwin) +$(package)_config_opts_darwin=--disable-atomicsupport +endif +$(package)_config_opts_aarch64=--disable-atomicsupport $(package)_cxxflags=-std=c++11 endef diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk index fd82dc4e0..91ff1c0f1 100644 --- a/depends/packages/libcurl.mk +++ b/depends/packages/libcurl.mk @@ -4,7 +4,7 @@ $(package)_dependencies=openssl $(package)_download_path=https://curl.haxx.se/download $(package)_file_name=curl-$($(package)_version).tar.gz $(package)_sha256_hash=52af3361cf806330b88b4fe6f483b6844209d47ae196ac46da4de59bb361ab02 -$(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-unknown-linux-gnu +$(package)_config_opts_linux=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(host) $(package)_config_opts_mingw32=--enable-mingw --disable-shared --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32 $(package)_config_opts_darwin=--disable-shared --enable-static --prefix=$(host_prefix) $(package)_cflags_darwin=-mmacosx-version-min=10.9 diff --git a/depends/packages/librustzcash.mk b/depends/packages/librustzcash.mk index 8612ac05a..fe6ef8a58 100644 --- a/depends/packages/librustzcash.mk +++ b/depends/packages/librustzcash.mk @@ -8,15 +8,29 @@ $(package)_git_commit=06da3b9ac8f278e5d4ae13088cf0a4c03d2c13f5 $(package)_dependencies=rust $(rust_crates) $(package)_patches=cargo.config 0001-Start-using-cargo-clippy-for-CI.patch remove-dev-dependencies.diff no-groth16.patch +$(package)_rust_target=$(if $(rust_rust_target_$(canonical_host)),$(rust_rust_target_$(canonical_host)),$(canonical_host)) + ifeq ($(host_os),mingw32) $(package)_library_file=target/x86_64-pc-windows-gnu/release/rustzcash.lib +else ifneq ($(canonical_host),$(build)) +ifeq ($(host_os),darwin) +$(package)_library_file=target/x86_64-apple-darwin/release/librustzcash.a +else +$(package)_library_file=target/$($(package)_rust_target)/release/librustzcash.a +endif else $(package)_library_file=target/release/librustzcash.a endif define $(package)_set_vars $(package)_build_opts=--frozen --release -$(package)_build_opts_mingw32=--target=x86_64-pc-windows-gnu +ifneq ($(canonical_host),$(build)) +ifeq ($(host_os),darwin) +$(package)_build_opts+=--target=x86_64-apple-darwin +else +$(package)_build_opts+=--target=$($(package)_rust_target) +endif +endif endef define $(package)_preprocess_cmds @@ -27,7 +41,7 @@ define $(package)_preprocess_cmds endef define $(package)_build_cmds - cargo build --package librustzcash $($(package)_build_opts) + $(host_prefix)/native/bin/cargo build --package librustzcash $($(package)_build_opts) endef define $(package)_stage_cmds diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 8abb7c708..8a56f73f3 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,5 +1,3 @@ -rust_packages := rust librustzcash - ifeq ($(build_os),darwin) zcash_packages := libgmp libsodium utfcpp else diff --git a/depends/packages/proton.mk b/depends/packages/proton.mk index 1bb5c8865..d974fa5fa 100644 --- a/depends/packages/proton.mk +++ b/depends/packages/proton.mk @@ -1,8 +1,8 @@ package=proton -$(package)_version=0.26.0 +$(package)_version=0.30.0 $(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version) $(package)_file_name=qpid-proton-$($(package)_version).tar.gz -$(package)_sha256_hash=0eddac870f0085b9aeb0c9da333bd3f53fedb7c872164171a7cc06761ddbbd75 +$(package)_sha256_hash=e37fd8fb13391c3996f927839969a8f66edf35612392d0611eeac6e39e48dd33 $(package)_patches=minimal-build.patch define $(package)_preprocess_cmds @@ -11,7 +11,7 @@ define $(package)_preprocess_cmds endef define $(package)_config_cmds - cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_PHP=OFF -DBUILD_JAVA=OFF -DBUILD_PERL=OFF -DBUILD_RUBY=OFF -DBUILD_JAVASCRIPT=OFF -DBUILD_GO=OFF -DBUILD_STATIC_LIBS=ON + cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_RUBY=OFF -DBUILD_GO=OFF -DBUILD_STATIC_LIBS=ON -DLIB_SUFFIX= -DENABLE_JSONCPP= endef define $(package)_build_cmds @@ -21,3 +21,4 @@ endef define $(package)_stage_cmds cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install endef + diff --git a/depends/packages/rust.mk b/depends/packages/rust.mk index 9cfb95054..2546a733e 100644 --- a/depends/packages/rust.mk +++ b/depends/packages/rust.mk @@ -1,28 +1,33 @@ package=rust -$(package)_version=1.32.0 +$(package)_version=1.42.0 $(package)_download_path=https://static.rust-lang.org/dist - $(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash_linux=e024698320d76b74daf0e6e71be3681a1e7923122e3ebd03673fcac3ecc23810 +$(package)_sha256_hash_linux=7d1e07ad9c8a33d8d039def7c0a131c5917aa3ea0af3d0cc399c6faf7b789052 $(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash_darwin=f0dfba507192f9b5c330b5984ba71d57d434475f3d62bd44a39201e36fa76304 -$(package)_file_name_mingw32=rust-$($(package)_version)-x86_64-pc-windows-gnu.tar.gz -$(package)_sha256_hash_mingw32=358e1435347c67dbf33aa9cad6fe501a833d6633ed5d5aa1863d5dffa0349be9 +$(package)_sha256_hash_darwin=db1055c46e0d54b99da05e88c71fea21b3897e74a4f5ff9390e934f3f050c0a8 +$(package)_file_name_freebsd=rust-$($(package)_version)-x86_64-unknown-freebsd.tar.gz +$(package)_sha256_hash_freebsd=230bcf17e4383fba85d3c87fe25d17737459fe561a5f4668fe70dcac2da4e17c -ifeq ($(build_os),darwin) -$(package)_file_name=$($(package)_file_name_darwin) -$(package)_sha256_hash=$($(package)_sha256_hash_darwin) -else ifeq ($(host_os),mingw32) -$(package)_file_name=$($(package)_file_name_mingw32) -$(package)_sha256_hash=$($(package)_sha256_hash_mingw32) -else -$(package)_file_name=$($(package)_file_name_linux) -$(package)_sha256_hash=$($(package)_sha256_hash_linux) -endif +# Mapping from GCC canonical hosts to Rust targets +# If a mapping is not present, we assume they are identical, unless $host_os is +# "darwin", in which case we assume x86_64-apple-darwin. +$(package)_rust_target_x86_64-w64-mingw32=x86_64-pc-windows-gnu -ifeq ($(host_os),mingw32) +# Mapping from Rust targets to SHA-256 hashes +$(package)_rust_std_sha256_hash_aarch64-unknown-linux-gnu=1343f51fc87049327233cee8941629c3d7dfdc425d359385f93665de3d46711b +$(package)_rust_std_sha256_hash_x86_64-apple-darwin=1d61e9ed5d29e1bb4c18e13d551c6d856c73fb8b410053245dc6e0d3b3a0e92c +$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=8a8389f3860df6f42fbf8b76a62ddc7b9b6fe6d0fb526dcfc42faab1005bfb6d + +define rust_target +$(if $($(1)_rust_target_$(2)),$($(1)_rust_target_$(2)),$(if $(findstring darwin,$(3)),x86_64-apple-darwin,$(2))) +endef + +ifneq ($(canonical_host),$(build)) +$(package)_rust_target=$(call rust_target,$(package),$(canonical_host),$(host_os)) +$(package)_exact_file_name=rust-std-$($(package)_version)-$($(package)_rust_target).tar.gz +$(package)_exact_sha256_hash=$($(package)_rust_std_sha256_hash_$($(package)_rust_target)) $(package)_build_subdir=buildos -$(package)_extra_sources = $($(package)_file_name_$(build_os)) +$(package)_extra_sources=$($(package)_file_name_$(build_os)) define $(package)_fetch_cmds $(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ @@ -34,19 +39,19 @@ define $(package)_extract_cmds echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ echo "$($(package)_sha256_hash_$(build_os)) $($(package)_source_dir)/$($(package)_file_name_$(build_os))" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir mingw32 && \ - tar --strip-components=1 -xf $($(package)_source) -C mingw32 && \ + mkdir $(canonical_host) && \ + tar --strip-components=1 -xf $($(package)_source) -C $(canonical_host) && \ mkdir buildos && \ tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_file_name_$(build_os)) -C buildos endef define $(package)_stage_cmds - ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig && \ - cp -r ../mingw32/rust-std-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu $($(package)_staging_dir)$(host_prefix)/native/lib/rustlib + bash ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig && \ + ../$(canonical_host)/install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig endef else define $(package)_stage_cmds - ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig + bash ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig endef endif diff --git a/depends/patches/proton/minimal-build.patch b/depends/patches/proton/minimal-build.patch index 90588929f..dd138d2f6 100644 --- a/depends/patches/proton/minimal-build.patch +++ b/depends/patches/proton/minimal-build.patch @@ -1,288 +1,314 @@ -From 03f5fc0826115edbfca468261b70c0daf627f488 Mon Sep 17 00:00:00 2001 -From: Simon -Date: Thu, 27 Apr 2017 17:15:59 -0700 -Subject: [PATCH] Enable C++11, build static library and cpp bindings with minimal dependencies. - ---- - CMakeLists.txt | 13 +++++++------ - examples/cpp/CMakeLists.txt | 1 + - proton-c/CMakeLists.txt | 32 +++++++++++++++---------------- - proton-c/bindings/CMakeLists.txt | 6 +++--- - proton-c/bindings/cpp/CMakeLists.txt | 24 +++++++++++------------ - proton-c/bindings/cpp/docs/CMakeLists.txt | 2 +- - proton-c/docs/api/CMakeLists.txt | 2 +- - 7 files changed, 41 insertions(+), 39 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index b538ffd..4a5e787 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -18,14 +18,15 @@ - # - cmake_minimum_required (VERSION 2.8.7) +diff -ur a/c/CMakeLists.txt b/c/CMakeLists.txt +--- a/c/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 ++++ b/c/CMakeLists.txt 2020-01-08 16:15:26.837987469 -0700 +@@ -428,18 +428,18 @@ + # Can't use target_link_libraries() because cmake 2.8.12 doesn't allow object libraries as the first param + # otherwise for cmake 3.9 and on this would be: + # target_link_libraries (qpid-proton-core-objects ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) +-target_compile_definitions(qpid-proton-core-objects PRIVATE $) +-target_compile_options (qpid-proton-core-objects PRIVATE $) +-target_include_directories(qpid-proton-core-objects PRIVATE $) +- +-add_library (qpid-proton-core SHARED $) +-target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) +-set_target_properties (qpid-proton-core +- PROPERTIES +- VERSION "${PN_LIB_CORE_VERSION}" +- SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}" +- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" +-) ++#target_compile_definitions(qpid-proton-core-objects PRIVATE $) ++#target_compile_options (qpid-proton-core-objects PRIVATE $) ++#target_include_directories(qpid-proton-core-objects PRIVATE $) ++ ++#add_library (qpid-proton-core SHARED $) ++#target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) ++#set_target_properties (qpid-proton-core ++# PROPERTIES ++# VERSION "${PN_LIB_CORE_VERSION}" ++# SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}" ++# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" ++#) -+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - project (Proton C) + if (BUILD_STATIC_LIBS) + add_library (qpid-proton-core-static STATIC ${qpid-proton-core-src}) +@@ -454,14 +454,14 @@ + ${qpid-proton-include-extra} + ) - # Enable C++ now for examples and bindings subdirectories, but make it optional. - enable_language(CXX OPTIONAL) +-add_library (qpid-proton SHARED $ ${qpid-proton-noncore-src}) +-target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS}) +-set_target_properties (qpid-proton +- PROPERTIES +- VERSION "${PN_LIB_LEGACY_VERSION}" +- SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}" +- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" +-) ++# add_library (qpid-proton SHARED $ ${qpid-proton-noncore-src}) ++# target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS}) ++# set_target_properties (qpid-proton ++# PROPERTIES ++# VERSION "${PN_LIB_LEGACY_VERSION}" ++# SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}" ++# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" ++# ) + + if (BUILD_STATIC_LIBS) + add_library(qpid-proton-static STATIC ${qpid-proton-core-src} ${qpid-proton-noncore-src}) +@@ -482,15 +482,15 @@ + + if (qpid-proton-proactor) + set(HAS_PROACTOR True) +- add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor}) +- target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core) +- target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS}) +- set_target_properties (qpid-proton-proactor +- PROPERTIES +- VERSION "${PN_LIB_PROACTOR_VERSION}" +- SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}" +- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" +- ) ++ # add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor}) ++ # target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core) ++ # target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS}) ++ # set_target_properties (qpid-proton-proactor ++ # PROPERTIES ++ # VERSION "${PN_LIB_PROACTOR_VERSION}" ++ # SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}" ++ # LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" ++ # ) + if (BUILD_STATIC_LIBS) + add_library (qpid-proton-proactor-static STATIC ${qpid-proton-proactor}) + endif(BUILD_STATIC_LIBS) +@@ -500,11 +500,11 @@ + if (BUILD_STATIC_LIBS) + set(STATIC_LIBS qpid-proton-static qpid-proton-core-static) + endif() +-install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS} +- EXPORT proton +- RUNTIME DESTINATION bin +- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} +- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) ++# install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS} ++# EXPORT proton ++# RUNTIME DESTINATION bin ++# ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ++# LIBRARY DESTINATION ${LIB_INSTALL_DIR}) + + # Install windows pdb files + if (MSVC) +@@ -520,11 +520,11 @@ + if (BUILD_STATIC_LIBS) + set(STATIC_LIBS qpid-proton-proactor-static) + endif() +- install(TARGETS qpid-proton-proactor ${STATIC_LIBS} +- EXPORT proton +- RUNTIME DESTINATION bin +- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} +- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) ++ # install(TARGETS qpid-proton-proactor ${STATIC_LIBS} ++ # EXPORT proton ++ # RUNTIME DESTINATION bin ++ # ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ++ # LIBRARY DESTINATION ${LIB_INSTALL_DIR}) + + # Install windows pdb files + if (MSVC) +@@ -576,10 +576,10 @@ + ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfigVersion.cmake + DESTINATION ${LIB_INSTALL_DIR}/cmake/Proton) + +-add_subdirectory(docs) +-add_subdirectory(examples) +-add_subdirectory(tests) +-add_subdirectory(tools) ++# add_subdirectory(docs) ++# add_subdirectory(examples) ++# add_subdirectory(tests) ++# add_subdirectory(tools) + + install (DIRECTORY examples/ + DESTINATION "${PROTON_SHARE}/examples/c" +diff -ur a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 ++++ b/CMakeLists.txt 2019-12-19 18:11:57.128248724 -0700 +@@ -24,7 +24,7 @@ + set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules") + set (CMAKE_THREAD_PREFER_PTHREAD TRUE) - # Enable testing --enable_testing() -include (CTest) -+#enable_testing() -+#include (CTest) ++# include (CTest) + include (CheckLanguage) + include (CheckLibraryExists) + include (CheckSymbolExists) +@@ -33,13 +33,13 @@ + find_package (OpenSSL) + find_package (Threads) + find_package (PythonInterp REQUIRED) +-find_package (SWIG) ++# find_package (SWIG) + find_package (CyrusSASL) - # Pull in local cmake modules - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules/") -@@ -141,7 +142,7 @@ set (BINDINGS_DIR ${LIB_INSTALL_DIR}/proton/bindings) +-enable_testing () ++#enable_testing () + + # Set up runtime checks (valgrind, sanitizers etc.) +-include(tests/RuntimeCheck.cmake) ++# include(tests/RuntimeCheck.cmake) + + ## Variables used across components + +@@ -260,7 +260,7 @@ set (SYSINSTALL_BINDINGS OFF CACHE BOOL "If SYSINSTALL_BINDINGS is OFF then proton bindings will be installed underneath ${BINDINGS_DIR} and each user will need to modify their interpreter configuration to load the appropriate binding. If SYSINSTALL_BINDINGS is ON, then each language interpreter will be queried for the appropriate directory and proton bindings will be installed and available system wide with no additional per user configuration.") --set (BINDING_LANGS PERL PHP PYTHON RUBY) -+#set (BINDING_LANGS PERL PHP PYTHON RUBY) +-set (BINDING_LANGS PYTHON RUBY) ++# set (BINDING_LANGS PYTHON RUBY) foreach (LANG ${BINDING_LANGS}) set (SYSINSTALL_${LANG} OFF CACHE BOOL "Install ${LANG} bindings into interpreter specified location.") -@@ -156,10 +157,10 @@ set (PROTON_SHARE ${SHARE_INSTALL_DIR}/proton-${PN_VERSION}) - # End of variables used during install - - # Check for valgrind here so tests under proton-c/ and examples/ can use it. --find_program(VALGRIND_EXE valgrind DOC "Location of the valgrind program") -+#find_program(VALGRIND_EXE valgrind DOC "Location of the valgrind program") - mark_as_advanced (VALGRIND_EXE) - --option(ENABLE_VALGRIND "Use valgrind to detect run-time problems" ON) -+#option(ENABLE_VALGRIND "Use valgrind to detect run-time problems" ON) - if (ENABLE_VALGRIND) - if (NOT VALGRIND_EXE) - message(STATUS "Can't locate the valgrind command; no run-time error detection") -@@ -171,7 +172,7 @@ if (ENABLE_VALGRIND) - endif (ENABLE_VALGRIND) - - add_subdirectory(proton-c) --add_subdirectory(examples) -+#add_subdirectory(examples) - - install (FILES LICENSE README.md - DESTINATION ${PROTON_SHARE}) -diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt -index 304d899..f4877b4 100644 ---- a/examples/cpp/CMakeLists.txt -+++ b/examples/cpp/CMakeLists.txt -@@ -17,6 +17,7 @@ - # under the License. - # - -+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - find_package(ProtonCpp REQUIRED) - - include_directories(${ProtonCpp_INCLUDE_DIRS}) -diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt -index 8edb661..dc7b99c 100644 ---- a/proton-c/CMakeLists.txt -+++ b/proton-c/CMakeLists.txt -@@ -22,24 +22,24 @@ include(CheckSymbolExists) - - include(soversion.cmake) - --add_custom_target(docs) --add_custom_target(doc DEPENDS docs) -+#add_custom_target(docs) -+#add_custom_target(doc DEPENDS docs) - - # Set the default SSL/TLS implementation --find_package(OpenSSL) -+#find_package(OpenSSL) - find_package(PythonInterp REQUIRED) --find_package(SWIG) -+#find_package(SWIG) - # FindSwig.cmake "forgets" make its outputs advanced like a good citizen - mark_as_advanced(SWIG_DIR SWIG_EXECUTABLE SWIG_VERSION) - - # See if Cyrus SASL is available --find_library(CYRUS_SASL_LIBRARY sasl2) --find_path(CYRUS_SASL_INCLUDE_DIR sasl/sasl.h PATH_SUFFIXES include) --find_package_handle_standard_args(CyrusSASL DEFAULT_MSG CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) -+#find_library(CYRUS_SASL_LIBRARY sasl2) -+#find_path(CYRUS_SASL_INCLUDE_DIR sasl/sasl.h PATH_SUFFIXES include) -+#find_package_handle_standard_args(CyrusSASL DEFAULT_MSG CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) - mark_as_advanced(CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) - - # Find saslpasswd2 executable to generate test config --find_program(SASLPASSWD_EXE saslpasswd2 DOC "Program used to make SASL user db for testing") -+#find_program(SASLPASSWD_EXE saslpasswd2 DOC "Program used to make SASL user db for testing") - mark_as_advanced(SASLPASSWD_EXE) - - if(WIN32 AND NOT CYGWIN) -@@ -315,8 +315,8 @@ pn_absolute_install_dir(EXEC_PREFIX "." ${CMAKE_INSTALL_PREFIX}) - pn_absolute_install_dir(LIBDIR ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}) - pn_absolute_install_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}) - --add_subdirectory(docs/api) --add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c) -+#add_subdirectory(docs/api) -+#add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c) - - # for full source distribution: - set (qpid-proton-platform-all -@@ -507,7 +507,7 @@ if (BUILD_WITH_CXX) - endif (BUILD_WITH_CXX) - - add_library ( -- qpid-proton-core SHARED -+ qpid-proton-core STATIC - ${qpid-proton-core} - ${qpid-proton-layers} - ${qpid-proton-platform} -@@ -527,7 +527,7 @@ set_target_properties ( - ) - - add_library( -- qpid-proton SHARED -+ qpid-proton STATIC - # Proton Core - ${qpid-proton-core} - ${qpid-proton-layers} -@@ -629,7 +629,7 @@ install (FILES - - # c tests: - --add_subdirectory(src/tests) -+#add_subdirectory(src/tests) - - if (CMAKE_SYSTEM_NAME STREQUAL Windows) - # No change needed for windows already use correct separator -@@ -712,7 +712,7 @@ if (BUILD_PYTHON) - - endif (BUILD_PYTHON) - --find_program(RUBY_EXE "ruby") -+#find_program(RUBY_EXE "ruby") - if (RUBY_EXE AND BUILD_RUBY) - set (rb_root "${pn_test_root}/ruby") - set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby") -@@ -751,8 +751,8 @@ if (RUBY_EXE AND BUILD_RUBY) - else (DEFAULT_RUBY_TESTING) - message(STATUS "Skipping Ruby tests: missing dependencies") - endif (DEFAULT_RUBY_TESTING) --else (RUBY_EXE) -- message (STATUS "Cannot find ruby, skipping ruby tests") -+#else (RUBY_EXE) -+# message (STATUS "Cannot find ruby, skipping ruby tests") +@@ -315,7 +315,7 @@ endif() - mark_as_advanced (RUBY_EXE RSPEC_EXE) -diff --git a/proton-c/bindings/CMakeLists.txt b/proton-c/bindings/CMakeLists.txt -index 6b88384..d1a50a5 100644 ---- a/proton-c/bindings/CMakeLists.txt -+++ b/proton-c/bindings/CMakeLists.txt -@@ -19,14 +19,14 @@ - - # Add bindings that do not require swig here - the directory name must be the same as the binding name - # See below for swig bindings --set(BINDINGS javascript cpp go) -+set(BINDINGS cpp) - - # Prerequisites for javascript. - # - # It uses a C/C++ to JavaScript cross-compiler called emscripten (https://github.com/kripken/emscripten). Emscripten takes C/C++ - # and compiles it into a highly optimisable subset of JavaScript called asm.js (http://asmjs.org/) that can be - # aggressively optimised and run at near-native speed (usually between 1.5 to 10 times slower than native C/C++). --find_package(Emscripten) -+#find_package(Emscripten) - if (EMSCRIPTEN_FOUND) - set (DEFAULT_JAVASCRIPT ON) - endif (EMSCRIPTEN_FOUND) -@@ -37,7 +37,7 @@ if (CMAKE_CXX_COMPILER) - endif (CMAKE_CXX_COMPILER) - # Prerequisites for Go -find_program(GO_EXE go) -+#find_program(GO_EXE go) ++# find_program(GO_EXE go) mark_as_advanced(GO_EXE) if (GO_EXE) - if(WIN32) -diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt -index 0cc4024..796fe29 100644 ---- a/proton-c/bindings/cpp/CMakeLists.txt -+++ b/proton-c/bindings/cpp/CMakeLists.txt -@@ -16,7 +16,7 @@ - # specific language governing permissions and limitations - # under the License. - # -- -+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - include(cpp.cmake) # Compiler checks - - include_directories( -@@ -89,7 +89,7 @@ set_source_files_properties ( - COMPILE_FLAGS "${LTO}" - ) + set (DEFAULT_GO ON) +diff -ur a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt +--- a/cpp/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 ++++ b/cpp/CMakeLists.txt 2020-01-08 16:20:18.855394195 -0700 +@@ -174,30 +174,30 @@ + set (CMAKE_DEBUG_POSTFIX "d") + endif () -add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source}) -+add_library(qpid-proton-cpp STATIC ${qpid-proton-cpp-source}) ++# add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source}) + if(BUILD_STATIC_LIBS) + add_library(qpid-proton-cpp-static STATIC ${qpid-proton-cpp-source}) + set(STATIC_LIBS qpid-proton-cpp-static) + endif(BUILD_STATIC_LIBS) - target_link_libraries (qpid-proton-cpp ${PLATFORM_LIBS} qpid-proton) +-target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS}) ++# target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS}) -@@ -120,8 +120,8 @@ endif (MSVC) +-set_target_properties ( +- qpid-proton-cpp +- PROPERTIES +- LINKER_LANGUAGE CXX +- VERSION "${PN_LIB_CPP_VERSION}" +- SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}" +- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" +- ) ++# set_target_properties ( ++# qpid-proton-cpp ++# PROPERTIES ++# LINKER_LANGUAGE CXX ++# VERSION "${PN_LIB_CPP_VERSION}" ++# SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}" ++# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" ++# ) + + ## Install + +-install(TARGETS qpid-proton-cpp ${STATIC_LIBS} +- EXPORT proton-cpp +- RUNTIME DESTINATION bin +- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} +- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) ++# install(TARGETS qpid-proton-cpp ${STATIC_LIBS} ++# EXPORT proton-cpp ++# RUNTIME DESTINATION bin ++# ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ++# LIBRARY DESTINATION ${LIB_INSTALL_DIR}) + + # Install windows qpid-proton-cpp pdb files + if (MSVC) +@@ -209,12 +209,12 @@ install (DIRECTORY "include/proton" DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.hpp") + install (FILES "${CMAKE_CURRENT_BINARY_DIR}/config_presets.hpp" DESTINATION "${INCLUDE_INSTALL_DIR}/proton/internal") +-install (DIRECTORY "examples/" +- DESTINATION "${PROTON_SHARE}/examples/cpp" +- USE_SOURCE_PERMISSIONS +- PATTERN "ProtonCppConfig.cmake" EXCLUDE) ++# install (DIRECTORY "examples/" ++# DESTINATION "${PROTON_SHARE}/examples/cpp" ++# USE_SOURCE_PERMISSIONS ++# PATTERN "ProtonCppConfig.cmake" EXCLUDE) --add_subdirectory(docs) --add_subdirectory(${CMAKE_SOURCE_DIR}/tests/tools/apps/cpp ${CMAKE_BINARY_DIR}/tests/tools/apps/cpp) -+#add_subdirectory(docs) -+#add_subdirectory(${CMAKE_SOURCE_DIR}/tests/tools/apps/cpp ${CMAKE_BINARY_DIR}/tests/tools/apps/cpp) +-add_subdirectory(examples) ++# add_subdirectory(examples) + add_subdirectory(docs) # Pkg config file - configure_file( -@@ -171,12 +171,12 @@ macro(add_cpp_test test) - endif () - endmacro(add_cpp_test) +@@ -268,40 +268,40 @@ + set(test_env ${test_env} "PATH=$") + endif() +-macro(add_cpp_test test) +- add_executable (${test} src/${test}.cpp) +- target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS}) +- add_test (NAME cpp-${test} +- COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $ ${ARGN}) +-endmacro(add_cpp_test) +- -add_cpp_test(codec_test) -+#add_cpp_test(codec_test) - #add_cpp_test(engine_test) --add_cpp_test(thread_safe_test) +-add_cpp_test(connection_driver_test) -add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) -add_cpp_test(message_test) +-add_cpp_test(map_test) -add_cpp_test(scalar_test) -add_cpp_test(value_test) -add_cpp_test(container_test) --add_cpp_test(url_test) -+#add_cpp_test(thread_safe_test) -+#add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) -+#add_cpp_test(message_test) -+#add_cpp_test(scalar_test) -+#add_cpp_test(value_test) -+#add_cpp_test(container_test) -+#add_cpp_test(url_test) -diff --git a/proton-c/bindings/cpp/docs/CMakeLists.txt b/proton-c/bindings/cpp/docs/CMakeLists.txt -index d512d15..8576867 100644 ---- a/proton-c/bindings/cpp/docs/CMakeLists.txt -+++ b/proton-c/bindings/cpp/docs/CMakeLists.txt -@@ -17,7 +17,7 @@ - # under the License. - # +-add_cpp_test(reconnect_test) +-add_cpp_test(link_test) +-add_cpp_test(credit_test) +-if (ENABLE_JSONCPP) +- add_cpp_test(connect_config_test) +- target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled +- set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") +- # Test data and output directories for connect_config_test +- file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") +-endif() ++# macro(add_cpp_test test) ++# add_executable (${test} src/${test}.cpp) ++# target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS}) ++# add_test (NAME cpp-${test} ++# COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $ ${ARGN}) ++# endmacro(add_cpp_test) ++# ++# add_cpp_test(codec_test) ++# add_cpp_test(connection_driver_test) ++# add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) ++# add_cpp_test(message_test) ++# add_cpp_test(map_test) ++# add_cpp_test(scalar_test) ++# add_cpp_test(value_test) ++# add_cpp_test(container_test) ++# add_cpp_test(reconnect_test) ++# add_cpp_test(link_test) ++# add_cpp_test(credit_test) ++# if (ENABLE_JSONCPP) ++# add_cpp_test(connect_config_test) ++# target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled ++# set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") ++# # Test data and output directories for connect_config_test ++# file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") ++# endif() --find_package(Doxygen) -+#find_package(Doxygen) + # TODO aconway 2018-10-31: Catch2 tests + # This is a simple example of a C++ test using the Catch2 framework. + # See c/tests/ for more interesting examples. + # Eventually all the C++ tests will migrate to Catch2. - if (DOXYGEN_FOUND) - configure_file ( -diff --git a/proton-c/docs/api/CMakeLists.txt b/proton-c/docs/api/CMakeLists.txt -index 7756e48..71ebb93 100644 ---- a/proton-c/docs/api/CMakeLists.txt -+++ b/proton-c/docs/api/CMakeLists.txt -@@ -17,7 +17,7 @@ - # under the License. - # +-include_directories(${CMAKE_SOURCE_DIR}/tests/include) +-add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp) +-target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS}) ++#include_directories(${CMAKE_SOURCE_DIR}/tests/include) ++#add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp) ++#target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS}) --find_package(Doxygen) -+#find_package(Doxygen) - if (DOXYGEN_FOUND) - configure_file (${CMAKE_CURRENT_SOURCE_DIR}/user.doxygen.in - ${CMAKE_CURRENT_BINARY_DIR}/user.doxygen) --- -2.7.4 - + macro(add_catch_test tag) + add_test ( diff --git a/src/Makefile.am b/src/Makefile.am index b44dd13c5..eb41a0031 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,13 +65,13 @@ LIBBITCOIN_WALLET=libbitcoin_wallet.a endif $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g " $(LIBUNIVALUE): $(wildcard univalue/lib/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g " $(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptoconditions/include/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -g " # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: diff --git a/src/cc/Makefile_custom b/src/cc/Makefile_custom old mode 100755 new mode 100644 index 79219ec96..0c2401f31 --- a/src/cc/Makefile_custom +++ b/src/cc/Makefile_custom @@ -2,6 +2,7 @@ SHELL = /bin/sh CC = gcc CC_DARWIN = g++-8 CC_WIN = x86_64-w64-mingw32-gcc-posix +CC_ARM64 = aarch64-linux-gnu-g++ CFLAGS_DARWIN = -DBUILD_CUSTOMCC -std=c++11 -arch x86_64 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib CFLAGS = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared CFLAGS_WIN = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared @@ -28,6 +29,10 @@ else ifeq ($(HOST),x86_64-w64-mingw32) $(CC_WIN) $(CFLAGS_WIN) $(DEBUGFLAGS) -o $(TARGET_WIN) -c $(SOURCES) cp $(TARGET_WIN) ../libcc.dll #else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host +else ifeq ($(HOST),aarch64-linux-gnu) + $(info LINUX ARM 64bit ) + $(CC_ARM64) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES) + cp $(TARGET) ../libcc.so else $(info LINUX) $(CC) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES) diff --git a/src/cc/makecustom b/src/cc/makecustom old mode 100755 new mode 100644 index 7f1c789c9..3516b4023 --- a/src/cc/makecustom +++ b/src/cc/makecustom @@ -1,5 +1,5 @@ #!/bin/sh -if make -f Makefile_custom "$@"; then +if HOST="$HOST" make -B -f Makefile_custom "$@"; then echo CUSTOMCC BUILD SUCCESSFUL else echo CUSTOMCC BUILD FAILED diff --git a/src/cryptoconditions/Makefile.am b/src/cryptoconditions/Makefile.am index 787b11ac6..615ac5783 100644 --- a/src/cryptoconditions/Makefile.am +++ b/src/cryptoconditions/Makefile.am @@ -15,7 +15,7 @@ AM_CFLAGS = -I$(top_srcdir)/src/asn -I$(top_srcdir)/include -I$(top_srcdir)/src/ LIBSECP256K1=src/include/secp256k1/libsecp256k1.la $(LIBSECP256K1): $(wildcard src/secp256k1/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -march:x86-64 -g + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) -g CRYPTOCONDITIONS_CORE=libcryptoconditions_core.la diff --git a/src/cryptoconditions/src/include/secp256k1/Makefile.am b/src/cryptoconditions/src/include/secp256k1/Makefile.am index 52303e4e4..13c83fe18 100644 --- a/src/cryptoconditions/src/include/secp256k1/Makefile.am +++ b/src/cryptoconditions/src/include/secp256k1/Makefile.am @@ -71,7 +71,7 @@ endif endif libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -march=x86-64 -g +libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) -g libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c diff --git a/zcutil/build-cross-aarch64.sh b/zcutil/build-cross-aarch64.sh new file mode 100644 index 000000000..eea5af471 --- /dev/null +++ b/zcutil/build-cross-aarch64.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright (c) 2019-2020 radix42 +# Copyright (c) 2019-2020 The Hush developers +# Original aarch64 port by radix42. Thank you! + +set -eu -o pipefail + +cat <<'EOF' + ________________ +< Building Hush! > + ---------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +EOF + +if [ "x$*" = 'x--help' ] +then + cat ./zcutil/dragon.txt + cat < Date: Sun, 12 Jul 2020 12:55:58 +0200 Subject: [PATCH 205/220] make crossbuild script executable --- zcutil/build-cross-aarch64.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 zcutil/build-cross-aarch64.sh diff --git a/zcutil/build-cross-aarch64.sh b/zcutil/build-cross-aarch64.sh old mode 100644 new mode 100755 From c12ec78caf29a030a332cbfef428727f02ec45e2 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Sun, 12 Jul 2020 13:35:31 +0200 Subject: [PATCH 206/220] executable permissions on makecustom script --- src/cc/makecustom | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/cc/makecustom diff --git a/src/cc/makecustom b/src/cc/makecustom old mode 100644 new mode 100755 From cbf0351e98b97de39881d5182156001cf890ce48 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 13 Jul 2020 14:03:37 -0400 Subject: [PATCH 207/220] Show shielded spends in getchaintxstats output --- src/rpc/blockchain.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3bdce7eb2..6e2efbd57 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1904,6 +1904,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk " \"nullifiers\": xxxxx, (numeric) The total number of shielded nullifiers in the chain up to that point.\n" " \"shielded_txcount\": xxxxx, (numeric) The total number of shielded (containing a zaddr) transactions in the chain up to that point.\n" " \"shielded_outputs\": xxxxx, (numeric) The total number of shielded outputs in the chain up to that point.\n" + " \"shielded_spends\": xxxxx, (numeric) The total number of shielded spends in the chain up to that point.\n" " \"shielded_pool_size\": xxxxx, (numeric) The total number of unspent shielded outputs, i.e. the Shielded Pool or Anonymity Set (anonset).\n" " \"shielding_txcount\": xxxxx, (numeric) The total number of shielding (containing a zaddr output) transactions in the chain up to that point.\n" " \"deshielding_txcount\": xxxxx, (numeric) The total number of deshielding (containing a zaddr input) transactions in the chain up to that point.\n" @@ -2007,6 +2008,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk ret.pushKV("nullifiers", (int64_t)nullifierCount); ret.pushKV("shielded_pool_size", (int64_t)(pindex->nChainShieldedOutputs - pindex->nChainShieldedSpends)); ret.pushKV("shielded_outputs", (int64_t)pindex->nChainShieldedOutputs); + ret.pushKV("shielded_spends", (int64_t)pindex->nChainShieldedSpends); } if (blockcount > 0) { From 6017bdba7954ba03841b9a8aa51deafff4a71c45 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Thu, 16 Jul 2020 19:24:30 +0200 Subject: [PATCH 208/220] cryptoconditions: ugly workaround to fix memory access issues on aarch64 --- src/cryptoconditions/src/asn/OCTET_STRING.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cryptoconditions/src/asn/OCTET_STRING.c b/src/cryptoconditions/src/asn/OCTET_STRING.c index 5420dedec..a886ff8fa 100644 --- a/src/cryptoconditions/src/asn/OCTET_STRING.c +++ b/src/cryptoconditions/src/asn/OCTET_STRING.c @@ -1714,7 +1714,9 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { OCTET_STRING_t *st = (OCTET_STRING_t *)sptr; asn_OCTET_STRING_specifics_t *specs; asn_struct_ctx_t *ctx; +#if !defined(__aarch64__) struct _stack *stck; +#endif if(!td || !st) return; @@ -1731,6 +1733,15 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { st->buf = 0; } +/* Attention !!! + * this is quick & dirty workaround for memory corruption bug on aarch64-linux-gnu + * - downside: allows memory leakage + * - issue description: On Raspberry Pi 4 @ 64bit linux, daemon crashes with "free(): invalid pointer" error + * - probable cause: misaligned memory access to nested structs containing pointers + * - TODO: use the latest asn1c compiler on CryptoConditions.asn, maybe generate cpp instead of c code... investigation in progress + */ + +#if !defined(__aarch64__) /* * Remove decode-time stack. */ @@ -1747,6 +1758,7 @@ OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { if(!contents_only) { FREEMEM(st); } +#endif } /* From b1de0a7f86d4d658ec892dc3ec0a54b099d0bc94 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Thu, 16 Jul 2020 23:35:43 +0200 Subject: [PATCH 209/220] proton lib removed --- configure.ac | 27 -- contrib/amqp/amqp_sub.py | 48 --- contrib/debian/copyright | 220 -------------- contrib/gitian-descriptors/gitian-linux.yml | 2 +- depends/Makefile | 3 +- depends/packages/packages.mk | 8 +- depends/packages/proton.mk | 24 -- depends/patches/proton/minimal-build.patch | 314 -------------------- doc/amqp.md | 123 -------- qa/pull-tester/rpc-tests.sh | 4 - qa/rpc-tests/proton_test.py | 117 -------- src/Makefile.am | 21 -- src/Makefile.gtest.include | 5 - src/Makefile.test.include | 4 - src/amqp/amqpabstractnotifier.cpp | 21 -- src/amqp/amqpabstractnotifier.h | 43 --- src/amqp/amqpconfig.h | 33 -- src/amqp/amqpnotificationinterface.cpp | 136 --------- src/amqp/amqpnotificationinterface.h | 36 --- src/amqp/amqppublishnotifier.cpp | 177 ----------- src/amqp/amqppublishnotifier.h | 56 ---- src/amqp/amqpsender.h | 115 ------- src/init.cpp | 39 --- zcutil/build-arm.sh | 2 +- zcutil/build-mac.sh | 2 +- zcutil/build.sh | 15 +- 26 files changed, 8 insertions(+), 1587 deletions(-) delete mode 100644 contrib/amqp/amqp_sub.py delete mode 100644 depends/packages/proton.mk delete mode 100644 depends/patches/proton/minimal-build.patch delete mode 100644 doc/amqp.md delete mode 100755 qa/rpc-tests/proton_test.py delete mode 100644 src/amqp/amqpabstractnotifier.cpp delete mode 100644 src/amqp/amqpabstractnotifier.h delete mode 100644 src/amqp/amqpconfig.h delete mode 100644 src/amqp/amqpnotificationinterface.cpp delete mode 100644 src/amqp/amqpnotificationinterface.h delete mode 100644 src/amqp/amqppublishnotifier.cpp delete mode 100644 src/amqp/amqppublishnotifier.h delete mode 100644 src/amqp/amqpsender.h diff --git a/configure.ac b/configure.ac index f0474aec0..ace3612da 100644 --- a/configure.ac +++ b/configure.ac @@ -96,12 +96,6 @@ AC_ARG_ENABLE([mining], [enable_mining=$enableval], [enable_mining=yes]) -AC_ARG_ENABLE([proton], - [AS_HELP_STRING([--disable-proton], - [disable Proton (AMQP messaging)])], - [use_proton=$enableval], - [use_proton=yes]) - AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), [use_tests=$enableval], @@ -605,23 +599,6 @@ if test x$enable_wallet != xno; then BITCOIN_FIND_BDB62 fi -dnl Check Qpid Proton headers and library exist -if test x$use_proton = xyes; then - AC_CHECK_HEADERS([proton/connection.hpp], - [], - [AC_MSG_WARN([Proton headers not found, disabling Proton support]) - use_proton=no]) - AC_CHECK_LIB([qpid-proton-cpp], [main], - [PROTON_LIBS="-lqpid-proton-cpp -lqpid-proton"], - [AC_MSG_WARN([Proton libraries not found, disabling Proton support]) - use_proton=no]) -fi -if test x$use_proton = xyes; then - AC_DEFINE(ENABLE_PROTON, 1, [Define to 1 to enable Proton functions]) -else - AC_DEFINE(ENABLE_PROTON, 0, [Define to 1 to enable Proton functions]) -fi - if test x$build_bitcoin_utils$build_bitcoind$use_tests = xnonono; then use_boost=no else @@ -849,8 +826,6 @@ fi AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) -AM_CONDITIONAL([ENABLE_PROTON], [test "x$use_proton" = "xyes"]) - AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) @@ -923,7 +898,6 @@ AC_SUBST(ZMQ_LIBS) AC_SUBST(GMP_LIBS) AC_SUBST(GMPXX_LIBS) AC_SUBST(LIBZCASH_LIBS) -AC_SUBST(PROTON_LIBS) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests-config.sh],[chmod +x qa/pull-tester/tests-config.sh]) @@ -970,7 +944,6 @@ esac echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" -echo " with proton = $use_proton" echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " debug enabled = $enable_debug" diff --git a/contrib/amqp/amqp_sub.py b/contrib/amqp/amqp_sub.py deleted file mode 100644 index bc51e8428..000000000 --- a/contrib/amqp/amqp_sub.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2017 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# Requirements: -# pip install python-qpid-proton - -import binascii -from proton.handlers import MessagingHandler -from proton.reactor import Container - -port = 5672 - -class Server(MessagingHandler): - def __init__(self, url): - super(Server, self).__init__() - self.url = url - self.senders = {} - - def on_start(self, event): - print "Listening on:", self.url - self.container = event.container - self.acceptor = event.container.listen(self.url) - - def on_message(self, event): - m = event.message - topic = m.subject - body = m.body - sequence = str( m.properties['x-opt-sequence-number'] ) - if topic == "hashablock": - print '- HASH BLOCK ('+sequence+') -' - print binascii.hexlify(body) - elif topic == "hashtx": - print '- HASH TX ('+sequence+') -' - print binascii.hexlify(body) - elif topic == "rawblock": - print '- RAW BLOCK HEADER ('+sequence+') -' - print binascii.hexlify(body[:80]) - elif topic == "rawtx": - print '- RAW TX ('+sequence+') -' - print binascii.hexlify(body) - -try: - Container(Server("127.0.0.1:%i" % port)).run() -except KeyboardInterrupt: - pass - diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 9371b7022..2f51f4a4c 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -52,10 +52,6 @@ Files: depends/sources/google*.tar.gz Copyright: 2008 Google Inc. License: BSD-3clause-Google -Files: depends/sources/qpid-proton-*.tar.gz -Copyright: 2012-2017 The Apache Software Foundation -License: Apache-Qpid-Proton-with-BSD-Subcomponents - Files: src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 Copyright: 2008 Don Anderson License: GNU-All-permissive-License @@ -1101,222 +1097,6 @@ Comment: You should have received a copy of the GNU General Public License along with this program. If not, see . -License: Apache-Qpid-Proton-with-BSD-Subcomponents - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - . - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - . - 1. Definitions. - . - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - . - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - . - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - . - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - . - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - . - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - . - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - . - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - . - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - . - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - . - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - . - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - . - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - . - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - . - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - . - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - . - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - . - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - . - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - . - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - . - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - . - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - . - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - . - END OF TERMS AND CONDITIONS - . - APPENDIX: How to apply the Apache License to your work. - . - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - . - Copyright [yyyy] [name of copyright owner] - . - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - . - http://www.apache.org/licenses/LICENSE-2.0 - . - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - . - . - PROTON SUBCOMPONENTS: - . - Proton includes freegetopt with a separate BSD license. Your use - of the source code for freegetopt is subject to the terms and - conditions of its license in examples/include/pncompat/internal/LICENSE. - . - The setup scripts for the python bindings include files derived by - PyZMQ and are licensed with a separate Modified BSD license. Use of - the source code in these setup files are subject to the terms and - conditions in the license: - proton-c/bindings/python/setuputils/PYZMQ_LICENSE.BSD. - License: GNU-All-permissive-License Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index c619cf270..317bd8694 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -85,7 +85,7 @@ script: | BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do - NO_PROTON="x" make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries diff --git a/depends/Makefile b/depends/Makefile index 9d53bd1be..82acde0ac 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -74,9 +74,8 @@ include builders/default.mk include packages/packages.mk wallet_packages_$(NO_WALLET) = $(wallet_packages) -proton_packages_$(NO_PROTON) = $(proton_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages) $(proton_packages_) $(wallet_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages) $(wallet_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) all_packages = $(packages) $(native_packages) diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 8a56f73f3..9c76166af 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,10 +1,4 @@ -ifeq ($(build_os),darwin) - zcash_packages := libgmp libsodium utfcpp -else - proton_packages := proton - zcash_packages := libgmp libsodium utfcpp -endif - +zcash_packages := libgmp libsodium utfcpp rust_crates := \ crate_aes \ crate_aesni \ diff --git a/depends/packages/proton.mk b/depends/packages/proton.mk deleted file mode 100644 index d974fa5fa..000000000 --- a/depends/packages/proton.mk +++ /dev/null @@ -1,24 +0,0 @@ -package=proton -$(package)_version=0.30.0 -$(package)_download_path=https://archive.apache.org/dist/qpid/proton/$($(package)_version) -$(package)_file_name=qpid-proton-$($(package)_version).tar.gz -$(package)_sha256_hash=e37fd8fb13391c3996f927839969a8f66edf35612392d0611eeac6e39e48dd33 -$(package)_patches=minimal-build.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/minimal-build.patch && \ - mkdir -p build/proton-c/src -endef - -define $(package)_config_cmds - cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_RUBY=OFF -DBUILD_GO=OFF -DBUILD_STATIC_LIBS=ON -DLIB_SUFFIX= -DENABLE_JSONCPP= -endef - -define $(package)_build_cmds - cd build; $(MAKE) VERBOSE=1 -endef - -define $(package)_stage_cmds - cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install -endef - diff --git a/depends/patches/proton/minimal-build.patch b/depends/patches/proton/minimal-build.patch deleted file mode 100644 index dd138d2f6..000000000 --- a/depends/patches/proton/minimal-build.patch +++ /dev/null @@ -1,314 +0,0 @@ -diff -ur a/c/CMakeLists.txt b/c/CMakeLists.txt ---- a/c/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 -+++ b/c/CMakeLists.txt 2020-01-08 16:15:26.837987469 -0700 -@@ -428,18 +428,18 @@ - # Can't use target_link_libraries() because cmake 2.8.12 doesn't allow object libraries as the first param - # otherwise for cmake 3.9 and on this would be: - # target_link_libraries (qpid-proton-core-objects ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) --target_compile_definitions(qpid-proton-core-objects PRIVATE $) --target_compile_options (qpid-proton-core-objects PRIVATE $) --target_include_directories(qpid-proton-core-objects PRIVATE $) -- --add_library (qpid-proton-core SHARED $) --target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) --set_target_properties (qpid-proton-core -- PROPERTIES -- VERSION "${PN_LIB_CORE_VERSION}" -- SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}" -- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" --) -+#target_compile_definitions(qpid-proton-core-objects PRIVATE $) -+#target_compile_options (qpid-proton-core-objects PRIVATE $) -+#target_include_directories(qpid-proton-core-objects PRIVATE $) -+ -+#add_library (qpid-proton-core SHARED $) -+#target_link_libraries (qpid-proton-core ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS}) -+#set_target_properties (qpid-proton-core -+# PROPERTIES -+# VERSION "${PN_LIB_CORE_VERSION}" -+# SOVERSION "${PN_LIB_CORE_MAJOR_VERSION}" -+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -+#) - - if (BUILD_STATIC_LIBS) - add_library (qpid-proton-core-static STATIC ${qpid-proton-core-src}) -@@ -454,14 +454,14 @@ - ${qpid-proton-include-extra} - ) - --add_library (qpid-proton SHARED $ ${qpid-proton-noncore-src}) --target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS}) --set_target_properties (qpid-proton -- PROPERTIES -- VERSION "${PN_LIB_LEGACY_VERSION}" -- SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}" -- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" --) -+# add_library (qpid-proton SHARED $ ${qpid-proton-noncore-src}) -+# target_link_libraries (qpid-proton LINK_PRIVATE ${SSL_LIB} ${SASL_LIB} ${TIME_LIB} ${PLATFORM_LIBS} ${PROACTOR_LIBS}) -+# set_target_properties (qpid-proton -+# PROPERTIES -+# VERSION "${PN_LIB_LEGACY_VERSION}" -+# SOVERSION "${PN_LIB_LEGACY_MAJOR_VERSION}" -+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -+# ) - - if (BUILD_STATIC_LIBS) - add_library(qpid-proton-static STATIC ${qpid-proton-core-src} ${qpid-proton-noncore-src}) -@@ -482,15 +482,15 @@ - - if (qpid-proton-proactor) - set(HAS_PROACTOR True) -- add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor}) -- target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core) -- target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS}) -- set_target_properties (qpid-proton-proactor -- PROPERTIES -- VERSION "${PN_LIB_PROACTOR_VERSION}" -- SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}" -- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -- ) -+ # add_library (qpid-proton-proactor SHARED ${qpid-proton-proactor}) -+ # target_link_libraries (qpid-proton-proactor LINK_PUBLIC qpid-proton-core) -+ # target_link_libraries (qpid-proton-proactor LINK_PRIVATE ${PLATFORM_LIBS} ${PROACTOR_LIBS}) -+ # set_target_properties (qpid-proton-proactor -+ # PROPERTIES -+ # VERSION "${PN_LIB_PROACTOR_VERSION}" -+ # SOVERSION "${PN_LIB_PROACTOR_MAJOR_VERSION}" -+ # LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -+ # ) - if (BUILD_STATIC_LIBS) - add_library (qpid-proton-proactor-static STATIC ${qpid-proton-proactor}) - endif(BUILD_STATIC_LIBS) -@@ -500,11 +500,11 @@ - if (BUILD_STATIC_LIBS) - set(STATIC_LIBS qpid-proton-static qpid-proton-core-static) - endif() --install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS} -- EXPORT proton -- RUNTIME DESTINATION bin -- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -+# install(TARGETS qpid-proton qpid-proton-core ${STATIC_LIBS} -+# EXPORT proton -+# RUNTIME DESTINATION bin -+# ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -+# LIBRARY DESTINATION ${LIB_INSTALL_DIR}) - - # Install windows pdb files - if (MSVC) -@@ -520,11 +520,11 @@ - if (BUILD_STATIC_LIBS) - set(STATIC_LIBS qpid-proton-proactor-static) - endif() -- install(TARGETS qpid-proton-proactor ${STATIC_LIBS} -- EXPORT proton -- RUNTIME DESTINATION bin -- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -+ # install(TARGETS qpid-proton-proactor ${STATIC_LIBS} -+ # EXPORT proton -+ # RUNTIME DESTINATION bin -+ # ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -+ # LIBRARY DESTINATION ${LIB_INSTALL_DIR}) - - # Install windows pdb files - if (MSVC) -@@ -576,10 +576,10 @@ - ${CMAKE_CURRENT_BINARY_DIR}/ProtonConfigVersion.cmake - DESTINATION ${LIB_INSTALL_DIR}/cmake/Proton) - --add_subdirectory(docs) --add_subdirectory(examples) --add_subdirectory(tests) --add_subdirectory(tools) -+# add_subdirectory(docs) -+# add_subdirectory(examples) -+# add_subdirectory(tests) -+# add_subdirectory(tools) - - install (DIRECTORY examples/ - DESTINATION "${PROTON_SHARE}/examples/c" -diff -ur a/CMakeLists.txt b/CMakeLists.txt ---- a/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 -+++ b/CMakeLists.txt 2019-12-19 18:11:57.128248724 -0700 -@@ -24,7 +24,7 @@ - set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules") - set (CMAKE_THREAD_PREFER_PTHREAD TRUE) - --include (CTest) -+# include (CTest) - include (CheckLanguage) - include (CheckLibraryExists) - include (CheckSymbolExists) -@@ -33,13 +33,13 @@ - find_package (OpenSSL) - find_package (Threads) - find_package (PythonInterp REQUIRED) --find_package (SWIG) -+# find_package (SWIG) - find_package (CyrusSASL) - --enable_testing () -+#enable_testing () - - # Set up runtime checks (valgrind, sanitizers etc.) --include(tests/RuntimeCheck.cmake) -+# include(tests/RuntimeCheck.cmake) - - ## Variables used across components - -@@ -260,7 +260,7 @@ - - set (SYSINSTALL_BINDINGS OFF CACHE BOOL "If SYSINSTALL_BINDINGS is OFF then proton bindings will be installed underneath ${BINDINGS_DIR} and each user will need to modify their interpreter configuration to load the appropriate binding. If SYSINSTALL_BINDINGS is ON, then each language interpreter will be queried for the appropriate directory and proton bindings will be installed and available system wide with no additional per user configuration.") - --set (BINDING_LANGS PYTHON RUBY) -+# set (BINDING_LANGS PYTHON RUBY) - - foreach (LANG ${BINDING_LANGS}) - set (SYSINSTALL_${LANG} OFF CACHE BOOL "Install ${LANG} bindings into interpreter specified location.") -@@ -315,7 +315,7 @@ - endif() - - # Prerequisites for Go --find_program(GO_EXE go) -+# find_program(GO_EXE go) - mark_as_advanced(GO_EXE) - if (GO_EXE) - set (DEFAULT_GO ON) -diff -ur a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt ---- a/cpp/CMakeLists.txt 2019-12-09 07:17:00.000000000 -0700 -+++ b/cpp/CMakeLists.txt 2020-01-08 16:20:18.855394195 -0700 -@@ -174,30 +174,30 @@ - set (CMAKE_DEBUG_POSTFIX "d") - endif () - --add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source}) -+# add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source}) - if(BUILD_STATIC_LIBS) - add_library(qpid-proton-cpp-static STATIC ${qpid-proton-cpp-source}) - set(STATIC_LIBS qpid-proton-cpp-static) - endif(BUILD_STATIC_LIBS) - --target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS}) -+# target_link_libraries (qpid-proton-cpp LINK_PRIVATE ${PLATFORM_LIBS} qpid-proton-core qpid-proton-proactor ${CONNECT_CONFIG_LIBS}) - --set_target_properties ( -- qpid-proton-cpp -- PROPERTIES -- LINKER_LANGUAGE CXX -- VERSION "${PN_LIB_CPP_VERSION}" -- SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}" -- LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -- ) -+# set_target_properties ( -+# qpid-proton-cpp -+# PROPERTIES -+# LINKER_LANGUAGE CXX -+# VERSION "${PN_LIB_CPP_VERSION}" -+# SOVERSION "${PN_LIB_CPP_MAJOR_VERSION}" -+# LINK_FLAGS "${CATCH_UNDEFINED} ${LTO}" -+# ) - - ## Install - --install(TARGETS qpid-proton-cpp ${STATIC_LIBS} -- EXPORT proton-cpp -- RUNTIME DESTINATION bin -- ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -- LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -+# install(TARGETS qpid-proton-cpp ${STATIC_LIBS} -+# EXPORT proton-cpp -+# RUNTIME DESTINATION bin -+# ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -+# LIBRARY DESTINATION ${LIB_INSTALL_DIR}) - - # Install windows qpid-proton-cpp pdb files - if (MSVC) -@@ -209,12 +209,12 @@ - - install (DIRECTORY "include/proton" DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.hpp") - install (FILES "${CMAKE_CURRENT_BINARY_DIR}/config_presets.hpp" DESTINATION "${INCLUDE_INSTALL_DIR}/proton/internal") --install (DIRECTORY "examples/" -- DESTINATION "${PROTON_SHARE}/examples/cpp" -- USE_SOURCE_PERMISSIONS -- PATTERN "ProtonCppConfig.cmake" EXCLUDE) -+# install (DIRECTORY "examples/" -+# DESTINATION "${PROTON_SHARE}/examples/cpp" -+# USE_SOURCE_PERMISSIONS -+# PATTERN "ProtonCppConfig.cmake" EXCLUDE) - --add_subdirectory(examples) -+# add_subdirectory(examples) - add_subdirectory(docs) - - # Pkg config file -@@ -268,40 +268,40 @@ - set(test_env ${test_env} "PATH=$") - endif() - --macro(add_cpp_test test) -- add_executable (${test} src/${test}.cpp) -- target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS}) -- add_test (NAME cpp-${test} -- COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $ ${ARGN}) --endmacro(add_cpp_test) -- --add_cpp_test(codec_test) --add_cpp_test(connection_driver_test) --add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) --add_cpp_test(message_test) --add_cpp_test(map_test) --add_cpp_test(scalar_test) --add_cpp_test(value_test) --add_cpp_test(container_test) --add_cpp_test(reconnect_test) --add_cpp_test(link_test) --add_cpp_test(credit_test) --if (ENABLE_JSONCPP) -- add_cpp_test(connect_config_test) -- target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled -- set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -- # Test data and output directories for connect_config_test -- file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") --endif() -+# macro(add_cpp_test test) -+# add_executable (${test} src/${test}.cpp) -+# target_link_libraries (${test} qpid-proton-cpp ${PLATFORM_LIBS}) -+# add_test (NAME cpp-${test} -+# COMMAND ${PN_ENV_SCRIPT} -- ${test_env} ${TEST_EXE_PREFIX_CMD} $ ${ARGN}) -+# endmacro(add_cpp_test) -+# -+# add_cpp_test(codec_test) -+# add_cpp_test(connection_driver_test) -+# add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) -+# add_cpp_test(message_test) -+# add_cpp_test(map_test) -+# add_cpp_test(scalar_test) -+# add_cpp_test(value_test) -+# add_cpp_test(container_test) -+# add_cpp_test(reconnect_test) -+# add_cpp_test(link_test) -+# add_cpp_test(credit_test) -+# if (ENABLE_JSONCPP) -+# add_cpp_test(connect_config_test) -+# target_link_libraries(connect_config_test qpid-proton-core) # For pn_sasl_enabled -+# set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -+# # Test data and output directories for connect_config_test -+# file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") -+# endif() - - # TODO aconway 2018-10-31: Catch2 tests - # This is a simple example of a C++ test using the Catch2 framework. - # See c/tests/ for more interesting examples. - # Eventually all the C++ tests will migrate to Catch2. - --include_directories(${CMAKE_SOURCE_DIR}/tests/include) --add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp) --target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS}) -+#include_directories(${CMAKE_SOURCE_DIR}/tests/include) -+#add_executable(cpp-test src/cpp-test.cpp src/url_test.cpp) -+#target_link_libraries(cpp-test qpid-proton-cpp ${PLATFORM_LIBS}) - - macro(add_catch_test tag) - add_test ( diff --git a/doc/amqp.md b/doc/amqp.md deleted file mode 100644 index 431fa55b1..000000000 --- a/doc/amqp.md +++ /dev/null @@ -1,123 +0,0 @@ -# Block and Transaction Broadcasting With AMQP 1.0 (Experimental Feature) - -[AMQP](https://www.amqp.org/) is an enterprise-level message queuing -protocol for the reliable passing of real-time data and business -transactions between applications. AMQP supports both broker and -brokerless messaging. AMQP 1.0 is an open standard and has been -ratified as ISO/IEC 19464. - -The Hush daemon can be configured to act as a trusted "border -router", implementing the Hush P2P protocol and relay, making -consensus decisions, maintaining the local blockchain database, -broadcasting locally generated transactions into the network, and -providing a queryable RPC interface to interact on a polled basis for -requesting blockchain related data. However, there exists only a -limited service to notify external software of events like the arrival -of new blocks or transactions. - -The AMQP facility implements a notification interface through a set -of specific notifiers. Currently there are notifiers that publish -blocks and transactions. This read-only facility requires only the -connection of a corresponding AMQP subscriber port in receiving -software. - -Currently the facility is not authenticated nor is there any two-way -protocol involvement. Therefore, subscribers should validate the -received data since it may be out of date, incomplete or even invalid. - -Because AMQP is message oriented, subscribers receive transactions -and blocks all-at-once and do not need to implement any sort of -buffering or reassembly. - -## Prerequisites - -The AMQP feature in Hush requires [Qpid Proton](https://qpid.apache.org/proton/) -version 0.17 or newer, which you will need to install if you are not -using the depends system. Typically, it is packaged by distributions as -something like *libqpid-proton*. The C++ wrapper for AMQP *is* required. - -In order to run the example Python client scripts in contrib/ one must -also install *python-qpid-proton*, though this is not necessary for -daemon operation. - -## Enabling - -By default, the AMQP feature is automatically compiled in if the -necessary prerequisites are found. To disable, use --disable-proton -during the *configure* step of building zcashd: - - $ ./configure --disable-proton (other options) - -To actually enable operation, one must set the appropriate options on -the commandline or in the configuration file. - -## Usage - -AMQP support is currently an experimental feature, so you must pass -the option: - - -experimentalfeatures - -Currently, the following notifications are supported: - - -amqppubhashtx=address - -amqppubhashblock=address - -amqppubrawblock=address - -amqppubrawtx=address - -The address must be a valid AMQP address, where the same address can be -used in more than notification. Note that SSL and SASL addresses are -not currently supported. - -Launch zcashd like this: - - $ zcashd -amqppubhashtx=amqp://127.0.0.1:5672 - -Or this: - - $ zcashd -amqppubhashtx=amqp://127.0.0.1:5672 \ - -amqppubrawtx=amqp://127.0.0.1:5672 \ - -amqppubrawblock=amqp://127.0.0.1:5672 \ - -amqppubhashblock=amqp://127.0.0.1:5672 \ - -debug=amqp - -The debug category `amqp` enables AMQP-related logging. - -Each notification has a topic and body, where the header corresponds -to the notification type. For instance, for the notification `-amqpubhashtx` -the topic is `hashtx` (no null terminator) and the body is the hexadecimal -transaction hash (32 bytes). This transaction hash and the block hash -found in `hashblock` are in RPC byte order. - -These options can also be provided in zcash.conf. - -Please see `contrib/amqp/amqp_sub.py` for a working example of an -AMQP server listening for messages. - -## Remarks - -From the perspective of zcashd, the local end of an AMQP link is write-only. - -No information is broadcast that wasn't already received from the public -P2P network. - -No authentication or authorization is done on peers that zcashd connects -to; it is assumed that the AMQP link is exposed only to trusted entities, -using other means such as firewalling. - -TLS support may be added once OpenSSL has been removed from the Hush -project and alternative TLS implementations have been evaluated. - -SASL support may be added in a future update for secure communication. - -Note that when the block chain tip changes, a reorganisation may occur -and just the tip will be notified. It is up to the subscriber to -retrieve the chain from the last known block to the new tip. - -At present, zcashd does not try to resend a notification if there was -a problem confirming receipt. Support for delivery guarantees such as -*at-least-once* and *exactly-once* will be added in in a future update. - -Currently, zcashd appends an up-counting sequence number to each notification -which allows listeners to detect lost notifications. - diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 35bf5a7e9..4af883ea3 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -96,10 +96,6 @@ if [ "x$ENABLE_ZMQ" = "x1" ]; then testScripts+=('zmq_test.py') fi -if [ "x$ENABLE_PROTON" = "x1" ]; then - testScripts+=('proton_test.py') -fi - extArg="-extended" passOn=${@#$extArg} diff --git a/qa/rpc-tests/proton_test.py b/qa/rpc-tests/proton_test.py deleted file mode 100755 index d9fb27bd3..000000000 --- a/qa/rpc-tests/proton_test.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2017 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# -# Test Proton interface (provides AMQP 1.0 messaging support). -# -# Requirements: -# Python library for Qpid Proton: -# https://pypi.python.org/pypi/python-qpid-proton -# To install: -# pip install python-qpid-proton -# - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, bytes_to_hex_str, \ - start_nodes - -from proton.handlers import MessagingHandler -from proton.reactor import Container - -import threading - - -class Server(MessagingHandler): - - def __init__(self, url, limit): - super(Server, self).__init__() - self.url = url - self.counter = limit - self.blockhashes = [] - self.txids = [] - self.blockseq = -1 - self.txidseq = -1 - - def on_start(self, event): - print "Proton listening on:", self.url - self.container = event.container - self.acceptor = event.container.listen(self.url) - - def on_message(self, event): - m = event.message - hash = bytes_to_hex_str(m.body) - sequence = m.properties['x-opt-sequence-number'] - if m.subject == "hashtx": - self.txids.append(hash) - - # Test that sequence id is incrementing - assert(sequence == 1 + self.txidseq) - self.txidseq = sequence - elif m.subject == "hashblock": - self.blockhashes.append(hash) - - # Test that sequence id is incrementing - assert(sequence == 1 + self.blockseq) - self.blockseq = sequence - - self.counter = self.counter - 1 - if self.counter == 0: - self.container.stop() - - -class ProtonTest (BitcoinTestFramework): - - port = 25672 - numblocks = 10 # must be even, as two nodes generate equal number - assert(numblocks % 2 == 0) - - def setup_nodes(self): - - # Launch proton server in background thread - # It terminates after receiving numblocks * 2 messages (one for coinbase, one for block) - self.server = Server("127.0.0.1:%i" % self.port, self.numblocks * 2) - self.container = Container(self.server) - self.t1 = threading.Thread(target=self.container.run) - self.t1.start() - - return start_nodes(4, self.options.tmpdir, extra_args=[ - ['-experimentalfeatures', '-debug=amqp', '-amqppubhashtx=amqp://127.0.0.1:'+str(self.port), - '-amqppubhashblock=amqp://127.0.0.1:'+str(self.port)], - [], - [], - [] - ]) - - def run_test(self): - self.sync_all() - baseheight = self.nodes[0].getblockcount() # 200 blocks already mined - - # generate some blocks - self.nodes[0].generate(self.numblocks/2) - self.sync_all() - self.nodes[1].generate(self.numblocks/2) - self.sync_all() - - # wait for server to finish - self.t1.join() - - # sequence numbers have already been checked in the server's message handler - - # sanity check that we have the right number of block hashes and coinbase txids - assert_equal(len(self.server.blockhashes), self.numblocks) - assert_equal(len(self.server.txids), self.numblocks) - - # verify that each block has the correct coinbase txid - for i in xrange(0, self.numblocks): - height = baseheight + i + 1 - blockhash = self.nodes[0].getblockhash(height) - assert_equal(blockhash, self.server.blockhashes[i]) - resp = self.nodes[0].getblock(blockhash) - coinbase = resp["tx"][0] - assert_equal(coinbase, self.server.txids[i]) - - -if __name__ == '__main__': - ProtonTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index eb41a0031..88e33df95 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,9 +54,6 @@ LIBZCASH=libzcash.a if ENABLE_ZMQ LIBBITCOIN_ZMQ=libbitcoin_zmq.a endif -if ENABLE_PROTON -LIBBITCOIN_PROTON=libbitcoin_proton.a -endif if BUILD_BITCOIN_LIBS LIBZCASH_CONSENSUS=libzcashconsensus.la endif @@ -89,9 +86,6 @@ endif if ENABLE_ZMQ EXTRA_LIBRARIES += $(LIBBITCOIN_ZMQ) endif -if ENABLE_PROTON -EXTRA_LIBRARIES += $(LIBBITCOIN_PROTON) -endif lib_LTLIBRARIES = $(LIBZCASH_CONSENSUS) @@ -331,15 +325,6 @@ libbitcoin_zmq_a_SOURCES = \ zmq/zmqpublishnotifier.cpp endif -if ENABLE_PROTON -libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES) -libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -libbitcoin_proton_a_SOURCES = \ - amqp/amqpabstractnotifier.cpp \ - amqp/amqpnotificationinterface.cpp \ - amqp/amqppublishnotifier.cpp -endif - # wallet: komodod, but only linked when wallet enabled libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -504,7 +489,6 @@ komodod_LDADD = \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_ZMQ) \ - $(LIBBITCOIN_PROTON) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH) \ $(LIBLEVELDB) \ @@ -524,7 +508,6 @@ komodod_LDADD += \ $(EVENT_PTHREADS_LIBS) \ $(EVENT_LIBS) \ $(ZMQ_LIBS) \ - $(PROTON_LIBS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) @@ -538,10 +521,6 @@ if TARGET_LINUX komodod_LDADD += libcc.so $(LIBSECP256K1) endif -if ENABLE_PROTON -komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) -endif - # [+] Decker: use static linking for libstdc++.6.dylib, libgomp.1.dylib, libgcc_s.1.dylib if TARGET_DARWIN komodod_LDFLAGS += -static-libgcc diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 1f1b511db..b259cbd4b 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -65,11 +65,6 @@ endif komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) -if ENABLE_PROTON -komodo_gtest_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) -endif - - komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 14324b02b..0e2433bfd 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -130,10 +130,6 @@ if ENABLE_ZMQ test_test_bitcoin_LDADD += $(ZMQ_LIBS) endif -if ENABLE_PROTON -test_test_bitcoin_LDADD += $(PROTON_LIBS) -endif - nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) diff --git a/src/amqp/amqpabstractnotifier.cpp b/src/amqp/amqpabstractnotifier.cpp deleted file mode 100644 index 57686ef1d..000000000 --- a/src/amqp/amqpabstractnotifier.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "amqpabstractnotifier.h" -#include "util.h" - - -AMQPAbstractNotifier::~AMQPAbstractNotifier() -{ -} - -bool AMQPAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/) -{ - return true; -} - -bool AMQPAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/) -{ - return true; -} diff --git a/src/amqp/amqpabstractnotifier.h b/src/amqp/amqpabstractnotifier.h deleted file mode 100644 index c993a2b3e..000000000 --- a/src/amqp/amqpabstractnotifier.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H -#define ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H - -#include "amqpconfig.h" - -class CBlockIndex; -class AMQPAbstractNotifier; - -typedef AMQPAbstractNotifier* (*AMQPNotifierFactory)(); - -class AMQPAbstractNotifier -{ -public: - AMQPAbstractNotifier() { } - virtual ~AMQPAbstractNotifier(); - - template - static AMQPAbstractNotifier* Create() - { - return new T(); - } - - std::string GetType() const { return type; } - void SetType(const std::string &t) { type = t; } - std::string GetAddress() const { return address; } - void SetAddress(const std::string &a) { address = a; } - - virtual bool Initialize() = 0; - virtual void Shutdown() = 0; - - virtual bool NotifyBlock(const CBlockIndex *pindex); - virtual bool NotifyTransaction(const CTransaction &transaction); - -protected: - std::string type; - std::string address; -}; - -#endif // ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H diff --git a/src/amqp/amqpconfig.h b/src/amqp/amqpconfig.h deleted file mode 100644 index dcc5f7709..000000000 --- a/src/amqp/amqpconfig.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_AMQP_AMQPCONFIG_H -#define ZCASH_AMQP_AMQPCONFIG_H - -#if defined(HAVE_CONFIG_H) -#include "config/bitcoin-config.h" -#endif - -#include -#include - -#if ENABLE_PROTON -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -#include "primitives/block.h" -#include "primitives/transaction.h" - -#endif // ZCASH_AMQP_AMQPCONFIG_H diff --git a/src/amqp/amqpnotificationinterface.cpp b/src/amqp/amqpnotificationinterface.cpp deleted file mode 100644 index 66f5398ca..000000000 --- a/src/amqp/amqpnotificationinterface.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "amqpnotificationinterface.h" -#include "amqppublishnotifier.h" - -#include "version.h" -#include "main.h" -#include "streams.h" -#include "util.h" - -// AMQP 1.0 Support -// -// The boost::signals2 signals and slot system is thread safe, so CValidationInterface listeners -// can be invoked from any thread. -// -// Currently signals are fired from main.cpp so the callbacks should be invoked on the same thread. -// It should be safe to share objects responsible for sending, as they should not be run concurrently -// across different threads. -// -// Developers should be mindful of where notifications are fired to avoid potential race conditions. -// For example, different signals targeting the same address could be fired from different threads -// in different parts of the system around the same time. -// -// Like the ZMQ notification interface, if a notifier fails to send a message, the notifier is shut down. -// - -AMQPNotificationInterface::AMQPNotificationInterface() -{ -} - -AMQPNotificationInterface::~AMQPNotificationInterface() -{ - Shutdown(); - - for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { - delete *i; - } -} - -AMQPNotificationInterface* AMQPNotificationInterface::CreateWithArguments(const std::map &args) -{ - AMQPNotificationInterface* notificationInterface = nullptr; - std::map factories; - std::list notifiers; - - factories["pubhashblock"] = AMQPAbstractNotifier::Create; - factories["pubhashtx"] = AMQPAbstractNotifier::Create; - factories["pubrawblock"] = AMQPAbstractNotifier::Create; - factories["pubrawtx"] = AMQPAbstractNotifier::Create; - - for (std::map::const_iterator i=factories.begin(); i!=factories.end(); ++i) { - std::map::const_iterator j = args.find("-amqp" + i->first); - if (j!=args.end()) { - AMQPNotifierFactory factory = i->second; - std::string address = j->second; - AMQPAbstractNotifier *notifier = factory(); - notifier->SetType(i->first); - notifier->SetAddress(address); - notifiers.push_back(notifier); - } - } - - if (!notifiers.empty()) { - notificationInterface = new AMQPNotificationInterface(); - notificationInterface->notifiers = notifiers; - - if (!notificationInterface->Initialize()) { - delete notificationInterface; - notificationInterface = nullptr; - } - } - - return notificationInterface; -} - -// Called at startup to conditionally set up -bool AMQPNotificationInterface::Initialize() -{ - LogPrint("amqp", "amqp: Initialize notification interface\n"); - - std::list::iterator i = notifiers.begin(); - for (; i != notifiers.end(); ++i) { - AMQPAbstractNotifier *notifier = *i; - if (notifier->Initialize()) { - LogPrint("amqp", "amqp: Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); - } else { - LogPrint("amqp", "amqp: Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); - break; - } - } - - if (i != notifiers.end()) { - return false; - } - - return true; -} - -// Called during shutdown sequence -void AMQPNotificationInterface::Shutdown() -{ - LogPrint("amqp", "amqp: Shutdown notification interface\n"); - - for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { - AMQPAbstractNotifier *notifier = *i; - notifier->Shutdown(); - } -} - -void AMQPNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) -{ - for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ) { - AMQPAbstractNotifier *notifier = *i; - if (notifier->NotifyBlock(pindex)) { - i++; - } else { - notifier->Shutdown(); - i = notifiers.erase(i); - } - } -} - -void AMQPNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) -{ - for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ) { - AMQPAbstractNotifier *notifier = *i; - if (notifier->NotifyTransaction(tx)) { - i++; - } else { - notifier->Shutdown(); - i = notifiers.erase(i); - } - } -} diff --git a/src/amqp/amqpnotificationinterface.h b/src/amqp/amqpnotificationinterface.h deleted file mode 100644 index 0c07ce235..000000000 --- a/src/amqp/amqpnotificationinterface.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H -#define ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H - -#include "validationinterface.h" -#include -#include - -class CBlockIndex; -class AMQPAbstractNotifier; - -class AMQPNotificationInterface : public CValidationInterface -{ -public: - virtual ~AMQPNotificationInterface(); - - static AMQPNotificationInterface* CreateWithArguments(const std::map &args); - -protected: - bool Initialize(); - void Shutdown(); - - // CValidationInterface - void SyncTransaction(const CTransaction &tx, const CBlock *pblock); - void UpdatedBlockTip(const CBlockIndex *pindex); - -private: - AMQPNotificationInterface(); - - std::list notifiers; -}; - -#endif // ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H diff --git a/src/amqp/amqppublishnotifier.cpp b/src/amqp/amqppublishnotifier.cpp deleted file mode 100644 index 589eb151f..000000000 --- a/src/amqp/amqppublishnotifier.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "amqppublishnotifier.h" -#include "main.h" -#include "util.h" - -#include "amqpsender.h" - -#include -#include - -static std::multimap mapPublishNotifiers; - -static const char *MSG_HASHBLOCK = "hashblock"; -static const char *MSG_HASHTX = "hashtx"; -static const char *MSG_RAWBLOCK = "rawblock"; -static const char *MSG_RAWTX = "rawtx"; - -// Invoke this method from a new thread to run the proton container event loop. -void AMQPAbstractPublishNotifier::SpawnProtonContainer() -{ - try { - proton::default_container(*handler_).run(); - } - catch (const proton::error_condition &e) { - LogPrint("amqp", "amqp: container error: %s\n", e.what()); - } - catch (const std::runtime_error &e) { - LogPrint("amqp", "amqp: runtime error: %s\n", e.what()); - } - catch (const std::exception &e) { - LogPrint("amqp", "amqp: exception: %s\n", e.what()); - } - catch (...) { - LogPrint("amqp", "amqp: unknown error\n"); - } - handler_->terminate(); -} - -bool AMQPAbstractPublishNotifier::Initialize() -{ - std::multimap::iterator i = mapPublishNotifiers.find(address); - - if (i == mapPublishNotifiers.end()) { - try { - handler_ = std::make_shared(address); - thread_ = std::make_shared(&AMQPAbstractPublishNotifier::SpawnProtonContainer, this); - } - catch (std::exception &e) { - LogPrint("amqp", "amqp: initialization error: %s\n", e.what()); - return false; - } - mapPublishNotifiers.insert(std::make_pair(address, this)); - } else { - // copy the shared ptrs to the message handler and the thread where the proton container is running - handler_ = i->second->handler_; - thread_ = i->second->thread_; - mapPublishNotifiers.insert(std::make_pair(address, this)); - } - - return true; -} - - -void AMQPAbstractPublishNotifier::Shutdown() -{ - LogPrint("amqp", "amqp: Shutdown notifier %s at %s\n", GetType(), GetAddress()); - - int count = mapPublishNotifiers.count(address); - - // remove this notifier from the list of publishers using this address - typedef std::multimap::iterator iterator; - std::pair iterpair = mapPublishNotifiers.equal_range(address); - - for (iterator it = iterpair.first; it != iterpair.second; ++it) { - if (it->second == this) { - mapPublishNotifiers.erase(it); - break; - } - } - - // terminate the connection if this is the last publisher using this address - if (count == 1) { - handler_->terminate(); - if (thread_.get() != nullptr) { - if (thread_->joinable()) { - thread_->join(); - } - } - } -} - - -bool AMQPAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size) -{ - try { - proton::binary content; - const char *p = (const char *)data; - content.assign(p, p + size); - - proton::message message(content); - message.subject(std::string(command)); - proton::message::property_map & props = message.properties(); - props.put("x-opt-sequence-number", sequence_); - handler_->publish(message); - - } catch (proton::error_condition &e) { - LogPrint("amqp", "amqp: error : %s\n", e.what()); - return false; - } - catch (const std::runtime_error &e) { - LogPrint("amqp", "amqp: runtime error: %s\n", e.what()); - return false; - } - catch (const std::exception &e) { - LogPrint("amqp", "amqp: exception: %s\n", e.what()); - return false; - } - catch (...) { - LogPrint("amqp", "amqp: unknown error\n"); - return false; - } - - sequence_++; - - return true; -} - -bool AMQPPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) -{ - uint256 hash = pindex->GetBlockHash(); - LogPrint("amqp", "amqp: Publish hashblock %s\n", hash.GetHex()); - char data[32]; - for (unsigned int i = 0; i < 32; i++) - data[31 - i] = hash.begin()[i]; - return SendMessage(MSG_HASHBLOCK, data, 32); -} - -bool AMQPPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) -{ - uint256 hash = transaction.GetHash(); - LogPrint("amqp", "amqp: Publish hashtx %s\n", hash.GetHex()); - char data[32]; - for (unsigned int i = 0; i < 32; i++) - data[31 - i] = hash.begin()[i]; - return SendMessage(MSG_HASHTX, data, 32); -} - -bool AMQPPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) -{ - LogPrint("amqp", "amqp: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - { - LOCK(cs_main); - CBlock block; - if(!ReadBlockFromDisk(block, pindex)) { - LogPrint("amqp", "amqp: Can't read block from disk"); - return false; - } - - ss << block; - } - - return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size()); -} - -bool AMQPPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) -{ - uint256 hash = transaction.GetHash(); - LogPrint("amqp", "amqp: Publish rawtx %s\n", hash.GetHex()); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << transaction; - return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); -} diff --git a/src/amqp/amqppublishnotifier.h b/src/amqp/amqppublishnotifier.h deleted file mode 100644 index 08b3aba08..000000000 --- a/src/amqp/amqppublishnotifier.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H -#define ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H - -#include "amqpabstractnotifier.h" -#include "amqpconfig.h" -#include "amqpsender.h" - -#include -#include - -class CBlockIndex; - -class AMQPAbstractPublishNotifier : public AMQPAbstractNotifier -{ -private: - uint64_t sequence_; // memory only, per notifier instance: upcounting message sequence number - - std::shared_ptr thread_; // proton container thread, may be shared between notifiers - std::shared_ptr handler_; // proton container message handler, may be shared between notifiers - -public: - bool SendMessage(const char *command, const void* data, size_t size); - bool Initialize(); - void Shutdown(); - void SpawnProtonContainer(); -}; - -class AMQPPublishHashBlockNotifier : public AMQPAbstractPublishNotifier -{ -public: - bool NotifyBlock(const CBlockIndex *pindex); -}; - -class AMQPPublishHashTransactionNotifier : public AMQPAbstractPublishNotifier -{ -public: - bool NotifyTransaction(const CTransaction &transaction); -}; - -class AMQPPublishRawBlockNotifier : public AMQPAbstractPublishNotifier -{ -public: - bool NotifyBlock(const CBlockIndex *pindex); -}; - -class AMQPPublishRawTransactionNotifier : public AMQPAbstractPublishNotifier -{ -public: - bool NotifyTransaction(const CTransaction &transaction); -}; - -#endif // ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H diff --git a/src/amqp/amqpsender.h b/src/amqp/amqpsender.h deleted file mode 100644 index 7fa85d89c..000000000 --- a/src/amqp/amqpsender.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2017 The Zcash developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef ZCASH_AMQP_AMQPSENDER_H -#define ZCASH_AMQP_AMQPSENDER_H - -#include "amqpconfig.h" - -#include -#include -#include -#include - -class AMQPSender : public proton::messaging_handler { - private: - std::deque messages_; - proton::url url_; - proton::connection conn_; - proton::sender sender_; - std::mutex lock_; - std::atomic terminated_ = {false}; - - public: - - AMQPSender(const std::string& url) : url_(url) {} - - // Callback to initialize the container when run() is invoked - void on_container_start(proton::container& c) override { - proton::duration t(10000); // milliseconds - proton::connection_options opts = proton::connection_options().idle_timeout(t); - conn_ = c.connect(url_, opts); - sender_ = conn_.open_sender(url_.path()); - } - - // Remote end signals when the local end can send (i.e. has credit) - void on_sendable(proton::sender &s) override { - dispatch(); - } - - // Publish message by adding to queue and trying to dispatch it - void publish(const proton::message &m) { - add_message(m); - dispatch(); - } - - // Add message to queue - void add_message(const proton::message &m) { - std::lock_guard guard(lock_); - messages_.push_back(m); - } - - // Send messages in queue - void dispatch() { - std::lock_guard guard(lock_); - - if (isTerminated()) { - throw std::runtime_error("amqp connection was terminated"); - } - - if (!conn_.active()) { - throw std::runtime_error("amqp connection is not active"); - } - - while (messages_.size() > 0) { - if (sender_.credit()) { - const proton::message& m = messages_.front(); - sender_.send(m); - messages_.pop_front(); - } else { - break; - } - } - } - - // Close connection to remote end. Container event-loop, by default, will auto-stop. - void terminate() { - std::lock_guard guard(lock_); - conn_.close(); - terminated_.store(true); - } - - bool isTerminated() const { - return terminated_.load(); - } - - void on_transport_error(proton::transport &t) override { - t.connection().close(); - throw t.error(); - } - - void on_connection_error(proton::connection &c) override { - c.close(); - throw c.error(); - } - - void on_session_error(proton::session &s) override { - s.connection().close(); - throw s.error(); - } - - void on_receiver_error(proton::receiver &r) override { - r.connection().close(); - throw r.error(); - } - - void on_sender_error(proton::sender &s) override { - s.connection().close(); - throw s.error(); - } - -}; - - -#endif //ZCASH_AMQP_AMQPSENDER_H diff --git a/src/init.cpp b/src/init.cpp index c43c5b0b4..d52888503 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -84,10 +84,6 @@ #include "zmq/zmqnotificationinterface.h" #endif -#if ENABLE_PROTON -#include "amqp/amqpnotificationinterface.h" -#endif - #include "librustzcash.h" using namespace std; @@ -112,10 +108,6 @@ bool fFeeEstimatesInitialized = false; static CZMQNotificationInterface* pzmqNotificationInterface = NULL; #endif -#if ENABLE_PROTON -static AMQPNotificationInterface* pAMQPNotificationInterface = NULL; -#endif - #ifdef WIN32 // Win32 LevelDB doesn't use file descriptors, and the ones used for // accessing block files don't count towards the fd_set size limit @@ -285,14 +277,6 @@ void Shutdown() } #endif -#if ENABLE_PROTON - if (pAMQPNotificationInterface) { - UnregisterValidationInterface(pAMQPNotificationInterface); - delete pAMQPNotificationInterface; - pAMQPNotificationInterface = NULL; - } -#endif - #ifndef WIN32 try { boost::filesystem::remove(GetPidFile()); @@ -486,14 +470,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-zmqpubrawtx=
", _("Enable publish raw transaction in
")); #endif -#if ENABLE_PROTON - strUsage += HelpMessageGroup(_("AMQP 1.0 notification options:")); - strUsage += HelpMessageOpt("-amqppubhashblock=
", _("Enable publish hash block in
")); - strUsage += HelpMessageOpt("-amqppubhashtx=
", _("Enable publish hash transaction in
")); - strUsage += HelpMessageOpt("-amqppubrawblock=
", _("Enable publish raw block in
")); - strUsage += HelpMessageOpt("-amqppubrawtx=
", _("Enable publish raw transaction in
")); -#endif - strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (showDebug) { @@ -1624,21 +1600,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif -#if ENABLE_PROTON - pAMQPNotificationInterface = AMQPNotificationInterface::CreateWithArguments(mapArgs); - - if (pAMQPNotificationInterface) { - - // AMQP support is currently an experimental feature, so fail if user configured AMQP notifications - // without enabling experimental features. - if (!fExperimentalMode) { - return InitError(_("AMQP support requires -experimentalfeatures.")); - } - - RegisterValidationInterface(pAMQPNotificationInterface); - } -#endif - if ( KOMODO_NSPV_SUPERLITE ) { std::vector vImportFiles; diff --git a/zcutil/build-arm.sh b/zcutil/build-arm.sh index 2131fa7cb..838607c7e 100644 --- a/zcutil/build-arm.sh +++ b/zcutil/build-arm.sh @@ -51,7 +51,7 @@ PREFIX="$(pwd)/depends/aarch64-unknown-linux-gnu/" HOST=aarch64-unknown-linux-gnu BUILD=aarch64-unknown-linux-gnu make "$@" -C ./depends/ V=1 NO_QT=1 ./autogen.sh -CONFIG_SITE="$(pwd)/depends/aarch64-unknown-linux-gnu/share/config.site" ./configure --prefix="${PREFIX}" --host=aarch64-unknown-linux-gnu --build=aarch64-unknown-linux-gnu --with-gui=no --enable-rust=no --disable-proton "$HARDENING_ARG" "$LCOV_ARG" CXXFLAGS='-fwrapv -fno-strict-aliasing -g' +CONFIG_SITE="$(pwd)/depends/aarch64-unknown-linux-gnu/share/config.site" ./configure --prefix="${PREFIX}" --host=aarch64-unknown-linux-gnu --build=aarch64-unknown-linux-gnu --with-gui=no --enable-rust=no "$HARDENING_ARG" "$LCOV_ARG" CXXFLAGS='-fwrapv -fno-strict-aliasing -g' #BUILD CCLIB diff --git a/zcutil/build-mac.sh b/zcutil/build-mac.sh index 096ca96e4..12e426e71 100755 --- a/zcutil/build-mac.sh +++ b/zcutil/build-mac.sh @@ -43,7 +43,7 @@ fi TRIPLET=`./depends/config.guess` PREFIX="$(pwd)/depends/$TRIPLET" -make "$@" -C ./depends/ V=1 NO_QT=1 NO_PROTON=1 +make "$@" -C ./depends/ V=1 NO_QT=1 #BUILD CCLIB diff --git a/zcutil/build.sh b/zcutil/build.sh index 76980476b..6b90c0e01 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -58,12 +58,11 @@ Welcome To The Hush Build System, Here Be Dragons! Usage: $0 --help Show this help message and exit. -$0 [ --enable-lcov || --disable-tests ] [ --disable-mining ] [ --enable-proton ] [ --disable-libs ] [ MAKEARGS... ] +$0 [ --enable-lcov || --disable-tests ] [ --disable-mining ] [ --disable-libs ] [ MAKEARGS... ] Build Hush and most of its transitive dependencies from source. MAKEARGS are applied to both dependencies and Hush itself. If --enable-lcov is passed, Hush is configured to add coverage instrumentation, thus enabling "make cov" to work. If --disable-tests is passed instead, the Hush tests are not built. If --disable-mining is passed, Hush is configured to not build any mining code. It must be passed after the test arguments, if present. - If --enable-proton is passed, Hush is configured to build the Apache Qpid Proton library required for AMQP support. This library is not built by default. It must be passed after the test/mining arguments, if present. EOF exit 0 @@ -94,25 +93,17 @@ then shift fi -# If --enable-proton is the next argument, enable building Proton code: -PROTON_ARG='--enable-proton=no' -if [ "x${1:-}" = 'x--enable-proton' ] -then - PROTON_ARG='' - shift -fi - # Just show the useful info eval "$MAKE" --version | head -n2 as --version | head -n1 as --version | tail -n1 ld -v -HOST="$HOST" BUILD="$BUILD" NO_PROTON="$PROTON_ARG" "$MAKE" "$@" -C ./depends/ V=1 +HOST="$HOST" BUILD="$BUILD" "$MAKE" "$@" -C ./depends/ V=1 ./autogen.sh -CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" "$LCOV_ARG" "$TEST_ARG" "$MINING_ARG" "$PROTON_ARG" $CONFIGURE_FLAGS CXXFLAGS='-g' +CONFIG_SITE="$PWD/depends/$HOST/share/config.site" ./configure "$HARDENING_ARG" "$LCOV_ARG" "$TEST_ARG" "$MINING_ARG" $CONFIGURE_FLAGS CXXFLAGS='-g' #BUILD CCLIB From c0eb0631e28c980534a476f6c981eb9303194748 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 01:58:23 +0200 Subject: [PATCH 210/220] rust reverted to version 1.32.0 --- depends/packages/rust.mk | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/depends/packages/rust.mk b/depends/packages/rust.mk index 2546a733e..6fbdda037 100644 --- a/depends/packages/rust.mk +++ b/depends/packages/rust.mk @@ -1,12 +1,12 @@ package=rust -$(package)_version=1.42.0 +$(package)_version=1.32.0 $(package)_download_path=https://static.rust-lang.org/dist $(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash_linux=7d1e07ad9c8a33d8d039def7c0a131c5917aa3ea0af3d0cc399c6faf7b789052 +$(package)_sha256_hash_linux=e024698320d76b74daf0e6e71be3681a1e7923122e3ebd03673fcac3ecc23810 $(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash_darwin=db1055c46e0d54b99da05e88c71fea21b3897e74a4f5ff9390e934f3f050c0a8 -$(package)_file_name_freebsd=rust-$($(package)_version)-x86_64-unknown-freebsd.tar.gz -$(package)_sha256_hash_freebsd=230bcf17e4383fba85d3c87fe25d17737459fe561a5f4668fe70dcac2da4e17c +$(package)_sha256_hash_darwin=f0dfba507192f9b5c330b5984ba71d57d434475f3d62bd44a39201e36fa76304 +$(package)_file_name_mingw32=rust-$($(package)_version)-x86_64-pc-windows-gnu.tar.gz +$(package)_sha256_hash_mingw32=358e1435347c67dbf33aa9cad6fe501a833d6633ed5d5aa1863d5dffa0349be9 # Mapping from GCC canonical hosts to Rust targets # If a mapping is not present, we assume they are identical, unless $host_os is @@ -14,9 +14,9 @@ $(package)_sha256_hash_freebsd=230bcf17e4383fba85d3c87fe25d17737459fe561a5f4668f $(package)_rust_target_x86_64-w64-mingw32=x86_64-pc-windows-gnu # Mapping from Rust targets to SHA-256 hashes -$(package)_rust_std_sha256_hash_aarch64-unknown-linux-gnu=1343f51fc87049327233cee8941629c3d7dfdc425d359385f93665de3d46711b -$(package)_rust_std_sha256_hash_x86_64-apple-darwin=1d61e9ed5d29e1bb4c18e13d551c6d856c73fb8b410053245dc6e0d3b3a0e92c -$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=8a8389f3860df6f42fbf8b76a62ddc7b9b6fe6d0fb526dcfc42faab1005bfb6d +$(package)_rust_std_sha256_hash_aarch64-unknown-linux-gnu=346efe3aef2aff7b71a611bf7661bcec5f9bc4025a599c2866ec5fd330247cb9 +$(package)_rust_std_sha256_hash_x86_64-apple-darwin=b736d035a97f830585360e54e3f8877b68c942211cf0a75e805f34bfb36103a6 +$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=cad5f1454d591c13eeb3657f1c9dbfeb30e648f59680bd0765b94c63e7afc49e define rust_target $(if $($(1)_rust_target_$(2)),$($(1)_rust_target_$(2)),$(if $(findstring darwin,$(3)),x86_64-apple-darwin,$(2))) From 534efcb65d509dd9b9146a7f7402e41b52bdadb5 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 02:28:27 +0200 Subject: [PATCH 211/220] malloc_trim is glibc specific --- src/wallet/wallet.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ae845cb21..3c7040b45 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2439,11 +2439,10 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) { return; } } -#if defined(__unix__) || defined(_WIN64) - // Miodrag: release memory back to the OS +#if defined(__GLIBC__) malloc_trim(0); #else - //TODO: This doesn't work on Mac + // On Mac and Win memory isn't kept back upon vector or list member erase, different garbage collector strategy. No need to force trimming. #endif } From fc409581f30d5ef446e6f32bba1b7bdce5b13cf5 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 02:35:25 +0200 Subject: [PATCH 212/220] updated .gitignore with cc dynamic libs built for Win --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 408d59085..ae3cff264 100644 --- a/.gitignore +++ b/.gitignore @@ -156,7 +156,9 @@ src/Makefile.in doc/man/Makefile.in Makefile.in src/libcc.so +src/libcc.dll src/cc/customcc.so +src/cc/customcc.dll src/HUSH3_7776 REGTEST_7776 src/cc/librogue.so From 29a06462cb46bb1dd43d66cc826bb84fb796f4b7 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 02:44:29 +0200 Subject: [PATCH 213/220] more associative naming convention --- src/cc/Makefile_custom | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/Makefile_custom b/src/cc/Makefile_custom index 0c2401f31..3989eefa3 100644 --- a/src/cc/Makefile_custom +++ b/src/cc/Makefile_custom @@ -2,7 +2,7 @@ SHELL = /bin/sh CC = gcc CC_DARWIN = g++-8 CC_WIN = x86_64-w64-mingw32-gcc-posix -CC_ARM64 = aarch64-linux-gnu-g++ +CC_AARCH64 = aarch64-linux-gnu-g++ CFLAGS_DARWIN = -DBUILD_CUSTOMCC -std=c++11 -arch x86_64 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib CFLAGS = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared CFLAGS_WIN = -Wno-write-strings -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared @@ -31,7 +31,7 @@ else ifeq ($(HOST),x86_64-w64-mingw32) #else ifeq ($(WIN_HOST),True) - todo: pass ENV var from build.sh if WIN host else ifeq ($(HOST),aarch64-linux-gnu) $(info LINUX ARM 64bit ) - $(CC_ARM64) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES) + $(CC_AARCH64) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) -c $(SOURCES) cp $(TARGET) ../libcc.so else $(info LINUX) From 221335602850703d2aaa23f06141097d4141f211 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 02:55:00 +0200 Subject: [PATCH 214/220] whitespaces: changes undoed --- configure.ac | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index ace3612da..4d1c91acd 100644 --- a/configure.ac +++ b/configure.ac @@ -328,11 +328,11 @@ case $host in dnl AC_CHECK_PROG([BREW],brew, brew) dnl if test x$BREW = xbrew; then - dnl These Homebrew packages may be keg-only, meaning that they won't be found - dnl in expected paths because they may conflict with system files. Ask - dnl Homebrew where each one is located, then adjust paths accordingly. - dnl It's safe to add these paths even if the functionality is disabled by - dnl the user (--without-wallet for example). + dnl These Homebrew packages may be keg-only, meaning that they won't be found + dnl in expected paths because they may conflict with system files. Ask + dnl Homebrew where each one is located, then adjust paths accordingly. + dnl It's safe to add these paths even if the functionality is disabled by + dnl the user (--without-wallet for example). dnl openssl_prefix=`$BREW --prefix openssl 2>/dev/null` dnl bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` @@ -948,10 +948,10 @@ echo " with zmq = $use_zmq" echo " with test = $use_tests" echo " debug enabled = $enable_debug" echo " werror = $enable_werror" -echo +echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" -echo +echo echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $CPPFLAGS" @@ -959,4 +959,4 @@ echo " CXX = $CXX" echo " CXXFLAGS = $CXXFLAGS" echo " LDFLAGS = $LDFLAGS" echo " ARFLAGS = $ARFLAGS" -echo +echo From 57052a0e9f1dd4f08f6a9218da2d7975135a9602 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 02:58:33 +0200 Subject: [PATCH 215/220] more typos fix --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 4d1c91acd..b14a6e156 100644 --- a/configure.ac +++ b/configure.ac @@ -686,7 +686,7 @@ if test x$use_pkgconfig = xyes; then ) else # BUG: Fix this: - echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, libgmp' + echo 'BUG: configure does not yet check for the following dependencies if pkg-config is not on the system: libcrypto++, gmp' AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) @@ -951,7 +951,7 @@ echo " werror = $enable_werror" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" -echo +echo echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $CPPFLAGS" From 2112a1ae04878d0917fe4122a2bda78f8662fab4 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 03:01:40 +0200 Subject: [PATCH 216/220] ... and this one --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b14a6e156..4ff3855b8 100644 --- a/configure.ac +++ b/configure.ac @@ -941,7 +941,7 @@ case $host in ;; esac -echo +echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" echo " with zmq = $use_zmq" From f7ec886a3e839b80aa18cb8c328909b43b799ae3 Mon Sep 17 00:00:00 2001 From: miodragpop Date: Fri, 17 Jul 2020 03:27:53 +0200 Subject: [PATCH 217/220] build-cross-aarch64.sh script removed for aarch64 cross-build use `HOST=aarch64-linux-gnu zcutil/build.sh` followed by optional parameters --- zcutil/build-cross-aarch64.sh | 64 ----------------------------------- 1 file changed, 64 deletions(-) delete mode 100755 zcutil/build-cross-aarch64.sh diff --git a/zcutil/build-cross-aarch64.sh b/zcutil/build-cross-aarch64.sh deleted file mode 100755 index eea5af471..000000000 --- a/zcutil/build-cross-aarch64.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# Copyright (c) 2019-2020 radix42 -# Copyright (c) 2019-2020 The Hush developers -# Original aarch64 port by radix42. Thank you! - -set -eu -o pipefail - -cat <<'EOF' - ________________ -< Building Hush! > - ---------------- - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || -EOF - -if [ "x$*" = 'x--help' ] -then - cat ./zcutil/dragon.txt - cat < Date: Fri, 17 Jul 2020 01:24:50 -0400 Subject: [PATCH 218/220] Catch errors early and exit, such as when best chain is still activating --- contrib/checkpoints.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/checkpoints.pl b/contrib/checkpoints.pl index 99a84f2c2..93ea1041c 100755 --- a/contrib/checkpoints.pl +++ b/contrib/checkpoints.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# Copyright 2019 The Hush developers +# Copyright 2019-2020 The Hush developers # Released under the GPLv3 use warnings; use strict; @@ -12,6 +12,10 @@ my $gethash = "$hush getblockhash"; my $stride = shift || 1000; my $count = 0; my $blocks = qx{$hush getblockcount}; +if($?) { + print "ERROR, exiting...\n"; + exit 1; +} my $prev = $blocks - $perday; my $last = 0; my $now = time(); From b094db7113f5567d1c6fadce39134b4f4f4b1ab4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 17 Jul 2020 15:35:28 -0400 Subject: [PATCH 219/220] More debugspam for -zdebug; Fix bug where shielded spends where not tracked correctly --- src/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0dc0cf87e..ac9be64b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4734,7 +4734,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl CAmount sproutValue = 0; CAmount saplingValue = 0; bool isShieldedTx = false; - unsigned int nShieldedSpends=0,nShieldedSpendsInBlock=0,nShieldedOutputs=0,nPayments=0, nShieldedOutputsInBlock=0; + unsigned int nShieldedSpends=0,nShieldedSpendsInBlock=0,nShieldedOutputs=0,nPayments=0,nShieldedOutputsInBlock=0; unsigned int nShieldedTx=0,nFullyShieldedTx=0,nDeshieldingTx=0,nShieldingTx=0; unsigned int nShieldedPayments=0,nFullyShieldedPayments=0,nShieldingPayments=0,nDeshieldingPayments=0; unsigned int nNotarizations=0; @@ -4825,6 +4825,9 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl // To calculate the anonset we must track the sum of spends and zouts in every tx, in every block. -- Duke nShieldedOutputsInBlock += nShieldedOutputs; nShieldedSpendsInBlock += nShieldedSpends; + if (fZdebug) { + fprintf(stderr,"%s: tx=%s has zspends=%d zouts=%d\n", __FUNCTION__, tx.GetHash().ToString().c_str(), nShieldedSpendsInBlock, nShieldedOutputsInBlock ); + } } pindexNew->nSproutValue = sproutValue; @@ -4864,12 +4867,15 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl queue.pop_front(); pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; + // Update -zindex stats if (fZindex) { - if (fZdebug) - fprintf(stderr,"%s: setting blockchain zstats with zouts=%d\n", __FUNCTION__, nShieldedOutputsInBlock ); + if (fZdebug) { + fprintf(stderr,"%s: setting blockchain zstats with zspends=%d, zouts=%d\n", __FUNCTION__, nShieldedSpendsInBlock, nShieldedOutputsInBlock ); + } pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations; pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx; pindex->nChainShieldedOutputs = (pindex->pprev ? pindex->pprev->nChainShieldedOutputs : 0) + pindex->nShieldedOutputs; + pindex->nChainShieldedSpends = (pindex->pprev ? pindex->pprev->nChainShieldedSpends : 0) + pindex->nShieldedSpends; pindex->nChainFullyShieldedTx = (pindex->pprev ? pindex->pprev->nChainFullyShieldedTx : 0) + pindex->nFullyShieldedTx; pindex->nChainShieldingTx = (pindex->pprev ? pindex->pprev->nChainShieldingTx : 0) + pindex->nShieldingTx; pindex->nChainDeshieldingTx = (pindex->pprev ? pindex->pprev->nChainDeshieldingTx : 0) + pindex->nDeshieldingTx; From 33358740f4110cf9382eb33a4dfdc83361a91241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miodrag=20Popovi=C4=87?= Date: Tue, 21 Jul 2020 10:26:42 +0200 Subject: [PATCH 220/220] malloc.h conditional inclusion malloc.h header is also glibc specific --- src/wallet/wallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3c7040b45..3a0bc389c 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -49,7 +49,9 @@ #include #include +#if defined(__GLIBC__) #include +#endif using namespace std; using namespace libzcash;