From c9fbc441efd78593ba6a9828be45baf2d6469757 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Tue, 17 May 2022 19:31:56 -0300 Subject: [PATCH] Use subtree again to allow publishing the crate (#34) * change: update Cargo.toml, lib.rs, CHANGELOG.md for 0.1.6 release. * Squashed 'depend/zcash/' content from commit 9af3bce26 git-subtree-dir: depend/zcash git-subtree-split: 9af3bce265ba428382006b0940678418d65f505f * fix: delete depend/zcash/Cargo.toml to prevent cargo from ignoring it * ci: add cargo package test * change(doc): explain the subtree / squash issue in README.md --- .github/workflows/ci.yml | 22 + .gitmodules | 4 - CHANGELOG.md | 5 +- Cargo.toml | 9 +- README.md | 46 +- depend/zcash | 1 - depend/zcash/.cargo/config.offline | 8 + depend/zcash/.gitattributes | 1 + .../.github/ISSUE_TEMPLATE/bug-report.md | 65 + .../.github/ISSUE_TEMPLATE/feature-request.md | 22 + .../zcash/.github/ISSUE_TEMPLATE/ux-report.md | 17 + depend/zcash/.github/dependabot.yml | 14 + depend/zcash/.github/pull_request_template.md | 5 + depend/zcash/.github/workflows/book.yml | 32 + depend/zcash/.github/workflows/lints.yml | 106 + depend/zcash/.gitignore | 129 + depend/zcash/CONTRIBUTING.md | 1 + depend/zcash/COPYING | 44 + depend/zcash/Cargo.lock | 2407 +++++ depend/zcash/INSTALL | 5 + depend/zcash/Makefile.am | 176 + depend/zcash/README.md | 66 + depend/zcash/SECURITY.md | 66 + depend/zcash/autogen.sh | 16 + depend/zcash/build-aux/m4/ax_boost_base.m4 | 291 + depend/zcash/build-aux/m4/ax_boost_chrono.m4 | 119 + .../zcash/build-aux/m4/ax_boost_filesystem.m4 | 119 + .../build-aux/m4/ax_boost_program_options.m4 | 108 + depend/zcash/build-aux/m4/ax_boost_system.m4 | 122 + depend/zcash/build-aux/m4/ax_boost_thread.m4 | 150 + .../m4/ax_boost_unit_test_framework.m4 | 138 + .../build-aux/m4/ax_check_compile_flag.m4 | 74 + .../zcash/build-aux/m4/ax_check_link_flag.m4 | 74 + .../build-aux/m4/ax_check_preproc_flag.m4 | 74 + .../build-aux/m4/ax_cxx_compile_stdcxx.m4 | 951 ++ .../build-aux/m4/ax_gcc_func_attribute.m4 | 223 + depend/zcash/build-aux/m4/ax_pthread.m4 | 485 + depend/zcash/build-aux/m4/bitcoin_find_bdb.m4 | 72 + .../build-aux/m4/bitcoin_subdir_to_include.m4 | 20 + depend/zcash/build-aux/m4/l_atomic.m4 | 46 + depend/zcash/code_of_conduct.md | 65 + depend/zcash/configure.ac | 1058 +++ depend/zcash/contrib/README.md | 43 + depend/zcash/contrib/bitrpc/README.md | 8 + depend/zcash/contrib/bitrpc/bitrpc.py | 335 + .../buildbot/Dockerfile-bbworker.apt | 42 + .../buildbot/Dockerfile-bbworker.arch | 35 + .../buildbot/Dockerfile-bbworker.centos8 | 35 + .../buildbot/Dockerfile-build-python.apt | 30 + .../ci-builders/buildbot/Dockerfile-build.apt | 9 + .../buildbot/Dockerfile-build.arch | 23 + .../buildbot/Dockerfile-build.centos8 | 14 + .../buildbot/Dockerfile-gitian.apt | 8 + .../contrib/ci-builders/buildbot/README.md | 42 + .../ci-builders/buildbot/apt-package-list.txt | 23 + .../buildbot/bbworker-buildbot.tac | 40 + .../buildbot/bbworker-requirements.txt | 9 + .../ci-builders/buildbot/docker-build.sh | 62 + .../ci-builders/tekton/Dockerfile-build.apt | 9 + .../ci-builders/tekton/Dockerfile-build.arch | 14 + .../tekton/Dockerfile-build.centos8 | 14 + .../tekton/Dockerfile-tekton-worker | 11 + .../contrib/ci-builders/tekton/README.md | 35 + .../tekton/apt-package-tekton-list.txt | 24 + .../ci-builders/tekton/docker-build.sh | 60 + .../ci-builders/tekton/requirements.txt | 8 + depend/zcash/contrib/ci-workers/README.md | 62 + depend/zcash/contrib/ci-workers/ansible.cfg | 2 + depend/zcash/contrib/ci-workers/files/bashrc | 2 + depend/zcash/contrib/ci-workers/grind.yml | 27 + .../contrib/ci-workers/tasks/install-brew.yml | 10 + .../contrib/ci-workers/tasks/install-pip.yml | 8 + .../templates/buildbot-worker.plist.j2 | 23 + .../templates/buildbot-worker.service.j2 | 17 + .../contrib/ci-workers/templates/host.ec2.j2 | 1 + .../contrib/ci-workers/templates/host.j2 | 3 + depend/zcash/contrib/ci-workers/unix.yml | 209 + .../contrib/ci-workers/vars/Archlinux.yml | 7 + .../zcash/contrib/ci-workers/vars/CentOS.yml | 13 + .../zcash/contrib/ci-workers/vars/Debian.yml | 6 + .../zcash/contrib/ci-workers/vars/Fedora.yml | 11 + .../zcash/contrib/ci-workers/vars/FreeBSD.yml | 10 + .../zcash/contrib/ci-workers/vars/MacOSX.yml | 6 + .../zcash/contrib/ci-workers/vars/Ubuntu.yml | 4 + .../contrib/ci-workers/vars/buildbot.yml | 5 + .../zcash/contrib/ci-workers/vars/default.yml | 53 + depend/zcash/contrib/debian/changelog | 593 ++ depend/zcash/contrib/debian/compat | 1 + depend/zcash/contrib/debian/control | 22 + depend/zcash/contrib/debian/copyright | 1891 ++++ .../zcash/contrib/debian/examples/zcash.conf | 129 + depend/zcash/contrib/debian/postinst | 39 + depend/zcash/contrib/debian/postrm | 37 + depend/zcash/contrib/debian/preinst | 35 + depend/zcash/contrib/debian/prerm | 38 + depend/zcash/contrib/debian/rules | 25 + depend/zcash/contrib/debian/zcash.examples | 1 + depend/zcash/contrib/debian/zcash.install | 3 + depend/zcash/contrib/debian/zcash.manpages | 2 + depend/zcash/contrib/devtools/README.md | 102 + .../contrib/devtools/fix-copyright-headers.py | 53 + depend/zcash/contrib/devtools/gen-manpages.sh | 40 + depend/zcash/contrib/devtools/github-merge.sh | 181 + .../zcash/contrib/devtools/optimize-pngs.py | 73 + .../zcash/contrib/devtools/rust-deps-graph.sh | 18 + .../zcash/contrib/devtools/security-check.py | 224 + depend/zcash/contrib/devtools/split-debug.sh | 10 + depend/zcash/contrib/devtools/symbol-check.py | 194 + .../contrib/devtools/test-security-check.py | 62 + .../contrib/devtools/update-rust-hashes.sh | 37 + depend/zcash/contrib/docker/.dockerignore | 2 + depend/zcash/contrib/docker/.env.example | 12 + depend/zcash/contrib/docker/.gitignore | 3 + depend/zcash/contrib/docker/Dockerfile | 37 + depend/zcash/contrib/docker/README.md | 87 + .../zcash/contrib/docker/docker-compose.yml | 11 + depend/zcash/contrib/docker/entrypoint.sh | 56 + .../contrib/gitian-descriptors/README.md | 65 + .../gitian-descriptors/gitian-linux.yml | 141 + .../gitian-descriptors/gitian-osx-signer.yml | 37 + .../contrib/gitian-descriptors/gitian-osx.yml | 146 + .../gitian-descriptors/gitian-win-signer.yml | 38 + .../contrib/gitian-descriptors/gitian-win.yml | 166 + .../zcash/contrib/gitian-downloader/daira.asc | 70 + .../zcash/contrib/gitian-downloader/jack.asc | 449 + .../zcash/contrib/gitian-downloader/kevin.asc | 171 + .../contrib/gitian-downloader/nathan.asc | 52 + .../zcash/contrib/gitian-downloader/sean.asc | 51 + .../zcash/contrib/gitian-downloader/simon.asc | 47 + depend/zcash/contrib/linearize/README.md | 33 + .../contrib/linearize/example-linearize.cfg | 29 + .../zcash/contrib/linearize/linearize-data.py | 303 + .../contrib/linearize/linearize-hashes.py | 113 + depend/zcash/contrib/macdeploy/README.md | 123 + depend/zcash/contrib/macdeploy/gen-sdk | 94 + depend/zcash/contrib/metrics/prometheus.yaml | 6 + depend/zcash/contrib/qos/README.md | 5 + depend/zcash/contrib/qos/tc.sh | 48 + depend/zcash/contrib/seeds/README.md | 4 + depend/zcash/contrib/seeds/generate-seeds.py | 138 + depend/zcash/contrib/seeds/makeseeds.py | 169 + depend/zcash/contrib/simulations/worstcase.py | 246 + depend/zcash/contrib/testgen/README.md | 8 + depend/zcash/contrib/testgen/base58.py | 104 + .../testgen/gen_base58_test_vectors.py | 126 + depend/zcash/contrib/tidy_datadir.sh | 62 + .../zcash/contrib/zcash-cli.bash-completion | 161 + depend/zcash/contrib/zcash-tx.bash-completion | 58 + depend/zcash/contrib/zcashd.bash-completion | 57 + depend/zcash/contrib/zmq/zmq_sub.py | 48 + depend/zcash/depends/.gitignore | 10 + depend/zcash/depends/Makefile | 210 + depend/zcash/depends/README.md | 57 + depend/zcash/depends/builders/darwin.mk | 23 + depend/zcash/depends/builders/default.mk | 20 + depend/zcash/depends/builders/freebsd.mk | 4 + depend/zcash/depends/builders/linux.mk | 2 + depend/zcash/depends/config.guess | 1685 ++++ depend/zcash/depends/config.site.in | 78 + depend/zcash/depends/config.sub | 1845 ++++ depend/zcash/depends/description.md | 53 + depend/zcash/depends/funcs.mk | 249 + depend/zcash/depends/hosts/darwin.mk | 43 + depend/zcash/depends/hosts/default.mk | 45 + depend/zcash/depends/hosts/freebsd.mk | 20 + depend/zcash/depends/hosts/linux.mk | 25 + depend/zcash/depends/hosts/mingw32.mk | 12 + depend/zcash/depends/packages.md | 186 + depend/zcash/depends/packages/bdb.mk | 53 + depend/zcash/depends/packages/boost.mk | 66 + depend/zcash/depends/packages/googletest.mk | 36 + depend/zcash/depends/packages/libcxx.mk | 75 + depend/zcash/depends/packages/libevent.mk | 40 + depend/zcash/depends/packages/libsodium.mk | 26 + depend/zcash/depends/packages/native_b2.mk | 20 + .../zcash/depends/packages/native_ccache.mk | 25 + .../zcash/depends/packages/native_cctools.mk | 62 + depend/zcash/depends/packages/native_clang.mk | 51 + .../zcash/depends/packages/native_libtinfo.mk | 22 + depend/zcash/depends/packages/native_rust.mk | 61 + depend/zcash/depends/packages/packages.mk | 20 + depend/zcash/depends/packages/utfcpp.mk | 10 + depend/zcash/depends/packages/zeromq.mk | 47 + .../patches/bdb/clang-12-stpcpy-issue.diff | 17 + .../bdb/winioctl-and-atomic_init_db.patch | 136 + .../0001-fix-windows-getaddrinfo.patch | 15 + .../libsodium/1.0.15-pubkey-validation.diff | 17 + .../1.0.15-signature-validation.diff | 78 + .../patches/native_cctools/ignore-otool.diff | 24 + .../zeromq/windows-unused-variables.diff | 17 + depend/zcash/doc/Doxyfile | 1752 ++++ depend/zcash/doc/authors.md | 252 + depend/zcash/doc/bips.md | 4 + depend/zcash/doc/book/.gitignore | 1 + depend/zcash/doc/book/book.toml | 6 + depend/zcash/doc/book/src/README.md | 1 + depend/zcash/doc/book/src/SUMMARY.md | 14 + depend/zcash/doc/book/src/design.md | 9 + .../zcash/doc/book/src/design/chain-state.md | 3 + .../zcash/doc/book/src/design/coins-view.md | 10 + .../book/src/design/p2p-data-propagation.md | 43 + depend/zcash/doc/book/src/dev.md | 3 + depend/zcash/doc/book/src/dev/deprecation.md | 38 + depend/zcash/doc/book/src/dev/regtest.md | 165 + depend/zcash/doc/book/src/dev/rust.md | 56 + depend/zcash/doc/book/src/doc/imgs/logo.png | 1 + .../doc/book/src/doc/imgs/zcashd_screen.gif | 1 + depend/zcash/doc/book/src/user.md | 6 + depend/zcash/doc/book/src/user/deprecation.md | 71 + depend/zcash/doc/book/src/user/metrics.md | 85 + depend/zcash/doc/developer-notes.md | 369 + depend/zcash/doc/dnsseed-policy.md | 6 + depend/zcash/doc/files.md | 5 + depend/zcash/doc/hotfix-process.md | 49 + depend/zcash/doc/imgs/logo.png | Bin 0 -> 10950 bytes depend/zcash/doc/imgs/zcashd_screen.gif | Bin 0 -> 39787 bytes depend/zcash/doc/imgs/zcashd_screenshot.png | Bin 0 -> 101160 bytes depend/zcash/doc/man/Makefile.am | 1 + depend/zcash/doc/man/zcash-cli.1 | 88 + depend/zcash/doc/man/zcash-fetch-params.1 | 28 + depend/zcash/doc/man/zcash-tx.1 | 100 + depend/zcash/doc/man/zcashd-wallet-tool.1 | 53 + depend/zcash/doc/man/zcashd.1 | 593 ++ depend/zcash/doc/payment-api.md | 5 + depend/zcash/doc/payment-disclosure.md | 107 + depend/zcash/doc/reduce-traffic.md | 55 + depend/zcash/doc/reducing-memory-usage.md | 8 + depend/zcash/doc/release-notes.md | 6 + .../release-notes/release-notes-0.11.2.z2.md | 35 + .../release-notes/release-notes-0.11.2.z3.md | 69 + .../release-notes/release-notes-0.11.2.z4.md | 70 + .../release-notes/release-notes-0.11.2.z5.md | 78 + .../release-notes/release-notes-0.11.2.z6.md | 18 + .../release-notes/release-notes-0.11.2.z7.md | 90 + .../release-notes/release-notes-0.11.2.z8.md | 61 + .../release-notes/release-notes-0.11.2.z9.md | 55 + .../release-notes-1.0.0-beta1.md | 159 + .../release-notes-1.0.0-beta2.md | 119 + .../release-notes/release-notes-1.0.0-rc1.md | 121 + .../release-notes/release-notes-1.0.0-rc2.md | 106 + .../release-notes/release-notes-1.0.0-rc3.md | 51 + .../release-notes/release-notes-1.0.0-rc4.md | 14 + .../doc/release-notes/release-notes-1.0.0.md | 18 + .../doc/release-notes/release-notes-1.0.1.md | 34 + .../release-notes/release-notes-1.0.10-1.md | 11 + .../doc/release-notes/release-notes-1.0.10.md | 79 + .../release-notes/release-notes-1.0.11-rc1.md | 44 + .../doc/release-notes/release-notes-1.0.11.md | 47 + .../release-notes/release-notes-1.0.12-rc1.md | 57 + .../doc/release-notes/release-notes-1.0.12.md | 65 + .../release-notes/release-notes-1.0.13-rc1.md | 88 + .../release-notes/release-notes-1.0.13-rc2.md | 95 + .../doc/release-notes/release-notes-1.0.13.md | 98 + .../release-notes/release-notes-1.0.14-rc1.md | 156 + .../doc/release-notes/release-notes-1.0.14.md | 160 + .../release-notes/release-notes-1.0.15-rc1.md | 165 + .../doc/release-notes/release-notes-1.0.15.md | 209 + .../doc/release-notes/release-notes-1.0.2.md | 16 + .../doc/release-notes/release-notes-1.0.3.md | 35 + .../doc/release-notes/release-notes-1.0.4.md | 75 + .../doc/release-notes/release-notes-1.0.5.md | 58 + .../doc/release-notes/release-notes-1.0.6.md | 148 + .../release-notes/release-notes-1.0.7-1.md | 4 + .../doc/release-notes/release-notes-1.0.7.md | 165 + .../release-notes/release-notes-1.0.8-1.md | 16 + .../doc/release-notes/release-notes-1.0.8.md | 170 + .../doc/release-notes/release-notes-1.0.9.md | 90 + .../release-notes/release-notes-1.1.0-rc1.md | 180 + .../doc/release-notes/release-notes-1.1.0.md | 193 + .../release-notes/release-notes-1.1.1-rc1.md | 286 + .../release-notes/release-notes-1.1.1-rc2.md | 290 + .../doc/release-notes/release-notes-1.1.1.md | 336 + .../release-notes/release-notes-1.1.2-rc1.md | 96 + .../doc/release-notes/release-notes-1.1.2.md | 99 + .../release-notes/release-notes-2.0.0-rc1.md | 176 + .../doc/release-notes/release-notes-2.0.0.md | 199 + .../release-notes/release-notes-2.0.1-rc1.md | 244 + .../doc/release-notes/release-notes-2.0.1.md | 276 + .../release-notes/release-notes-2.0.2-rc1.md | 106 + .../doc/release-notes/release-notes-2.0.2.md | 110 + .../release-notes/release-notes-2.0.3-rc1.md | 57 + .../doc/release-notes/release-notes-2.0.3.md | 61 + .../release-notes/release-notes-2.0.4-rc1.md | 132 + .../doc/release-notes/release-notes-2.0.4.md | 139 + .../release-notes/release-notes-2.0.5-1.md | 68 + .../release-notes/release-notes-2.0.5-2.md | 77 + .../release-notes/release-notes-2.0.5-rc1.md | 73 + .../doc/release-notes/release-notes-2.0.5.md | 130 + .../release-notes/release-notes-2.0.6-rc1.md | 62 + .../doc/release-notes/release-notes-2.0.6.md | 102 + .../release-notes/release-notes-2.0.7-1.md | 38 + .../release-notes/release-notes-2.0.7-2.md | 30 + .../release-notes/release-notes-2.0.7-3.md | 35 + .../release-notes/release-notes-2.0.7-rc1.md | 118 + .../doc/release-notes/release-notes-2.0.7.md | 149 + .../release-notes/release-notes-2.1.0-1.md | 10 + .../release-notes/release-notes-2.1.0-rc1.md | 177 + .../doc/release-notes/release-notes-2.1.0.md | 215 + .../release-notes/release-notes-2.1.1-1.md | 43 + .../release-notes/release-notes-2.1.1-rc1.md | 288 + .../release-notes/release-notes-2.1.1-rc2.md | 298 + .../doc/release-notes/release-notes-2.1.1.md | 301 + .../release-notes/release-notes-2.1.2-1.md | 17 + .../release-notes/release-notes-2.1.2-2.md | 18 + .../release-notes/release-notes-2.1.2-3.md | 12 + .../release-notes/release-notes-2.1.2-rc1.md | 615 ++ .../doc/release-notes/release-notes-2.1.2.md | 623 ++ .../release-notes/release-notes-3.0.0-rc1.md | 120 + .../doc/release-notes/release-notes-3.0.0.md | 130 + .../release-notes/release-notes-3.1.0-rc1.md | 243 + .../release-notes/release-notes-3.1.0-rc2.md | 250 + .../doc/release-notes/release-notes-3.1.0.md | 274 + .../release-notes/release-notes-4.0.0-rc1.md | 276 + .../doc/release-notes/release-notes-4.0.0.md | 290 + .../release-notes/release-notes-4.1.0-rc1.md | 382 + .../doc/release-notes/release-notes-4.1.0.md | 387 + .../doc/release-notes/release-notes-4.1.1.md | 156 + .../release-notes/release-notes-4.2.0-rc1.md | 242 + .../doc/release-notes/release-notes-4.2.0.md | 247 + .../release-notes/release-notes-4.3.0-rc1.md | 320 + .../doc/release-notes/release-notes-4.3.0.md | 331 + .../release-notes/release-notes-4.4.0-rc1.md | 187 + .../doc/release-notes/release-notes-4.4.0.md | 197 + .../release-notes/release-notes-4.4.1-rc1.md | 128 + .../doc/release-notes/release-notes-4.4.1.md | 156 + .../release-notes/release-notes-4.5.0-rc1.md | 311 + .../doc/release-notes/release-notes-4.5.0.md | 387 + .../release-notes/release-notes-4.5.1-1.md | 46 + .../doc/release-notes/release-notes-4.5.1.md | 80 + .../release-notes/release-notes-4.6.0-1.md | 37 + .../release-notes/release-notes-4.6.0-2.md | 47 + .../release-notes/release-notes-4.6.0-rc1.md | 111 + .../doc/release-notes/release-notes-4.6.0.md | 126 + .../release-notes/release-notes-4.7.0-rc1.md | 538 ++ .../doc/release-notes/release-notes-4.7.0.md | 869 ++ .../release-notes/release-notes-5.0.0-rc1.md | 215 + .../doc/release-notes/release-notes-5.0.0.md | 253 + depend/zcash/doc/release-process.md | 223 + depend/zcash/doc/security-warnings.md | 6 + depend/zcash/doc/shield-coinbase.md | 5 + depend/zcash/doc/tor.md | 6 + .../zcash/doc/translation_strings_policy.md | 71 + depend/zcash/doc/unit-tests.md | 6 + depend/zcash/doc/wallet-backup.md | 5 + depend/zcash/doc/zmq.md | 122 + depend/zcash/libzcash_script.pc.in | 10 + depend/zcash/qa/README.md | 87 + depend/zcash/qa/pull-tester/rpc-tests.py | 454 + .../zcash/qa/pull-tester/tests_config.ini.in | 18 + depend/zcash/qa/rpc-tests/.gitignore | 2 + depend/zcash/qa/rpc-tests/README.md | 108 + depend/zcash/qa/rpc-tests/addressindex.py | 382 + depend/zcash/qa/rpc-tests/bip65-cltv-p2p.py | 94 + depend/zcash/qa/rpc-tests/bipdersig-p2p.py | 101 + depend/zcash/qa/rpc-tests/blockchain.py | 53 + .../qa/rpc-tests/coinbase_funding_streams.py | 101 + depend/zcash/qa/rpc-tests/create_cache.py | 29 + depend/zcash/qa/rpc-tests/decodescript.py | 187 + depend/zcash/qa/rpc-tests/disablewallet.py | 34 + depend/zcash/qa/rpc-tests/feature_logging.py | 59 + .../zcash/qa/rpc-tests/feature_walletfile.py | 50 + depend/zcash/qa/rpc-tests/feature_zip221.py | 190 + depend/zcash/qa/rpc-tests/feature_zip239.py | 266 + .../feature_zip244_blockcommitments.py | 68 + depend/zcash/qa/rpc-tests/finalsaplingroot.py | 232 + depend/zcash/qa/rpc-tests/forknotify.py | 68 + depend/zcash/qa/rpc-tests/framework.py | 51 + .../zcash/qa/rpc-tests/fundrawtransaction.py | 606 ++ depend/zcash/qa/rpc-tests/getblocktemplate.py | 214 + .../qa/rpc-tests/getblocktemplate_longpoll.py | 97 + .../rpc-tests/getblocktemplate_proposals.py | 194 + depend/zcash/qa/rpc-tests/getchaintips.py | 63 + depend/zcash/qa/rpc-tests/getmininginfo.py | 47 + .../qa/rpc-tests/getrawtransaction_insight.py | 105 + .../zcash/qa/rpc-tests/golden/blossom.tar.gz | Bin 0 -> 47555 bytes .../qa/rpc-tests/golden/heartwood.tar.gz | Bin 0 -> 55861 bytes .../zcash/qa/rpc-tests/hardforkdetection.py | 69 + depend/zcash/qa/rpc-tests/httpbasics.py | 113 + depend/zcash/qa/rpc-tests/invalidateblock.py | 77 + .../zcash/qa/rpc-tests/invalidblockrequest.py | 115 + depend/zcash/qa/rpc-tests/invalidtxrequest.py | 70 + .../zcash/qa/rpc-tests/key_import_export.py | 111 + depend/zcash/qa/rpc-tests/keypool.py | 96 + depend/zcash/qa/rpc-tests/listtransactions.py | 115 + .../zcash/qa/rpc-tests/maxblocksinflight.py | 105 + depend/zcash/qa/rpc-tests/maxuploadtarget.py | 305 + depend/zcash/qa/rpc-tests/mempool_limit.py | 106 + .../qa/rpc-tests/mempool_nu_activation.py | 208 + depend/zcash/qa/rpc-tests/mempool_reorg.py | 109 + .../qa/rpc-tests/mempool_resurrect_test.py | 95 + .../qa/rpc-tests/mempool_spendcoinbase.py | 90 + .../zcash/qa/rpc-tests/mempool_tx_expiry.py | 268 + .../qa/rpc-tests/mergetoaddress_helper.py | 365 + .../qa/rpc-tests/mergetoaddress_mixednotes.py | 77 + .../qa/rpc-tests/mergetoaddress_sapling.py | 26 + .../qa/rpc-tests/mergetoaddress_sprout.py | 26 + depend/zcash/qa/rpc-tests/merkle_blocks.py | 116 + .../qa/rpc-tests/mining_shielded_coinbase.py | 170 + depend/zcash/qa/rpc-tests/multi_rpc.py | 120 + depend/zcash/qa/rpc-tests/nodehandling.py | 87 + depend/zcash/qa/rpc-tests/nuparams.py | 222 + depend/zcash/qa/rpc-tests/orchard_reorg.py | 127 + depend/zcash/qa/rpc-tests/p2p-acceptblock.py | 297 + .../zcash/qa/rpc-tests/p2p-fullblocktest.py | 282 + depend/zcash/qa/rpc-tests/p2p_node_bloom.py | 111 + .../qa/rpc-tests/p2p_nu_peer_management.py | 192 + .../zcash/qa/rpc-tests/p2p_txexpiringsoon.py | 211 + depend/zcash/qa/rpc-tests/p2p_txexpiry_dos.py | 82 + .../qa/rpc-tests/post_heartwood_rollback.py | 115 + .../qa/rpc-tests/prioritisetransaction.py | 140 + depend/zcash/qa/rpc-tests/proxy_test.py | 195 + depend/zcash/qa/rpc-tests/pruning.py | 363 + depend/zcash/qa/rpc-tests/rawtransactions.py | 181 + depend/zcash/qa/rpc-tests/receivedby.py | 174 + .../rpc-tests/regtest_signrawtransaction.py | 27 + depend/zcash/qa/rpc-tests/reindex.py | 45 + .../qa/rpc-tests/remove_sprout_shielding.py | 139 + depend/zcash/qa/rpc-tests/reorg_limit.py | 107 + depend/zcash/qa/rpc-tests/rest.py | 347 + depend/zcash/qa/rpc-tests/rewind_index.py | 93 + depend/zcash/qa/rpc-tests/rpcbind_test.py | 124 + .../qa/rpc-tests/sapling_rewind_check.py | 109 + .../zcash/qa/rpc-tests/shorter_block_times.py | 73 + .../rpc-tests/signrawtransaction_offline.py | 60 + .../zcash/qa/rpc-tests/signrawtransactions.py | 111 + depend/zcash/qa/rpc-tests/smartfees.py | 267 + depend/zcash/qa/rpc-tests/spentindex.py | 185 + .../qa/rpc-tests/sprout_sapling_migration.py | 203 + .../qa/rpc-tests/test_framework/__init__.py | 0 .../qa/rpc-tests/test_framework/authproxy.py | 166 + .../qa/rpc-tests/test_framework/bignum.py | 100 + .../qa/rpc-tests/test_framework/blockstore.py | 142 + .../qa/rpc-tests/test_framework/blocktools.py | 96 + .../qa/rpc-tests/test_framework/comptool.py | 429 + .../qa/rpc-tests/test_framework/coverage.py | 106 + .../qa/rpc-tests/test_framework/equihash.py | 294 + .../qa/rpc-tests/test_framework/flyclient.py | 210 + .../zcash/qa/rpc-tests/test_framework/key.py | 215 + .../qa/rpc-tests/test_framework/mininode.py | 2115 +++++ .../qa/rpc-tests/test_framework/netutil.py | 156 + .../qa/rpc-tests/test_framework/script.py | 978 ++ .../qa/rpc-tests/test_framework/socks5.py | 161 + .../test_framework/test_framework.py | 212 + .../zcash/qa/rpc-tests/test_framework/util.py | 675 ++ .../qa/rpc-tests/test_framework/zip244.py | 294 + .../zcash/qa/rpc-tests/threeofthreerestore.py | 59 + depend/zcash/qa/rpc-tests/timestampindex.py | 92 + depend/zcash/qa/rpc-tests/turnstile.py | 187 + depend/zcash/qa/rpc-tests/tx_expiry_helper.py | 101 + depend/zcash/qa/rpc-tests/txn_doublespend.py | 111 + depend/zcash/qa/rpc-tests/upgrade_golden.py | 96 + depend/zcash/qa/rpc-tests/wallet.py | 224 + depend/zcash/qa/rpc-tests/wallet_1941.py | 103 + depend/zcash/qa/rpc-tests/wallet_accounts.py | 251 + depend/zcash/qa/rpc-tests/wallet_addresses.py | 191 + .../zcash/qa/rpc-tests/wallet_anchorfork.py | 119 + depend/zcash/qa/rpc-tests/wallet_broadcast.py | 59 + .../qa/rpc-tests/wallet_changeaddresses.py | 93 + .../qa/rpc-tests/wallet_changeindicator.py | 77 + depend/zcash/qa/rpc-tests/wallet_db_flush.py | 85 + .../zcash/qa/rpc-tests/wallet_deprecation.py | 74 + .../zcash/qa/rpc-tests/wallet_doublespend.py | 162 + .../qa/rpc-tests/wallet_import_export.py | 103 + depend/zcash/qa/rpc-tests/wallet_isfromme.py | 93 + depend/zcash/qa/rpc-tests/wallet_listnotes.py | 221 + .../zcash/qa/rpc-tests/wallet_listreceived.py | 553 ++ .../zcash/qa/rpc-tests/wallet_nullifiers.py | 171 + depend/zcash/qa/rpc-tests/wallet_orchard.py | 228 + .../qa/rpc-tests/wallet_orchard_change.py | 123 + .../zcash/qa/rpc-tests/wallet_orchard_init.py | 162 + .../rpc-tests/wallet_orchard_persistence.py | 107 + .../zcash/qa/rpc-tests/wallet_overwintertx.py | 180 + .../qa/rpc-tests/wallet_parsing_amounts.py | 113 + .../zcash/qa/rpc-tests/wallet_persistence.py | 145 + depend/zcash/qa/rpc-tests/wallet_sapling.py | 175 + .../qa/rpc-tests/wallet_sendmany_any_taddr.py | 129 + .../qa/rpc-tests/wallet_shieldcoinbase.py | 193 + .../wallet_shieldcoinbase_sapling.py | 22 + .../rpc-tests/wallet_shieldcoinbase_sprout.py | 22 + .../rpc-tests/wallet_shieldcoinbase_ua_nu5.py | 49 + .../wallet_shieldcoinbase_ua_sapling.py | 42 + .../qa/rpc-tests/wallet_shieldingcoinbase.py | 369 + depend/zcash/qa/rpc-tests/wallet_treestate.py | 105 + .../qa/rpc-tests/wallet_unified_change.py | 115 + .../zcash/qa/rpc-tests/wallet_z_sendmany.py | 448 + .../zcash/qa/rpc-tests/wallet_zero_value.py | 49 + depend/zcash/qa/rpc-tests/walletbackup.py | 247 + depend/zcash/qa/rpc-tests/zapwallettxes.py | 85 + depend/zcash/qa/rpc-tests/zcjoinsplit.py | 65 + .../qa/rpc-tests/zcjoinsplitdoublespend.py | 186 + .../zcash/qa/rpc-tests/zkey_import_export.py | 160 + depend/zcash/qa/rpc-tests/zmq_test.py | 99 + depend/zcash/qa/zcash/checksec.sh | 2057 +++++ .../qa/zcash/create_benchmark_archive.py | 262 + .../qa/zcash/create_wallet_200k_utxos.py | 60 + depend/zcash/qa/zcash/full_test_suite.py | 247 + .../qa/zcash/performance-measurements.sh | 379 + depend/zcash/qa/zcash/postponed-updates.txt | 36 + depend/zcash/qa/zcash/smoke_tests.py | 735 ++ .../qa/zcash/test-depends-sources-mirror.py | 43 + depend/zcash/qa/zcash/updatecheck.py | 414 + depend/zcash/rust-toolchain | 1 + depend/zcash/share/genbuild.sh | 58 + depend/zcash/share/rpcuser/README.md | 10 + depend/zcash/share/rpcuser/rpcuser.py | 41 + depend/zcash/src/.clang-format | 50 + depend/zcash/src/Makefile.am | 670 ++ depend/zcash/src/Makefile.bench.include | 63 + depend/zcash/src/Makefile.gtest.include | 104 + depend/zcash/src/Makefile.leveldb.include | 150 + depend/zcash/src/Makefile.test.include | 194 + depend/zcash/src/addrdb.cpp | 218 + depend/zcash/src/addrdb.h | 102 + depend/zcash/src/addressindex.h | 287 + depend/zcash/src/addrman.cpp | 517 ++ depend/zcash/src/addrman.h | 580 ++ depend/zcash/src/alert.cpp | 284 + depend/zcash/src/alert.h | 115 + depend/zcash/src/alertkeys.h | 10 + depend/zcash/src/amount.cpp | 40 + depend/zcash/src/amount.h | 67 + depend/zcash/src/arith_uint256.cpp | 261 + depend/zcash/src/arith_uint256.h | 290 + depend/zcash/src/asyncrpcoperation.cpp | 181 + depend/zcash/src/asyncrpcoperation.h | 153 + depend/zcash/src/asyncrpcqueue.cpp | 233 + depend/zcash/src/asyncrpcqueue.h | 68 + depend/zcash/src/base58.cpp | 136 + depend/zcash/src/base58.h | 61 + depend/zcash/src/bech32.cpp | 194 + depend/zcash/src/bech32.h | 30 + depend/zcash/src/bench/.gitignore | 1 + depend/zcash/src/bench/Examples.cpp | 34 + depend/zcash/src/bench/base58.cpp | 59 + depend/zcash/src/bench/bench.cpp | 106 + depend/zcash/src/bench/bench.h | 95 + depend/zcash/src/bench/bench_bitcoin.cpp | 47 + depend/zcash/src/bench/checkqueue.cpp | 103 + depend/zcash/src/bench/crypto_hash.cpp | 79 + depend/zcash/src/bench/lockedpool.cpp | 46 + depend/zcash/src/bench/perf.cpp | 53 + depend/zcash/src/bench/perf.h | 37 + .../zcash/src/bench/prevector_destructor.cpp | 36 + depend/zcash/src/bench/rollingbloom.cpp | 51 + depend/zcash/src/bench/verification.cpp | 152 + depend/zcash/src/bitcoin-cli-res.rc | 35 + depend/zcash/src/bitcoin-cli.cpp | 436 + depend/zcash/src/bitcoin-tx-res.rc | 35 + depend/zcash/src/bitcoin-tx.cpp | 712 ++ depend/zcash/src/bitcoind-res.rc | 35 + depend/zcash/src/bitcoind.cpp | 224 + depend/zcash/src/bloom.cpp | 276 + depend/zcash/src/bloom.h | 142 + depend/zcash/src/chain.cpp | 109 + depend/zcash/src/chain.h | 649 ++ depend/zcash/src/chainparams.cpp | 860 ++ depend/zcash/src/chainparams.h | 154 + depend/zcash/src/chainparamsbase.cpp | 118 + depend/zcash/src/chainparamsbase.h | 60 + depend/zcash/src/chainparamsseeds.h | 15 + depend/zcash/src/checkpoints.cpp | 89 + depend/zcash/src/checkpoints.h | 33 + depend/zcash/src/checkqueue.h | 218 + depend/zcash/src/clientversion.cpp | 138 + depend/zcash/src/clientversion.h | 72 + depend/zcash/src/coincontrol.h | 68 + depend/zcash/src/coins.cpp | 1158 +++ depend/zcash/src/coins.h | 672 ++ depend/zcash/src/compat.h | 107 + depend/zcash/src/compat/byteswap.h | 47 + depend/zcash/src/compat/endian.h | 241 + depend/zcash/src/compat/glibc_compat.cpp | 29 + depend/zcash/src/compat/glibc_sanity.cpp | 68 + depend/zcash/src/compat/glibcxx_sanity.cpp | 61 + depend/zcash/src/compat/sanity.h | 11 + depend/zcash/src/compat/strnlen.cpp | 18 + depend/zcash/src/compressor.cpp | 185 + depend/zcash/src/compressor.h | 121 + depend/zcash/src/config/.empty | 0 depend/zcash/src/consensus/consensus.h | 50 + depend/zcash/src/consensus/funding.cpp | 94 + depend/zcash/src/consensus/funding.h | 45 + depend/zcash/src/consensus/params.cpp | 249 + depend/zcash/src/consensus/params.h | 371 + depend/zcash/src/consensus/upgrades.cpp | 177 + depend/zcash/src/consensus/upgrades.h | 98 + depend/zcash/src/consensus/validation.h | 85 + depend/zcash/src/core_io.h | 32 + depend/zcash/src/core_memusage.h | 70 + depend/zcash/src/core_read.cpp | 151 + depend/zcash/src/core_write.cpp | 195 + depend/zcash/src/crypto/aes.cpp | 217 + depend/zcash/src/crypto/aes.h | 118 + depend/zcash/src/crypto/chacha20.cpp | 180 + depend/zcash/src/crypto/chacha20.h | 26 + depend/zcash/src/crypto/common.h | 108 + depend/zcash/src/crypto/ctaes/COPYING | 21 + depend/zcash/src/crypto/ctaes/README.md | 41 + depend/zcash/src/crypto/ctaes/bench.c | 170 + depend/zcash/src/crypto/ctaes/ctaes.c | 556 ++ depend/zcash/src/crypto/ctaes/ctaes.h | 41 + depend/zcash/src/crypto/ctaes/test.c | 110 + depend/zcash/src/crypto/equihash.cpp | 768 ++ depend/zcash/src/crypto/equihash.h | 293 + depend/zcash/src/crypto/equihash.tcc | 49 + depend/zcash/src/crypto/hmac_sha256.cpp | 34 + depend/zcash/src/crypto/hmac_sha256.h | 32 + depend/zcash/src/crypto/hmac_sha512.cpp | 34 + depend/zcash/src/crypto/hmac_sha512.h | 32 + depend/zcash/src/crypto/ripemd160.cpp | 292 + depend/zcash/src/crypto/ripemd160.h | 28 + depend/zcash/src/crypto/sha1.cpp | 199 + depend/zcash/src/crypto/sha1.h | 28 + depend/zcash/src/crypto/sha256.cpp | 199 + depend/zcash/src/crypto/sha256.h | 32 + depend/zcash/src/crypto/sha512.cpp | 207 + depend/zcash/src/crypto/sha512.h | 28 + depend/zcash/src/dbwrapper.cpp | 107 + depend/zcash/src/dbwrapper.h | 264 + depend/zcash/src/deprecation.cpp | 123 + depend/zcash/src/deprecation.h | 87 + depend/zcash/src/experimental_features.cpp | 56 + depend/zcash/src/experimental_features.h | 21 + depend/zcash/src/fs.cpp | 15 + depend/zcash/src/fs.h | 24 + depend/zcash/src/fuzzing/CheckBlock/fuzz.cpp | 67 + .../zcash/src/fuzzing/CheckBlock/input/0.bin | Bin 0 -> 1692 bytes .../src/fuzzing/CheckBlock/input/476431.bin | Bin 0 -> 1967 bytes .../src/fuzzing/CheckBlock/input/620000.bin | Bin 0 -> 2584 bytes depend/zcash/src/fuzzing/DecodeHexTx/fuzz.cpp | 39 + .../fuzzing/DecodeHexTx/input/coinbase.txt | 1 + .../fuzzing/DecodeHexTx/input/manyoutputs.txt | 1 + .../src/fuzzing/DecodeHexTx/input/sapling.txt | 1 + .../src/fuzzing/DecodeHexTx/input/sprout.txt | 1 + .../src/fuzzing/DeserializeAddrMan/fuzz.cpp | 33 + .../input/peers.dat-minus-4-byte-header | Bin 0 -> 160686 bytes .../zcash/src/fuzzing/DeserializeTx/fuzz.cpp | 43 + .../fuzzing/DeserializeTx/input/coinbase.bin | Bin 0 -> 178 bytes .../DeserializeTx/input/manyoutputs.bin | Bin 0 -> 2734 bytes .../fuzzing/DeserializeTx/input/sapling.bin | Bin 0 -> 2373 bytes .../fuzzing/DeserializeTx/input/sprout.bin | Bin 0 -> 1823 bytes .../src/fuzzing/ReadFeeEstimates/fuzz.cpp | 34 + .../ReadFeeEstimates/input/fee_estimates.dat | Bin 0 -> 24726 bytes depend/zcash/src/fuzzing/UniValue__Read/dict | 7 + .../zcash/src/fuzzing/UniValue__Read/fuzz.cpp | 29 + .../fuzzing/UniValue__Read/input/fail1.json | 1 + .../fuzzing/UniValue__Read/input/fail10.json | 1 + .../fuzzing/UniValue__Read/input/fail11.json | 1 + .../fuzzing/UniValue__Read/input/fail12.json | 1 + .../fuzzing/UniValue__Read/input/fail13.json | 1 + .../fuzzing/UniValue__Read/input/fail14.json | 1 + .../fuzzing/UniValue__Read/input/fail15.json | 1 + .../fuzzing/UniValue__Read/input/fail16.json | 1 + .../fuzzing/UniValue__Read/input/fail17.json | 1 + .../fuzzing/UniValue__Read/input/fail18.json | 1 + .../fuzzing/UniValue__Read/input/fail19.json | 1 + .../fuzzing/UniValue__Read/input/fail2.json | 1 + .../fuzzing/UniValue__Read/input/fail20.json | 1 + .../fuzzing/UniValue__Read/input/fail21.json | 1 + .../fuzzing/UniValue__Read/input/fail22.json | 1 + .../fuzzing/UniValue__Read/input/fail23.json | 1 + .../fuzzing/UniValue__Read/input/fail24.json | 1 + .../fuzzing/UniValue__Read/input/fail25.json | 1 + .../fuzzing/UniValue__Read/input/fail26.json | 1 + .../fuzzing/UniValue__Read/input/fail27.json | 2 + .../fuzzing/UniValue__Read/input/fail28.json | 2 + .../fuzzing/UniValue__Read/input/fail29.json | 1 + .../fuzzing/UniValue__Read/input/fail3.json | 1 + .../fuzzing/UniValue__Read/input/fail30.json | 1 + .../fuzzing/UniValue__Read/input/fail31.json | 1 + .../fuzzing/UniValue__Read/input/fail32.json | 1 + .../fuzzing/UniValue__Read/input/fail33.json | 1 + .../fuzzing/UniValue__Read/input/fail34.json | 1 + .../fuzzing/UniValue__Read/input/fail35.json | 1 + .../fuzzing/UniValue__Read/input/fail36.json | 1 + .../fuzzing/UniValue__Read/input/fail37.json | 1 + .../fuzzing/UniValue__Read/input/fail38.json | 1 + .../fuzzing/UniValue__Read/input/fail39.json | 1 + .../fuzzing/UniValue__Read/input/fail4.json | 1 + .../fuzzing/UniValue__Read/input/fail40.json | 1 + .../fuzzing/UniValue__Read/input/fail41.json | 1 + .../fuzzing/UniValue__Read/input/fail42.json | Bin 0 -> 37 bytes .../fuzzing/UniValue__Read/input/fail5.json | 1 + .../fuzzing/UniValue__Read/input/fail6.json | 1 + .../fuzzing/UniValue__Read/input/fail7.json | 1 + .../fuzzing/UniValue__Read/input/fail8.json | 1 + .../fuzzing/UniValue__Read/input/fail9.json | 1 + .../fuzzing/UniValue__Read/input/pass1.json | 58 + .../fuzzing/UniValue__Read/input/pass2.json | 1 + .../fuzzing/UniValue__Read/input/pass3.json | 6 + .../fuzzing/UniValue__Read/input/round1.json | 1 + .../fuzzing/UniValue__Read/input/round2.json | 1 + .../fuzzing/UniValue__Read/input/round3.json | 1 + .../fuzzing/UniValue__Read/input/round4.json | 1 + .../fuzzing/UniValue__Read/input/round5.json | 1 + .../fuzzing/UniValue__Read/input/round6.json | 1 + .../fuzzing/UniValue__Read/input/round7.json | 1 + .../data/tx-orchard-duplicate-nullifiers.h | 4 + depend/zcash/src/gtest/json_test_vectors.cpp | 14 + depend/zcash/src/gtest/json_test_vectors.h | 56 + depend/zcash/src/gtest/main.cpp | 98 + depend/zcash/src/gtest/test_allocator.cpp | 22 + depend/zcash/src/gtest/test_block.cpp | 15 + depend/zcash/src/gtest/test_checkblock.cpp | 398 + .../zcash/src/gtest/test_checktransaction.cpp | 1659 ++++ depend/zcash/src/gtest/test_coins.cpp | 809 ++ depend/zcash/src/gtest/test_consensus.cpp | 1298 +++ depend/zcash/src/gtest/test_deprecation.cpp | 150 + depend/zcash/src/gtest/test_dynamicusage.cpp | 118 + depend/zcash/src/gtest/test_equihash.cpp | 294 + .../zcash/src/gtest/test_feature_flagging.cpp | 97 + .../zcash/src/gtest/test_foundersreward.cpp | 300 + depend/zcash/src/gtest/test_history.cpp | 215 + depend/zcash/src/gtest/test_httprpc.cpp | 62 + depend/zcash/src/gtest/test_joinsplit.cpp | 660 ++ depend/zcash/src/gtest/test_keys.cpp | 313 + depend/zcash/src/gtest/test_keystore.cpp | 634 ++ .../zcash/src/gtest/test_libzcash_utils.cpp | 44 + depend/zcash/src/gtest/test_mempool.cpp | 272 + depend/zcash/src/gtest/test_mempoollimit.cpp | 166 + depend/zcash/src/gtest/test_merkletree.cpp | 324 + depend/zcash/src/gtest/test_metrics.cpp | 184 + depend/zcash/src/gtest/test_miner.cpp | 125 + .../zcash/src/gtest/test_noteencryption.cpp | 789 ++ depend/zcash/src/gtest/test_pedersen_hash.cpp | 15 + depend/zcash/src/gtest/test_pow.cpp | 125 + depend/zcash/src/gtest/test_random.cpp | 33 + depend/zcash/src/gtest/test_rpc.cpp | 109 + depend/zcash/src/gtest/test_sapling_note.cpp | 72 + depend/zcash/src/gtest/test_sighash.cpp | 129 + depend/zcash/src/gtest/test_tautology.cpp | 10 + depend/zcash/src/gtest/test_timedata.cpp | 100 + depend/zcash/src/gtest/test_transaction.cpp | 93 + .../src/gtest/test_transaction_builder.cpp | 505 ++ .../src/gtest/test_transaction_builder.h | 73 + depend/zcash/src/gtest/test_txid.cpp | 34 + depend/zcash/src/gtest/test_upgrades.cpp | 202 + depend/zcash/src/gtest/test_validation.cpp | 295 + depend/zcash/src/gtest/test_zip32.cpp | 188 + depend/zcash/src/gtest/utils.cpp | 68 + depend/zcash/src/gtest/utils.h | 32 + depend/zcash/src/hash.cpp | 210 + depend/zcash/src/hash.h | 240 + depend/zcash/src/httprpc.cpp | 250 + depend/zcash/src/httprpc.h | 37 + depend/zcash/src/httpserver.cpp | 670 ++ depend/zcash/src/httpserver.h | 150 + depend/zcash/src/init.cpp | 1947 ++++ depend/zcash/src/init.h | 42 + depend/zcash/src/key.cpp | 370 + depend/zcash/src/key.h | 201 + depend/zcash/src/key_constants.h | 57 + depend/zcash/src/key_io.cpp | 532 ++ depend/zcash/src/key_io.h | 50 + depend/zcash/src/keystore.cpp | 547 ++ depend/zcash/src/keystore.h | 445 + depend/zcash/src/leveldb/.gitignore | 13 + depend/zcash/src/leveldb/.travis.yml | 13 + depend/zcash/src/leveldb/AUTHORS | 12 + depend/zcash/src/leveldb/CONTRIBUTING.md | 36 + depend/zcash/src/leveldb/LICENSE | 27 + depend/zcash/src/leveldb/Makefile | 424 + depend/zcash/src/leveldb/NEWS | 17 + depend/zcash/src/leveldb/README.md | 174 + depend/zcash/src/leveldb/TODO | 14 + depend/zcash/src/leveldb/WINDOWS.md | 39 + .../zcash/src/leveldb/build_detect_platform | 250 + .../zcash/src/leveldb/db/autocompact_test.cc | 118 + depend/zcash/src/leveldb/db/builder.cc | 88 + depend/zcash/src/leveldb/db/builder.h | 34 + depend/zcash/src/leveldb/db/c.cc | 597 ++ depend/zcash/src/leveldb/db/c_test.c | 390 + .../zcash/src/leveldb/db/corruption_test.cc | 374 + depend/zcash/src/leveldb/db/db_bench.cc | 1020 +++ depend/zcash/src/leveldb/db/db_impl.cc | 1568 ++++ depend/zcash/src/leveldb/db/db_impl.h | 211 + depend/zcash/src/leveldb/db/db_iter.cc | 317 + depend/zcash/src/leveldb/db/db_iter.h | 28 + depend/zcash/src/leveldb/db/db_test.cc | 2158 +++++ depend/zcash/src/leveldb/db/dbformat.cc | 140 + depend/zcash/src/leveldb/db/dbformat.h | 230 + depend/zcash/src/leveldb/db/dbformat_test.cc | 112 + depend/zcash/src/leveldb/db/dumpfile.cc | 225 + .../src/leveldb/db/fault_injection_test.cc | 554 ++ depend/zcash/src/leveldb/db/filename.cc | 144 + depend/zcash/src/leveldb/db/filename.h | 85 + depend/zcash/src/leveldb/db/filename_test.cc | 123 + depend/zcash/src/leveldb/db/leveldbutil.cc | 65 + depend/zcash/src/leveldb/db/log_format.h | 35 + depend/zcash/src/leveldb/db/log_reader.cc | 284 + depend/zcash/src/leveldb/db/log_reader.h | 113 + depend/zcash/src/leveldb/db/log_test.cc | 591 ++ depend/zcash/src/leveldb/db/log_writer.cc | 112 + depend/zcash/src/leveldb/db/log_writer.h | 54 + depend/zcash/src/leveldb/db/memtable.cc | 145 + depend/zcash/src/leveldb/db/memtable.h | 88 + depend/zcash/src/leveldb/db/recovery_test.cc | 324 + depend/zcash/src/leveldb/db/repair.cc | 461 + depend/zcash/src/leveldb/db/skiplist.h | 384 + depend/zcash/src/leveldb/db/skiplist_test.cc | 378 + depend/zcash/src/leveldb/db/snapshot.h | 67 + depend/zcash/src/leveldb/db/table_cache.cc | 127 + depend/zcash/src/leveldb/db/table_cache.h | 61 + depend/zcash/src/leveldb/db/version_edit.cc | 266 + depend/zcash/src/leveldb/db/version_edit.h | 107 + .../zcash/src/leveldb/db/version_edit_test.cc | 46 + depend/zcash/src/leveldb/db/version_set.cc | 1535 ++++ depend/zcash/src/leveldb/db/version_set.h | 398 + .../zcash/src/leveldb/db/version_set_test.cc | 179 + depend/zcash/src/leveldb/db/write_batch.cc | 147 + .../src/leveldb/db/write_batch_internal.h | 50 + .../zcash/src/leveldb/db/write_batch_test.cc | 120 + .../src/leveldb/doc/bench/db_bench_sqlite3.cc | 718 ++ .../src/leveldb/doc/bench/db_bench_tree_db.cc | 528 ++ depend/zcash/src/leveldb/doc/benchmark.html | 459 + depend/zcash/src/leveldb/doc/impl.md | 170 + depend/zcash/src/leveldb/doc/index.md | 523 ++ depend/zcash/src/leveldb/doc/log_format.md | 75 + depend/zcash/src/leveldb/doc/table_format.md | 107 + .../src/leveldb/helpers/memenv/memenv.cc | 401 + .../zcash/src/leveldb/helpers/memenv/memenv.h | 20 + .../src/leveldb/helpers/memenv/memenv_test.cc | 241 + depend/zcash/src/leveldb/include/leveldb/c.h | 290 + .../zcash/src/leveldb/include/leveldb/cache.h | 110 + .../src/leveldb/include/leveldb/comparator.h | 63 + depend/zcash/src/leveldb/include/leveldb/db.h | 163 + .../src/leveldb/include/leveldb/dumpfile.h | 25 + .../zcash/src/leveldb/include/leveldb/env.h | 360 + .../leveldb/include/leveldb/filter_policy.h | 70 + .../src/leveldb/include/leveldb/iterator.h | 100 + .../src/leveldb/include/leveldb/options.h | 213 + .../zcash/src/leveldb/include/leveldb/slice.h | 109 + .../src/leveldb/include/leveldb/status.h | 112 + .../zcash/src/leveldb/include/leveldb/table.h | 85 + .../leveldb/include/leveldb/table_builder.h | 92 + .../src/leveldb/include/leveldb/write_batch.h | 64 + .../zcash/src/leveldb/issues/issue178_test.cc | 92 + .../zcash/src/leveldb/issues/issue200_test.cc | 59 + depend/zcash/src/leveldb/port/README | 10 + .../zcash/src/leveldb/port/atomic_pointer.h | 245 + depend/zcash/src/leveldb/port/port.h | 21 + depend/zcash/src/leveldb/port/port_example.h | 145 + depend/zcash/src/leveldb/port/port_posix.cc | 67 + depend/zcash/src/leveldb/port/port_posix.h | 161 + .../zcash/src/leveldb/port/port_posix_sse.cc | 110 + depend/zcash/src/leveldb/port/port_win.cc | 158 + depend/zcash/src/leveldb/port/port_win.h | 185 + .../src/leveldb/port/thread_annotations.h | 60 + depend/zcash/src/leveldb/port/win/stdint.h | 24 + depend/zcash/src/leveldb/table/block.cc | 268 + depend/zcash/src/leveldb/table/block.h | 44 + .../zcash/src/leveldb/table/block_builder.cc | 109 + .../zcash/src/leveldb/table/block_builder.h | 57 + .../zcash/src/leveldb/table/filter_block.cc | 111 + depend/zcash/src/leveldb/table/filter_block.h | 68 + .../src/leveldb/table/filter_block_test.cc | 128 + depend/zcash/src/leveldb/table/format.cc | 144 + depend/zcash/src/leveldb/table/format.h | 108 + depend/zcash/src/leveldb/table/iterator.cc | 67 + .../src/leveldb/table/iterator_wrapper.h | 66 + depend/zcash/src/leveldb/table/merger.cc | 197 + depend/zcash/src/leveldb/table/merger.h | 26 + depend/zcash/src/leveldb/table/table.cc | 285 + .../zcash/src/leveldb/table/table_builder.cc | 270 + depend/zcash/src/leveldb/table/table_test.cc | 876 ++ .../src/leveldb/table/two_level_iterator.cc | 182 + .../src/leveldb/table/two_level_iterator.h | 34 + depend/zcash/src/leveldb/util/arena.cc | 68 + depend/zcash/src/leveldb/util/arena.h | 68 + depend/zcash/src/leveldb/util/arena_test.cc | 68 + depend/zcash/src/leveldb/util/bloom.cc | 95 + depend/zcash/src/leveldb/util/bloom_test.cc | 162 + depend/zcash/src/leveldb/util/cache.cc | 405 + depend/zcash/src/leveldb/util/cache_test.cc | 226 + depend/zcash/src/leveldb/util/coding.cc | 194 + depend/zcash/src/leveldb/util/coding.h | 104 + depend/zcash/src/leveldb/util/coding_test.cc | 196 + depend/zcash/src/leveldb/util/comparator.cc | 81 + depend/zcash/src/leveldb/util/crc32c.cc | 354 + depend/zcash/src/leveldb/util/crc32c.h | 45 + depend/zcash/src/leveldb/util/crc32c_test.cc | 72 + depend/zcash/src/leveldb/util/env.cc | 100 + depend/zcash/src/leveldb/util/env_posix.cc | 706 ++ .../zcash/src/leveldb/util/env_posix_test.cc | 66 + .../src/leveldb/util/env_posix_test_helper.h | 28 + depend/zcash/src/leveldb/util/env_test.cc | 106 + depend/zcash/src/leveldb/util/env_win.cc | 902 ++ .../zcash/src/leveldb/util/filter_policy.cc | 11 + depend/zcash/src/leveldb/util/hash.cc | 52 + depend/zcash/src/leveldb/util/hash.h | 19 + depend/zcash/src/leveldb/util/hash_test.cc | 54 + depend/zcash/src/leveldb/util/histogram.cc | 139 + depend/zcash/src/leveldb/util/histogram.h | 42 + depend/zcash/src/leveldb/util/logging.cc | 72 + depend/zcash/src/leveldb/util/logging.h | 43 + depend/zcash/src/leveldb/util/mutexlock.h | 41 + depend/zcash/src/leveldb/util/options.cc | 30 + depend/zcash/src/leveldb/util/posix_logger.h | 98 + depend/zcash/src/leveldb/util/random.h | 64 + depend/zcash/src/leveldb/util/status.cc | 75 + depend/zcash/src/leveldb/util/testharness.cc | 77 + depend/zcash/src/leveldb/util/testharness.h | 138 + depend/zcash/src/leveldb/util/testutil.cc | 51 + depend/zcash/src/leveldb/util/testutil.h | 63 + depend/zcash/src/limitedmap.h | 97 + depend/zcash/src/logging.cpp | 149 + depend/zcash/src/logging.h | 59 + depend/zcash/src/main.cpp | 7891 +++++++++++++++++ depend/zcash/src/main.h | 640 ++ depend/zcash/src/mempool_limit.cpp | 159 + depend/zcash/src/mempool_limit.h | 131 + depend/zcash/src/memusage.h | 143 + depend/zcash/src/merkleblock.cpp | 179 + depend/zcash/src/merkleblock.h | 156 + depend/zcash/src/metrics.cpp | 705 ++ depend/zcash/src/metrics.h | 121 + depend/zcash/src/miner.cpp | 1167 +++ depend/zcash/src/miner.h | 114 + depend/zcash/src/net.cpp | 2397 +++++ depend/zcash/src/net.h | 742 ++ depend/zcash/src/netbase.cpp | 1468 +++ depend/zcash/src/netbase.h | 225 + depend/zcash/src/noui.cpp | 60 + depend/zcash/src/noui.h | 10 + depend/zcash/src/obj/.gitignore | 2 + depend/zcash/src/policy/fees.cpp | 538 ++ depend/zcash/src/policy/fees.h | 285 + depend/zcash/src/policy/policy.cpp | 194 + depend/zcash/src/policy/policy.h | 62 + depend/zcash/src/pow.cpp | 172 + depend/zcash/src/pow.h | 35 + depend/zcash/src/pow/tromp/equi.h | 105 + depend/zcash/src/pow/tromp/equi_miner.h | 651 ++ depend/zcash/src/pow/tromp/osx_barrier.h | 75 + depend/zcash/src/prevector.h | 487 + depend/zcash/src/primitives/block.cpp | 198 + depend/zcash/src/primitives/block.h | 218 + depend/zcash/src/primitives/orchard.h | 143 + depend/zcash/src/primitives/transaction.cpp | 432 + depend/zcash/src/primitives/transaction.h | 1147 +++ .../zcash/src/primitives/tx_version_info.cpp | 47 + depend/zcash/src/proof_verifier.cpp | 71 + depend/zcash/src/proof_verifier.h | 42 + depend/zcash/src/protocol.cpp | 156 + depend/zcash/src/protocol.h | 204 + depend/zcash/src/pubkey.cpp | 175 + depend/zcash/src/pubkey.h | 318 + depend/zcash/src/random.cpp | 93 + depend/zcash/src/random.h | 164 + depend/zcash/src/rest.cpp | 630 ++ depend/zcash/src/reverse_iterator.h | 39 + depend/zcash/src/reverselock.h | 34 + depend/zcash/src/rpc/blockchain.cpp | 1508 ++++ depend/zcash/src/rpc/client.cpp | 205 + depend/zcash/src/rpc/client.h | 17 + depend/zcash/src/rpc/mining.cpp | 1080 +++ depend/zcash/src/rpc/misc.cpp | 1243 +++ depend/zcash/src/rpc/net.cpp | 648 ++ depend/zcash/src/rpc/protocol.cpp | 127 + depend/zcash/src/rpc/protocol.h | 95 + depend/zcash/src/rpc/rawtransaction.cpp | 1194 +++ depend/zcash/src/rpc/register.h | 32 + depend/zcash/src/rpc/server.cpp | 580 ++ depend/zcash/src/rpc/server.h | 197 + depend/zcash/src/rust/README.md | 30 + depend/zcash/src/rust/bin/wallet_tool.rs | 664 ++ depend/zcash/src/rust/include/librustzcash.h | 401 + depend/zcash/src/rust/include/rust/VA_OPT.hpp | 156 + depend/zcash/src/rust/include/rust/address.h | 54 + depend/zcash/src/rust/include/rust/blake2b.h | 59 + depend/zcash/src/rust/include/rust/builder.h | 105 + depend/zcash/src/rust/include/rust/ed25519.h | 59 + .../src/rust/include/rust/ed25519/types.h | 56 + depend/zcash/src/rust/include/rust/helpers.h | 34 + depend/zcash/src/rust/include/rust/history.h | 74 + depend/zcash/src/rust/include/rust/map.h | 71 + depend/zcash/src/rust/include/rust/metrics.h | 314 + depend/zcash/src/rust/include/rust/orchard.h | 190 + .../rust/orchard/incremental_merkle_tree.h | 96 + .../src/rust/include/rust/orchard/keys.h | 269 + .../src/rust/include/rust/orchard/wallet.h | 397 + depend/zcash/src/rust/include/rust/streams.h | 23 + .../src/rust/include/rust/test_harness.h | 28 + .../zcash/src/rust/include/rust/transaction.h | 68 + depend/zcash/src/rust/include/rust/types.h | 16 + .../src/rust/include/rust/unified_keys.h | 144 + depend/zcash/src/rust/include/rust/zip339.h | 59 + depend/zcash/src/rust/include/tracing.h | 316 + depend/zcash/src/rust/src/address_ffi.rs | 231 + depend/zcash/src/rust/src/blake2b.rs | 56 + depend/zcash/src/rust/src/builder_ffi.rs | 232 + depend/zcash/src/rust/src/ed25519.rs | 67 + depend/zcash/src/rust/src/history_ffi.rs | 265 + .../src/rust/src/incremental_merkle_tree.rs | 141 + .../rust/src/incremental_merkle_tree_ffi.rs | 186 + depend/zcash/src/rust/src/metrics_ffi.rs | 240 + depend/zcash/src/rust/src/orchard_ffi.rs | 344 + depend/zcash/src/rust/src/orchard_keys_ffi.rs | 402 + depend/zcash/src/rust/src/rustzcash.rs | 1206 +++ depend/zcash/src/rust/src/streams_ffi.rs | 54 + depend/zcash/src/rust/src/test_harness_ffi.rs | 13 + .../zcash/src/rust/src/tests/key_agreement.rs | 72 + .../src/rust/src/tests/key_components.rs | 703 ++ depend/zcash/src/rust/src/tests/mmr.rs | 225 + depend/zcash/src/rust/src/tests/mod.rs | 81 + depend/zcash/src/rust/src/tests/notes.rs | 674 ++ .../zcash/src/rust/src/tests/res/tree1023.dat | Bin 0 -> 153867 bytes .../zcash/src/rust/src/tests/res/tree16.dat | Bin 0 -> 2352 bytes depend/zcash/src/rust/src/tests/signatures.rs | 510 ++ depend/zcash/src/rust/src/tests/zip339.rs | 120 + depend/zcash/src/rust/src/tracing_ffi.rs | 675 ++ depend/zcash/src/rust/src/transaction_ffi.rs | 338 + depend/zcash/src/rust/src/unified_keys_ffi.rs | 217 + depend/zcash/src/rust/src/wallet.rs | 1400 +++ depend/zcash/src/rust/src/zcashd_orchard.rs | 35 + depend/zcash/src/rust/src/zip339_ffi.rs | 114 + depend/zcash/src/scheduler.cpp | 122 + depend/zcash/src/scheduler.h | 82 + depend/zcash/src/script/interpreter.cpp | 1519 ++++ depend/zcash/src/script/interpreter.h | 195 + depend/zcash/src/script/ismine.cpp | 124 + depend/zcash/src/script/ismine.h | 33 + depend/zcash/src/script/script.cpp | 271 + depend/zcash/src/script/script.h | 647 ++ depend/zcash/src/script/script_error.cpp | 75 + depend/zcash/src/script/script_error.h | 62 + depend/zcash/src/script/sigcache.cpp | 113 + depend/zcash/src/script/sigcache.h | 30 + depend/zcash/src/script/sign.cpp | 386 + depend/zcash/src/script/sign.h | 104 + depend/zcash/src/script/standard.cpp | 304 + depend/zcash/src/script/standard.h | 130 + depend/zcash/src/script/zcash_script.cpp | 329 + depend/zcash/src/script/zcash_script.h | 189 + depend/zcash/src/secp256k1/.gitignore | 53 + depend/zcash/src/secp256k1/.travis.yml | 109 + depend/zcash/src/secp256k1/COPYING | 19 + depend/zcash/src/secp256k1/Makefile.am | 164 + depend/zcash/src/secp256k1/README.md | 104 + depend/zcash/src/secp256k1/SECURITY.md | 15 + depend/zcash/src/secp256k1/autogen.sh | 3 + .../build-aux/m4/ax_prog_cc_for_build.m4 | 125 + .../secp256k1/build-aux/m4/bitcoin_secp.m4 | 97 + depend/zcash/src/secp256k1/configure.ac | 585 ++ .../src/secp256k1/contrib/lax_der_parsing.c | 149 + .../src/secp256k1/contrib/lax_der_parsing.h | 91 + .../contrib/lax_der_privatekey_parsing.c | 113 + .../contrib/lax_der_privatekey_parsing.h | 90 + depend/zcash/src/secp256k1/contrib/travis.sh | 68 + .../zcash/src/secp256k1/include/secp256k1.h | 771 ++ .../src/secp256k1/include/secp256k1_ecdh.h | 62 + .../secp256k1/include/secp256k1_extrakeys.h | 249 + .../include/secp256k1_preallocated.h | 128 + .../secp256k1/include/secp256k1_recovery.h | 110 + .../secp256k1/include/secp256k1_schnorrsig.h | 111 + depend/zcash/src/secp256k1/libsecp256k1.pc.in | 13 + depend/zcash/src/secp256k1/obj/.gitignore | 0 .../secp256k1/sage/gen_exhaustive_groups.sage | 124 + .../sage/gen_split_lambda_constants.sage | 114 + .../src/secp256k1/sage/group_prover.sage | 327 + .../sage/prove_group_implementations.sage | 306 + .../src/secp256k1/sage/secp256k1_params.sage | 36 + .../secp256k1/sage/weierstrass_prover.sage | 264 + .../src/secp256k1/src/asm/field_10x26_arm.s | 913 ++ depend/zcash/src/secp256k1/src/assumptions.h | 80 + depend/zcash/src/secp256k1/src/basic-config.h | 34 + depend/zcash/src/secp256k1/src/bench.h | 133 + depend/zcash/src/secp256k1/src/bench_ecdh.c | 59 + depend/zcash/src/secp256k1/src/bench_ecmult.c | 214 + .../zcash/src/secp256k1/src/bench_internal.c | 431 + .../zcash/src/secp256k1/src/bench_recover.c | 62 + .../src/secp256k1/src/bench_schnorrsig.c | 102 + depend/zcash/src/secp256k1/src/bench_sign.c | 58 + depend/zcash/src/secp256k1/src/bench_verify.c | 115 + depend/zcash/src/secp256k1/src/ecdsa.h | 21 + depend/zcash/src/secp256k1/src/ecdsa_impl.h | 315 + depend/zcash/src/secp256k1/src/eckey.h | 25 + depend/zcash/src/secp256k1/src/eckey_impl.h | 96 + depend/zcash/src/secp256k1/src/ecmult.h | 46 + depend/zcash/src/secp256k1/src/ecmult_const.h | 20 + .../src/secp256k1/src/ecmult_const_impl.h | 254 + depend/zcash/src/secp256k1/src/ecmult_gen.h | 50 + .../zcash/src/secp256k1/src/ecmult_gen_impl.h | 208 + depend/zcash/src/secp256k1/src/ecmult_impl.h | 1083 +++ depend/zcash/src/secp256k1/src/field.h | 129 + depend/zcash/src/secp256k1/src/field_10x26.h | 50 + .../src/secp256k1/src/field_10x26_impl.h | 1167 +++ depend/zcash/src/secp256k1/src/field_5x52.h | 55 + .../src/secp256k1/src/field_5x52_asm_impl.h | 502 ++ .../zcash/src/secp256k1/src/field_5x52_impl.h | 501 ++ .../secp256k1/src/field_5x52_int128_impl.h | 279 + depend/zcash/src/secp256k1/src/field_impl.h | 293 + depend/zcash/src/secp256k1/src/gen_context.c | 88 + depend/zcash/src/secp256k1/src/group.h | 154 + depend/zcash/src/secp256k1/src/group_impl.h | 693 ++ depend/zcash/src/secp256k1/src/hash.h | 41 + depend/zcash/src/secp256k1/src/hash_impl.h | 297 + .../src/modules/ecdh/Makefile.am.include | 8 + .../secp256k1/src/modules/ecdh/main_impl.h | 71 + .../secp256k1/src/modules/ecdh/tests_impl.h | 132 + .../src/modules/extrakeys/Makefile.am.include | 4 + .../src/modules/extrakeys/main_impl.h | 261 + .../modules/extrakeys/tests_exhaustive_impl.h | 68 + .../src/modules/extrakeys/tests_impl.h | 549 ++ .../src/modules/recovery/Makefile.am.include | 9 + .../src/modules/recovery/main_impl.h | 160 + .../modules/recovery/tests_exhaustive_impl.h | 149 + .../src/modules/recovery/tests_impl.h | 393 + .../modules/schnorrsig/Makefile.am.include | 9 + .../src/modules/schnorrsig/main_impl.h | 239 + .../schnorrsig/tests_exhaustive_impl.h | 206 + .../src/modules/schnorrsig/tests_impl.h | 806 ++ depend/zcash/src/secp256k1/src/num.h | 74 + depend/zcash/src/secp256k1/src/num_gmp.h | 20 + depend/zcash/src/secp256k1/src/num_gmp_impl.h | 288 + depend/zcash/src/secp256k1/src/num_impl.h | 24 + depend/zcash/src/secp256k1/src/scalar.h | 117 + depend/zcash/src/secp256k1/src/scalar_4x64.h | 19 + .../src/secp256k1/src/scalar_4x64_impl.h | 986 ++ depend/zcash/src/secp256k1/src/scalar_8x32.h | 19 + .../src/secp256k1/src/scalar_8x32_impl.h | 734 ++ depend/zcash/src/secp256k1/src/scalar_impl.h | 516 ++ depend/zcash/src/secp256k1/src/scalar_low.h | 17 + .../zcash/src/secp256k1/src/scalar_low_impl.h | 128 + depend/zcash/src/secp256k1/src/scratch.h | 42 + depend/zcash/src/secp256k1/src/scratch_impl.h | 99 + depend/zcash/src/secp256k1/src/secp256k1.c | 776 ++ depend/zcash/src/secp256k1/src/selftest.h | 32 + depend/zcash/src/secp256k1/src/testrand.h | 47 + .../zcash/src/secp256k1/src/testrand_impl.h | 158 + depend/zcash/src/secp256k1/src/tests.c | 5696 ++++++++++++ .../src/secp256k1/src/tests_exhaustive.c | 454 + depend/zcash/src/secp256k1/src/util.h | 279 + .../src/secp256k1/src/valgrind_ctime_test.c | 163 + depend/zcash/src/sendalert.cpp | 173 + depend/zcash/src/serialize.h | 1178 +++ depend/zcash/src/spentindex.h | 97 + depend/zcash/src/streams.h | 704 ++ depend/zcash/src/support/allocators/secure.h | 61 + .../src/support/allocators/zeroafterfree.h | 48 + depend/zcash/src/support/cleanse.cpp | 38 + depend/zcash/src/support/cleanse.h | 15 + depend/zcash/src/support/events.h | 56 + depend/zcash/src/support/lockedpool.cpp | 417 + depend/zcash/src/support/lockedpool.h | 238 + depend/zcash/src/sync.cpp | 224 + depend/zcash/src/sync.h | 295 + depend/zcash/src/test/Checkpoints_tests.cpp | 29 + depend/zcash/src/test/DoS_tests.cpp | 212 + depend/zcash/src/test/Makefile | 6 + depend/zcash/src/test/README.md | 43 + depend/zcash/src/test/addrman_tests.cpp | 522 ++ depend/zcash/src/test/alert_tests.cpp | 412 + depend/zcash/src/test/allocator_tests.cpp | 228 + depend/zcash/src/test/arith_uint256_tests.cpp | 567 ++ depend/zcash/src/test/base32_tests.cpp | 25 + depend/zcash/src/test/base58_tests.cpp | 199 + depend/zcash/src/test/base64_tests.cpp | 25 + depend/zcash/src/test/bctest.py | 127 + depend/zcash/src/test/bech32_tests.cpp | 125 + depend/zcash/src/test/bip32_tests.cpp | 140 + depend/zcash/src/test/bitcoin-util-test.py | 45 + depend/zcash/src/test/bloom_tests.cpp | 540 ++ depend/zcash/src/test/buildenv.py.in | 2 + depend/zcash/src/test/checkblock_tests.cpp | 66 + depend/zcash/src/test/checkqueue_tests.cpp | 441 + depend/zcash/src/test/coins_tests.cpp | 759 ++ depend/zcash/src/test/compress_tests.cpp | 65 + depend/zcash/src/test/convertbits_tests.cpp | 52 + depend/zcash/src/test/crypto_tests.cpp | 507 ++ depend/zcash/src/test/data/README.md | 12 + depend/zcash/src/test/data/alertTests.raw | Bin 0 -> 2111 bytes .../src/test/data/base58_encode_decode.json | 14 + .../src/test/data/base58_keys_invalid.json | 152 + .../src/test/data/base58_keys_valid.json | 426 + .../src/test/data/bitcoin-util-test.json | 160 + depend/zcash/src/test/data/blanktx.hex | 1 + depend/zcash/src/test/data/blanktx.json | 10 + .../src/test/data/merkle_commitments.json | 18 + .../test/data/merkle_commitments_sapling.json | 18 + depend/zcash/src/test/data/merkle_path.json | 122 + .../src/test/data/merkle_path_sapling.json | 122 + depend/zcash/src/test/data/merkle_roots.json | 18 + .../src/test/data/merkle_roots_orchard.h | 5595 ++++++++++++ .../src/test/data/merkle_roots_sapling.json | 18 + .../src/test/data/merkle_serialization.json | 18 + .../data/merkle_serialization_sapling.json | 18 + .../data/merkle_witness_serialization.json | 138 + .../merkle_witness_serialization_sapling.json | 138 + .../src/test/data/sapling_key_components.json | 14 + .../zcash/src/test/data/script_invalid.json | 772 ++ depend/zcash/src/test/data/script_valid.json | 834 ++ depend/zcash/src/test/data/sighash.json | 503 ++ depend/zcash/src/test/data/tt-delin1-out.hex | 1 + depend/zcash/src/test/data/tt-delin1-out.json | 216 + depend/zcash/src/test/data/tt-delout1-out.hex | 1 + .../zcash/src/test/data/tt-delout1-out.json | 212 + .../src/test/data/tt-locktime317000-out.hex | 1 + .../src/test/data/tt-locktime317000-out.json | 225 + depend/zcash/src/test/data/tx394b54bb.hex | 1 + depend/zcash/src/test/data/tx_invalid.json | 245 + depend/zcash/src/test/data/tx_valid.json | 138 + depend/zcash/src/test/data/txcreate1.hex | 1 + depend/zcash/src/test/data/txcreate1.json | 63 + depend/zcash/src/test/data/txcreate2.hex | 1 + depend/zcash/src/test/data/txcreate2.json | 19 + .../zcash/src/test/data/txcreatedata_seq0.hex | 1 + .../src/test/data/txcreatedata_seq0.json | 32 + .../zcash/src/test/data/txcreatedata_seq1.hex | 1 + .../src/test/data/txcreatedata_seq1.json | 41 + depend/zcash/src/test/data/txcreatesign.hex | 1 + depend/zcash/src/test/data/txcreatesign.json | 32 + depend/zcash/src/test/data/unified_addrs.json | 24 + .../test/data/unified_full_viewing_keys.json | 25 + depend/zcash/src/test/data/zip0244.json | 14 + depend/zcash/src/test/dbwrapper_tests.cpp | 234 + depend/zcash/src/test/equihash_tests.cpp | 235 + depend/zcash/src/test/getarg_tests.cpp | 161 + depend/zcash/src/test/hash_tests.cpp | 127 + depend/zcash/src/test/key_tests.cpp | 265 + depend/zcash/src/test/limitedmap_tests.cpp | 101 + depend/zcash/src/test/main_tests.cpp | 126 + depend/zcash/src/test/mempool_tests.cpp | 249 + depend/zcash/src/test/miner_tests.cpp | 468 + depend/zcash/src/test/multisig_tests.cpp | 238 + depend/zcash/src/test/net_tests.cpp | 145 + depend/zcash/src/test/netbase_tests.cpp | 254 + depend/zcash/src/test/pmt_tests.cpp | 126 + .../zcash/src/test/policyestimator_tests.cpp | 208 + depend/zcash/src/test/pow_tests.cpp | 167 + depend/zcash/src/test/prevector_tests.cpp | 251 + depend/zcash/src/test/raii_event_tests.cpp | 94 + depend/zcash/src/test/random_tests.cpp | 48 + depend/zcash/src/test/reverselock_tests.cpp | 60 + depend/zcash/src/test/rpc_tests.cpp | 415 + depend/zcash/src/test/sanity_tests.cpp | 20 + depend/zcash/src/test/scheduler_tests.cpp | 110 + depend/zcash/src/test/script_P2PKH_tests.cpp | 59 + depend/zcash/src/test/script_P2SH_tests.cpp | 405 + .../zcash/src/test/script_standard_tests.cpp | 526 ++ depend/zcash/src/test/script_tests.cpp | 983 ++ depend/zcash/src/test/scriptnum10.h | 209 + depend/zcash/src/test/scriptnum_tests.cpp | 247 + depend/zcash/src/test/serialize_tests.cpp | 420 + .../zcash/src/test/sha256compress_tests.cpp | 86 + depend/zcash/src/test/sighash_tests.cpp | 346 + depend/zcash/src/test/sigopcount_tests.cpp | 65 + depend/zcash/src/test/skiplist_tests.cpp | 103 + depend/zcash/src/test/streams_tests.cpp | 257 + depend/zcash/src/test/test_bitcoin.cpp | 217 + depend/zcash/src/test/test_bitcoin.h | 95 + depend/zcash/src/test/test_random.h | 29 + depend/zcash/src/test/test_util.cpp | 120 + depend/zcash/src/test/test_util.h | 15 + depend/zcash/src/test/torcontrol_tests.cpp | 199 + depend/zcash/src/test/transaction_tests.cpp | 947 ++ .../src/test/txvalidationcache_tests.cpp | 89 + depend/zcash/src/test/uint256_tests.cpp | 269 + depend/zcash/src/test/univalue_tests.cpp | 320 + depend/zcash/src/test/util_tests.cpp | 624 ++ depend/zcash/src/threadsafety.h | 55 + depend/zcash/src/timedata.cpp | 70 + depend/zcash/src/timedata.h | 40 + depend/zcash/src/timestampindex.h | 131 + depend/zcash/src/tinyformat.h | 1049 +++ depend/zcash/src/torcontrol.cpp | 777 ++ depend/zcash/src/torcontrol.h | 20 + depend/zcash/src/transaction_builder.cpp | 1022 +++ depend/zcash/src/transaction_builder.h | 404 + depend/zcash/src/txdb.cpp | 670 ++ depend/zcash/src/txdb.h | 151 + depend/zcash/src/txmempool.cpp | 958 ++ depend/zcash/src/txmempool.h | 391 + depend/zcash/src/ui_interface.h | 115 + depend/zcash/src/uint252.h | 50 + depend/zcash/src/uint256.cpp | 86 + depend/zcash/src/uint256.h | 164 + depend/zcash/src/undo.h | 81 + depend/zcash/src/univalue/.gitignore | 32 + depend/zcash/src/univalue/.travis.yml | 51 + depend/zcash/src/univalue/COPYING | 19 + depend/zcash/src/univalue/Makefile.am | 118 + depend/zcash/src/univalue/README.md | 21 + depend/zcash/src/univalue/TODO | 10 + depend/zcash/src/univalue/autogen.sh | 9 + .../src/univalue/build-aux/m4/.gitignore | 1 + depend/zcash/src/univalue/configure.ac | 69 + depend/zcash/src/univalue/gen/gen.cpp | 82 + depend/zcash/src/univalue/include/univalue.h | 242 + depend/zcash/src/univalue/lib/.gitignore | 2 + depend/zcash/src/univalue/lib/univalue.cpp | 242 + .../zcash/src/univalue/lib/univalue_escapes.h | 262 + .../zcash/src/univalue/lib/univalue_get.cpp | 147 + .../zcash/src/univalue/lib/univalue_read.cpp | 460 + .../src/univalue/lib/univalue_utffilter.h | 119 + .../zcash/src/univalue/lib/univalue_write.cpp | 113 + .../univalue/pc/libunivalue-uninstalled.pc.in | 9 + .../zcash/src/univalue/pc/libunivalue.pc.in | 10 + depend/zcash/src/univalue/test/.gitignore | 8 + depend/zcash/src/univalue/test/fail1.json | 1 + depend/zcash/src/univalue/test/fail10.json | 1 + depend/zcash/src/univalue/test/fail11.json | 1 + depend/zcash/src/univalue/test/fail12.json | 1 + depend/zcash/src/univalue/test/fail13.json | 1 + depend/zcash/src/univalue/test/fail14.json | 1 + depend/zcash/src/univalue/test/fail15.json | 1 + depend/zcash/src/univalue/test/fail16.json | 1 + depend/zcash/src/univalue/test/fail17.json | 1 + depend/zcash/src/univalue/test/fail18.json | 1 + depend/zcash/src/univalue/test/fail19.json | 1 + depend/zcash/src/univalue/test/fail2.json | 1 + depend/zcash/src/univalue/test/fail20.json | 1 + depend/zcash/src/univalue/test/fail21.json | 1 + depend/zcash/src/univalue/test/fail22.json | 1 + depend/zcash/src/univalue/test/fail23.json | 1 + depend/zcash/src/univalue/test/fail24.json | 1 + depend/zcash/src/univalue/test/fail25.json | 1 + depend/zcash/src/univalue/test/fail26.json | 1 + depend/zcash/src/univalue/test/fail27.json | 2 + depend/zcash/src/univalue/test/fail28.json | 2 + depend/zcash/src/univalue/test/fail29.json | 1 + depend/zcash/src/univalue/test/fail3.json | 1 + depend/zcash/src/univalue/test/fail30.json | 1 + depend/zcash/src/univalue/test/fail31.json | 1 + depend/zcash/src/univalue/test/fail32.json | 1 + depend/zcash/src/univalue/test/fail33.json | 1 + depend/zcash/src/univalue/test/fail34.json | 1 + depend/zcash/src/univalue/test/fail35.json | 1 + depend/zcash/src/univalue/test/fail36.json | 1 + depend/zcash/src/univalue/test/fail37.json | 1 + depend/zcash/src/univalue/test/fail38.json | 1 + depend/zcash/src/univalue/test/fail39.json | 1 + depend/zcash/src/univalue/test/fail4.json | 1 + depend/zcash/src/univalue/test/fail40.json | 1 + depend/zcash/src/univalue/test/fail41.json | 1 + depend/zcash/src/univalue/test/fail42.json | Bin 0 -> 37 bytes depend/zcash/src/univalue/test/fail44.json | 1 + depend/zcash/src/univalue/test/fail45.json | 1 + depend/zcash/src/univalue/test/fail5.json | 1 + depend/zcash/src/univalue/test/fail6.json | 1 + depend/zcash/src/univalue/test/fail7.json | 1 + depend/zcash/src/univalue/test/fail8.json | 1 + depend/zcash/src/univalue/test/fail9.json | 1 + depend/zcash/src/univalue/test/no_nul.cpp | 8 + depend/zcash/src/univalue/test/object.cpp | 420 + depend/zcash/src/univalue/test/pass1.json | 58 + depend/zcash/src/univalue/test/pass2.json | 1 + depend/zcash/src/univalue/test/pass3.json | 6 + depend/zcash/src/univalue/test/pass4.json | 1 + depend/zcash/src/univalue/test/round1.json | 1 + depend/zcash/src/univalue/test/round2.json | 1 + depend/zcash/src/univalue/test/round3.json | 1 + depend/zcash/src/univalue/test/round4.json | 1 + depend/zcash/src/univalue/test/round5.json | 1 + depend/zcash/src/univalue/test/round6.json | 1 + depend/zcash/src/univalue/test/round7.json | 1 + depend/zcash/src/univalue/test/test_json.cpp | 24 + depend/zcash/src/univalue/test/unitester.cpp | 171 + depend/zcash/src/util.cpp | 682 ++ depend/zcash/src/util.h | 217 + depend/zcash/src/util/match.h | 24 + depend/zcash/src/utilmoneystr.cpp | 79 + depend/zcash/src/utilmoneystr.h | 21 + depend/zcash/src/utilstrencodings.cpp | 565 ++ depend/zcash/src/utilstrencodings.h | 176 + depend/zcash/src/utiltest.cpp | 365 + depend/zcash/src/utiltest.h | 103 + depend/zcash/src/utiltime.cpp | 60 + depend/zcash/src/utiltime.h | 20 + depend/zcash/src/validationinterface.cpp | 276 + depend/zcash/src/validationinterface.h | 85 + depend/zcash/src/version.h | 43 + .../src/wallet/asyncrpcoperation_common.cpp | 42 + .../src/wallet/asyncrpcoperation_common.h | 64 + .../asyncrpcoperation_mergetoaddress.cpp | 1024 +++ .../wallet/asyncrpcoperation_mergetoaddress.h | 194 + .../asyncrpcoperation_saplingmigration.cpp | 233 + .../asyncrpcoperation_saplingmigration.h | 39 + .../src/wallet/asyncrpcoperation_sendmany.cpp | 812 ++ .../src/wallet/asyncrpcoperation_sendmany.h | 122 + .../asyncrpcoperation_shieldcoinbase.cpp | 497 ++ .../wallet/asyncrpcoperation_shieldcoinbase.h | 148 + depend/zcash/src/wallet/crypter.cpp | 732 ++ depend/zcash/src/wallet/crypter.h | 267 + depend/zcash/src/wallet/db.cpp | 459 + depend/zcash/src/wallet/db.h | 312 + .../src/wallet/gtest/test_note_selection.cpp | 503 ++ .../src/wallet/gtest/test_orchard_wallet.cpp | 157 + .../src/wallet/gtest/test_orchard_zkeys.cpp | 35 + .../wallet/gtest/test_paymentdisclosure.cpp | 194 + .../src/wallet/gtest/test_rpc_wallet.cpp | 353 + depend/zcash/src/wallet/gtest/test_wallet.cpp | 2505 ++++++ .../src/wallet/gtest/test_wallet_zkeys.cpp | 531 ++ depend/zcash/src/wallet/orchard.cpp | 43 + depend/zcash/src/wallet/orchard.h | 532 ++ depend/zcash/src/wallet/paymentdisclosure.cpp | 69 + depend/zcash/src/wallet/paymentdisclosure.h | 167 + .../zcash/src/wallet/paymentdisclosuredb.cpp | 92 + depend/zcash/src/wallet/paymentdisclosuredb.h | 41 + depend/zcash/src/wallet/rpcdisclosure.cpp | 314 + depend/zcash/src/wallet/rpcdump.cpp | 1040 +++ depend/zcash/src/wallet/rpcwallet.cpp | 6344 +++++++++++++ depend/zcash/src/wallet/rpcwallet.h | 14 + depend/zcash/src/wallet/test/crypto_tests.cpp | 127 + .../src/wallet/test/rpc_wallet_tests.cpp | 1766 ++++ .../src/wallet/test/wallet_test_fixture.cpp | 31 + .../src/wallet/test/wallet_test_fixture.h | 17 + depend/zcash/src/wallet/test/wallet_tests.cpp | 327 + depend/zcash/src/wallet/wallet.cpp | 7858 ++++++++++++++++ depend/zcash/src/wallet/wallet.h | 2166 +++++ depend/zcash/src/wallet/walletdb.cpp | 1372 +++ depend/zcash/src/wallet/walletdb.h | 497 ++ depend/zcash/src/warnings.cpp | 117 + depend/zcash/src/warnings.h | 22 + depend/zcash/src/zcash/Address.cpp | 381 + depend/zcash/src/zcash/Address.hpp | 331 + depend/zcash/src/zcash/History.cpp | 190 + depend/zcash/src/zcash/History.hpp | 84 + .../zcash/src/zcash/IncrementalMerkleTree.cpp | 1150 +++ .../zcash/src/zcash/IncrementalMerkleTree.hpp | 356 + depend/zcash/src/zcash/JoinSplit.cpp | 252 + depend/zcash/src/zcash/JoinSplit.hpp | 84 + depend/zcash/src/zcash/Note.cpp | 503 ++ depend/zcash/src/zcash/Note.hpp | 278 + depend/zcash/src/zcash/NoteEncryption.cpp | 458 + depend/zcash/src/zcash/NoteEncryption.hpp | 203 + depend/zcash/src/zcash/Proof.hpp | 218 + depend/zcash/src/zcash/Zcash.h | 47 + depend/zcash/src/zcash/address/mnemonic.cpp | 68 + depend/zcash/src/zcash/address/mnemonic.h | 119 + depend/zcash/src/zcash/address/orchard.cpp | 73 + depend/zcash/src/zcash/address/orchard.hpp | 325 + depend/zcash/src/zcash/address/sapling.cpp | 86 + depend/zcash/src/zcash/address/sapling.hpp | 142 + depend/zcash/src/zcash/address/sprout.cpp | 44 + depend/zcash/src/zcash/address/sprout.hpp | 95 + .../zcash/src/zcash/address/transparent.cpp | 122 + depend/zcash/src/zcash/address/transparent.h | 112 + depend/zcash/src/zcash/address/unified.cpp | 257 + depend/zcash/src/zcash/address/unified.h | 291 + depend/zcash/src/zcash/address/zip32.cpp | 298 + depend/zcash/src/zcash/address/zip32.h | 329 + depend/zcash/src/zcash/prf.cpp | 154 + depend/zcash/src/zcash/prf.h | 36 + depend/zcash/src/zcash/util.cpp | 45 + depend/zcash/src/zcash/util.h | 11 + depend/zcash/src/zcbenchmarks.cpp | 767 ++ depend/zcash/src/zcbenchmarks.h | 28 + depend/zcash/src/zmq/zmqabstractnotifier.cpp | 27 + depend/zcash/src/zmq/zmqabstractnotifier.h | 45 + depend/zcash/src/zmq/zmqconfig.h | 24 + .../src/zmq/zmqnotificationinterface.cpp | 185 + .../zcash/src/zmq/zmqnotificationinterface.h | 39 + depend/zcash/src/zmq/zmqpublishnotifier.cpp | 205 + depend/zcash/src/zmq/zmqpublishnotifier.h | 61 + depend/zcash/test/lint/README.md | 31 + depend/zcash/test/lint/commit-script-check.sh | 54 + depend/zcash/test/lint/git-subtree-check.sh | 96 + depend/zcash/test/lint/lint-all.sh | 30 + depend/zcash/test/lint/lint-cargo-patches.sh | 62 + depend/zcash/test/lint/lint-include-guards.sh | 35 + depend/zcash/test/lint/lint-includes.sh | 132 + .../zcash/test/lint/lint-locale-dependence.sh | 231 + .../test/lint/lint-python-utf8-encoding.sh | 20 + depend/zcash/test/lint/lint-shebang.sh | 25 + depend/zcash/test/lint/lint-shell-locale.sh | 25 + depend/zcash/test/lint/lint-shell.sh | 47 + depend/zcash/test/lint/lint-whitespace.sh | 113 + depend/zcash/zcutil/afl/afl-build.sh | 105 + depend/zcash/zcutil/afl/afl-get.sh | 81 + depend/zcash/zcutil/afl/afl-getbuildrun.sh | 69 + depend/zcash/zcutil/afl/afl-run.sh | 62 + depend/zcash/zcutil/afl/zcash-wrapper | 59 + depend/zcash/zcutil/afl/zcash-wrapper-clang | 1 + depend/zcash/zcutil/afl/zcash-wrapper-clang++ | 1 + depend/zcash/zcutil/afl/zcash-wrapper-g++ | 1 + depend/zcash/zcutil/afl/zcash-wrapper-gcc | 1 + depend/zcash/zcutil/build-debian-package.sh | 78 + depend/zcash/zcutil/build.sh | 90 + depend/zcash/zcutil/clean.sh | 110 + depend/zcash/zcutil/cleanup-tags.sh | 27 + depend/zcash/zcutil/distclean.sh | 17 + depend/zcash/zcutil/fetch-params.sh | 237 + .../zcash/zcutil/libfuzzer/libfuzzer-build.sh | 152 + depend/zcash/zcutil/libfuzzer/zcash-wrapper | 123 + .../zcutil/libfuzzer/zcash-wrapper-clang | 1 + .../zcutil/libfuzzer/zcash-wrapper-clang++ | 1 + depend/zcash/zcutil/make-release.py | 740 ++ depend/zcash/zcutil/release-notes.py | 158 + src/lib.rs | 2 +- 1490 files changed, 298363 insertions(+), 38 deletions(-) delete mode 100644 .gitmodules delete mode 160000 depend/zcash create mode 100644 depend/zcash/.cargo/config.offline create mode 100644 depend/zcash/.gitattributes create mode 100644 depend/zcash/.github/ISSUE_TEMPLATE/bug-report.md create mode 100644 depend/zcash/.github/ISSUE_TEMPLATE/feature-request.md create mode 100644 depend/zcash/.github/ISSUE_TEMPLATE/ux-report.md create mode 100644 depend/zcash/.github/dependabot.yml create mode 100644 depend/zcash/.github/pull_request_template.md create mode 100644 depend/zcash/.github/workflows/book.yml create mode 100644 depend/zcash/.github/workflows/lints.yml create mode 100644 depend/zcash/.gitignore create mode 100644 depend/zcash/CONTRIBUTING.md create mode 100644 depend/zcash/COPYING create mode 100644 depend/zcash/Cargo.lock create mode 100644 depend/zcash/INSTALL create mode 100644 depend/zcash/Makefile.am create mode 100644 depend/zcash/README.md create mode 100644 depend/zcash/SECURITY.md create mode 100755 depend/zcash/autogen.sh create mode 100644 depend/zcash/build-aux/m4/ax_boost_base.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_chrono.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_filesystem.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_program_options.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_system.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_thread.m4 create mode 100644 depend/zcash/build-aux/m4/ax_boost_unit_test_framework.m4 create mode 100644 depend/zcash/build-aux/m4/ax_check_compile_flag.m4 create mode 100644 depend/zcash/build-aux/m4/ax_check_link_flag.m4 create mode 100644 depend/zcash/build-aux/m4/ax_check_preproc_flag.m4 create mode 100644 depend/zcash/build-aux/m4/ax_cxx_compile_stdcxx.m4 create mode 100644 depend/zcash/build-aux/m4/ax_gcc_func_attribute.m4 create mode 100644 depend/zcash/build-aux/m4/ax_pthread.m4 create mode 100644 depend/zcash/build-aux/m4/bitcoin_find_bdb.m4 create mode 100644 depend/zcash/build-aux/m4/bitcoin_subdir_to_include.m4 create mode 100644 depend/zcash/build-aux/m4/l_atomic.m4 create mode 100644 depend/zcash/code_of_conduct.md create mode 100644 depend/zcash/configure.ac create mode 100644 depend/zcash/contrib/README.md create mode 100644 depend/zcash/contrib/bitrpc/README.md create mode 100644 depend/zcash/contrib/bitrpc/bitrpc.py create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.apt create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.arch create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.centos8 create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build-python.apt create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.apt create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.arch create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.centos8 create mode 100644 depend/zcash/contrib/ci-builders/buildbot/Dockerfile-gitian.apt create mode 100644 depend/zcash/contrib/ci-builders/buildbot/README.md create mode 100644 depend/zcash/contrib/ci-builders/buildbot/apt-package-list.txt create mode 100644 depend/zcash/contrib/ci-builders/buildbot/bbworker-buildbot.tac create mode 100644 depend/zcash/contrib/ci-builders/buildbot/bbworker-requirements.txt create mode 100755 depend/zcash/contrib/ci-builders/buildbot/docker-build.sh create mode 100644 depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.apt create mode 100644 depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.arch create mode 100644 depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.centos8 create mode 100644 depend/zcash/contrib/ci-builders/tekton/Dockerfile-tekton-worker create mode 100644 depend/zcash/contrib/ci-builders/tekton/README.md create mode 100644 depend/zcash/contrib/ci-builders/tekton/apt-package-tekton-list.txt create mode 100755 depend/zcash/contrib/ci-builders/tekton/docker-build.sh create mode 100644 depend/zcash/contrib/ci-builders/tekton/requirements.txt create mode 100644 depend/zcash/contrib/ci-workers/README.md create mode 100644 depend/zcash/contrib/ci-workers/ansible.cfg create mode 100644 depend/zcash/contrib/ci-workers/files/bashrc create mode 100644 depend/zcash/contrib/ci-workers/grind.yml create mode 100644 depend/zcash/contrib/ci-workers/tasks/install-brew.yml create mode 100644 depend/zcash/contrib/ci-workers/tasks/install-pip.yml create mode 100644 depend/zcash/contrib/ci-workers/templates/buildbot-worker.plist.j2 create mode 100644 depend/zcash/contrib/ci-workers/templates/buildbot-worker.service.j2 create mode 100644 depend/zcash/contrib/ci-workers/templates/host.ec2.j2 create mode 100644 depend/zcash/contrib/ci-workers/templates/host.j2 create mode 100644 depend/zcash/contrib/ci-workers/unix.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/Archlinux.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/CentOS.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/Debian.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/Fedora.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/FreeBSD.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/MacOSX.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/Ubuntu.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/buildbot.yml create mode 100644 depend/zcash/contrib/ci-workers/vars/default.yml create mode 100644 depend/zcash/contrib/debian/changelog create mode 100644 depend/zcash/contrib/debian/compat create mode 100644 depend/zcash/contrib/debian/control create mode 100644 depend/zcash/contrib/debian/copyright create mode 100644 depend/zcash/contrib/debian/examples/zcash.conf create mode 100755 depend/zcash/contrib/debian/postinst create mode 100755 depend/zcash/contrib/debian/postrm create mode 100755 depend/zcash/contrib/debian/preinst create mode 100755 depend/zcash/contrib/debian/prerm create mode 100755 depend/zcash/contrib/debian/rules create mode 100644 depend/zcash/contrib/debian/zcash.examples create mode 100644 depend/zcash/contrib/debian/zcash.install create mode 100644 depend/zcash/contrib/debian/zcash.manpages create mode 100644 depend/zcash/contrib/devtools/README.md create mode 100755 depend/zcash/contrib/devtools/fix-copyright-headers.py create mode 100755 depend/zcash/contrib/devtools/gen-manpages.sh create mode 100755 depend/zcash/contrib/devtools/github-merge.sh create mode 100755 depend/zcash/contrib/devtools/optimize-pngs.py create mode 100755 depend/zcash/contrib/devtools/rust-deps-graph.sh create mode 100755 depend/zcash/contrib/devtools/security-check.py create mode 100755 depend/zcash/contrib/devtools/split-debug.sh create mode 100755 depend/zcash/contrib/devtools/symbol-check.py create mode 100755 depend/zcash/contrib/devtools/test-security-check.py create mode 100755 depend/zcash/contrib/devtools/update-rust-hashes.sh create mode 100644 depend/zcash/contrib/docker/.dockerignore create mode 100644 depend/zcash/contrib/docker/.env.example create mode 100644 depend/zcash/contrib/docker/.gitignore create mode 100644 depend/zcash/contrib/docker/Dockerfile create mode 100644 depend/zcash/contrib/docker/README.md create mode 100644 depend/zcash/contrib/docker/docker-compose.yml create mode 100755 depend/zcash/contrib/docker/entrypoint.sh create mode 100644 depend/zcash/contrib/gitian-descriptors/README.md create mode 100644 depend/zcash/contrib/gitian-descriptors/gitian-linux.yml create mode 100644 depend/zcash/contrib/gitian-descriptors/gitian-osx-signer.yml create mode 100644 depend/zcash/contrib/gitian-descriptors/gitian-osx.yml create mode 100644 depend/zcash/contrib/gitian-descriptors/gitian-win-signer.yml create mode 100644 depend/zcash/contrib/gitian-descriptors/gitian-win.yml create mode 100644 depend/zcash/contrib/gitian-downloader/daira.asc create mode 100644 depend/zcash/contrib/gitian-downloader/jack.asc create mode 100644 depend/zcash/contrib/gitian-downloader/kevin.asc create mode 100644 depend/zcash/contrib/gitian-downloader/nathan.asc create mode 100644 depend/zcash/contrib/gitian-downloader/sean.asc create mode 100644 depend/zcash/contrib/gitian-downloader/simon.asc create mode 100644 depend/zcash/contrib/linearize/README.md create mode 100644 depend/zcash/contrib/linearize/example-linearize.cfg create mode 100755 depend/zcash/contrib/linearize/linearize-data.py create mode 100755 depend/zcash/contrib/linearize/linearize-hashes.py create mode 100644 depend/zcash/contrib/macdeploy/README.md create mode 100755 depend/zcash/contrib/macdeploy/gen-sdk create mode 100644 depend/zcash/contrib/metrics/prometheus.yaml create mode 100644 depend/zcash/contrib/qos/README.md create mode 100644 depend/zcash/contrib/qos/tc.sh create mode 100644 depend/zcash/contrib/seeds/README.md create mode 100755 depend/zcash/contrib/seeds/generate-seeds.py create mode 100755 depend/zcash/contrib/seeds/makeseeds.py create mode 100755 depend/zcash/contrib/simulations/worstcase.py create mode 100644 depend/zcash/contrib/testgen/README.md create mode 100644 depend/zcash/contrib/testgen/base58.py create mode 100755 depend/zcash/contrib/testgen/gen_base58_test_vectors.py create mode 100755 depend/zcash/contrib/tidy_datadir.sh create mode 100644 depend/zcash/contrib/zcash-cli.bash-completion create mode 100644 depend/zcash/contrib/zcash-tx.bash-completion create mode 100644 depend/zcash/contrib/zcashd.bash-completion create mode 100755 depend/zcash/contrib/zmq/zmq_sub.py create mode 100644 depend/zcash/depends/.gitignore create mode 100644 depend/zcash/depends/Makefile create mode 100644 depend/zcash/depends/README.md create mode 100644 depend/zcash/depends/builders/darwin.mk create mode 100644 depend/zcash/depends/builders/default.mk create mode 100644 depend/zcash/depends/builders/freebsd.mk create mode 100644 depend/zcash/depends/builders/linux.mk create mode 100755 depend/zcash/depends/config.guess create mode 100644 depend/zcash/depends/config.site.in create mode 100755 depend/zcash/depends/config.sub create mode 100644 depend/zcash/depends/description.md create mode 100644 depend/zcash/depends/funcs.mk create mode 100644 depend/zcash/depends/hosts/darwin.mk create mode 100644 depend/zcash/depends/hosts/default.mk create mode 100644 depend/zcash/depends/hosts/freebsd.mk create mode 100644 depend/zcash/depends/hosts/linux.mk create mode 100644 depend/zcash/depends/hosts/mingw32.mk create mode 100644 depend/zcash/depends/packages.md create mode 100644 depend/zcash/depends/packages/bdb.mk create mode 100644 depend/zcash/depends/packages/boost.mk create mode 100644 depend/zcash/depends/packages/googletest.mk create mode 100644 depend/zcash/depends/packages/libcxx.mk create mode 100644 depend/zcash/depends/packages/libevent.mk create mode 100644 depend/zcash/depends/packages/libsodium.mk create mode 100644 depend/zcash/depends/packages/native_b2.mk create mode 100644 depend/zcash/depends/packages/native_ccache.mk create mode 100644 depend/zcash/depends/packages/native_cctools.mk create mode 100644 depend/zcash/depends/packages/native_clang.mk create mode 100644 depend/zcash/depends/packages/native_libtinfo.mk create mode 100644 depend/zcash/depends/packages/native_rust.mk create mode 100644 depend/zcash/depends/packages/packages.mk create mode 100644 depend/zcash/depends/packages/utfcpp.mk create mode 100644 depend/zcash/depends/packages/zeromq.mk create mode 100644 depend/zcash/depends/patches/bdb/clang-12-stpcpy-issue.diff create mode 100644 depend/zcash/depends/patches/bdb/winioctl-and-atomic_init_db.patch create mode 100644 depend/zcash/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch create mode 100644 depend/zcash/depends/patches/libsodium/1.0.15-pubkey-validation.diff create mode 100644 depend/zcash/depends/patches/libsodium/1.0.15-signature-validation.diff create mode 100644 depend/zcash/depends/patches/native_cctools/ignore-otool.diff create mode 100644 depend/zcash/depends/patches/zeromq/windows-unused-variables.diff create mode 100644 depend/zcash/doc/Doxyfile create mode 100644 depend/zcash/doc/authors.md create mode 100644 depend/zcash/doc/bips.md create mode 100644 depend/zcash/doc/book/.gitignore create mode 100644 depend/zcash/doc/book/book.toml create mode 100644 depend/zcash/doc/book/src/README.md create mode 100644 depend/zcash/doc/book/src/SUMMARY.md create mode 100644 depend/zcash/doc/book/src/design.md create mode 100644 depend/zcash/doc/book/src/design/chain-state.md create mode 100644 depend/zcash/doc/book/src/design/coins-view.md create mode 100644 depend/zcash/doc/book/src/design/p2p-data-propagation.md create mode 100644 depend/zcash/doc/book/src/dev.md create mode 100644 depend/zcash/doc/book/src/dev/deprecation.md create mode 100644 depend/zcash/doc/book/src/dev/regtest.md create mode 100644 depend/zcash/doc/book/src/dev/rust.md create mode 120000 depend/zcash/doc/book/src/doc/imgs/logo.png create mode 120000 depend/zcash/doc/book/src/doc/imgs/zcashd_screen.gif create mode 100644 depend/zcash/doc/book/src/user.md create mode 100644 depend/zcash/doc/book/src/user/deprecation.md create mode 100644 depend/zcash/doc/book/src/user/metrics.md create mode 100644 depend/zcash/doc/developer-notes.md create mode 100644 depend/zcash/doc/dnsseed-policy.md create mode 100644 depend/zcash/doc/files.md create mode 100644 depend/zcash/doc/hotfix-process.md create mode 100644 depend/zcash/doc/imgs/logo.png create mode 100644 depend/zcash/doc/imgs/zcashd_screen.gif create mode 100644 depend/zcash/doc/imgs/zcashd_screenshot.png create mode 100644 depend/zcash/doc/man/Makefile.am create mode 100644 depend/zcash/doc/man/zcash-cli.1 create mode 100644 depend/zcash/doc/man/zcash-fetch-params.1 create mode 100644 depend/zcash/doc/man/zcash-tx.1 create mode 100644 depend/zcash/doc/man/zcashd-wallet-tool.1 create mode 100644 depend/zcash/doc/man/zcashd.1 create mode 100644 depend/zcash/doc/payment-api.md create mode 100644 depend/zcash/doc/payment-disclosure.md create mode 100644 depend/zcash/doc/reduce-traffic.md create mode 100644 depend/zcash/doc/reducing-memory-usage.md create mode 100644 depend/zcash/doc/release-notes.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z4.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z5.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z6.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z7.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z8.md create mode 100644 depend/zcash/doc/release-notes/release-notes-0.11.2.z9.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-beta1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-beta2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-rc2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-rc3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0-rc4.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.10-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.10.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.11-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.11.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.12-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.12.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.13-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.13-rc2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.13.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.14-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.14.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.15-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.15.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.4.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.5.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.6.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.7-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.7.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.8-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.8.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.0.9.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.1-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.1-rc2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.2-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-1.1.2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.1-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.2-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.3-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.4-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.4.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.5-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.5-2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.5-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.5.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.6-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.6.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.7-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.7-2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.7-3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.7-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.0.7.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.0-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.1-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.1-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.1-rc2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.2-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.2-2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.2-3.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.2-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-2.1.2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-3.0.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-3.0.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-3.1.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-3.1.0-rc2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-3.1.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.0.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.0.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.1.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.1.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.1.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.2.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.2.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.3.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.3.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.4.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.4.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.4.1-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.4.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.5.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.5.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.5.1-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.5.1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.6.0-1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.6.0-2.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.6.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.6.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.7.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-4.7.0.md create mode 100644 depend/zcash/doc/release-notes/release-notes-5.0.0-rc1.md create mode 100644 depend/zcash/doc/release-notes/release-notes-5.0.0.md create mode 100644 depend/zcash/doc/release-process.md create mode 100644 depend/zcash/doc/security-warnings.md create mode 100644 depend/zcash/doc/shield-coinbase.md create mode 100644 depend/zcash/doc/tor.md create mode 100644 depend/zcash/doc/translation_strings_policy.md create mode 100644 depend/zcash/doc/unit-tests.md create mode 100644 depend/zcash/doc/wallet-backup.md create mode 100644 depend/zcash/doc/zmq.md create mode 100644 depend/zcash/libzcash_script.pc.in create mode 100644 depend/zcash/qa/README.md create mode 100755 depend/zcash/qa/pull-tester/rpc-tests.py create mode 100644 depend/zcash/qa/pull-tester/tests_config.ini.in create mode 100644 depend/zcash/qa/rpc-tests/.gitignore create mode 100644 depend/zcash/qa/rpc-tests/README.md create mode 100755 depend/zcash/qa/rpc-tests/addressindex.py create mode 100755 depend/zcash/qa/rpc-tests/bip65-cltv-p2p.py create mode 100755 depend/zcash/qa/rpc-tests/bipdersig-p2p.py create mode 100755 depend/zcash/qa/rpc-tests/blockchain.py create mode 100755 depend/zcash/qa/rpc-tests/coinbase_funding_streams.py create mode 100755 depend/zcash/qa/rpc-tests/create_cache.py create mode 100755 depend/zcash/qa/rpc-tests/decodescript.py create mode 100755 depend/zcash/qa/rpc-tests/disablewallet.py create mode 100755 depend/zcash/qa/rpc-tests/feature_logging.py create mode 100755 depend/zcash/qa/rpc-tests/feature_walletfile.py create mode 100755 depend/zcash/qa/rpc-tests/feature_zip221.py create mode 100755 depend/zcash/qa/rpc-tests/feature_zip239.py create mode 100755 depend/zcash/qa/rpc-tests/feature_zip244_blockcommitments.py create mode 100755 depend/zcash/qa/rpc-tests/finalsaplingroot.py create mode 100755 depend/zcash/qa/rpc-tests/forknotify.py create mode 100755 depend/zcash/qa/rpc-tests/framework.py create mode 100755 depend/zcash/qa/rpc-tests/fundrawtransaction.py create mode 100755 depend/zcash/qa/rpc-tests/getblocktemplate.py create mode 100755 depend/zcash/qa/rpc-tests/getblocktemplate_longpoll.py create mode 100755 depend/zcash/qa/rpc-tests/getblocktemplate_proposals.py create mode 100755 depend/zcash/qa/rpc-tests/getchaintips.py create mode 100755 depend/zcash/qa/rpc-tests/getmininginfo.py create mode 100755 depend/zcash/qa/rpc-tests/getrawtransaction_insight.py create mode 100644 depend/zcash/qa/rpc-tests/golden/blossom.tar.gz create mode 100644 depend/zcash/qa/rpc-tests/golden/heartwood.tar.gz create mode 100755 depend/zcash/qa/rpc-tests/hardforkdetection.py create mode 100755 depend/zcash/qa/rpc-tests/httpbasics.py create mode 100755 depend/zcash/qa/rpc-tests/invalidateblock.py create mode 100755 depend/zcash/qa/rpc-tests/invalidblockrequest.py create mode 100755 depend/zcash/qa/rpc-tests/invalidtxrequest.py create mode 100755 depend/zcash/qa/rpc-tests/key_import_export.py create mode 100755 depend/zcash/qa/rpc-tests/keypool.py create mode 100755 depend/zcash/qa/rpc-tests/listtransactions.py create mode 100755 depend/zcash/qa/rpc-tests/maxblocksinflight.py create mode 100755 depend/zcash/qa/rpc-tests/maxuploadtarget.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_limit.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_nu_activation.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_reorg.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_resurrect_test.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_spendcoinbase.py create mode 100755 depend/zcash/qa/rpc-tests/mempool_tx_expiry.py create mode 100755 depend/zcash/qa/rpc-tests/mergetoaddress_helper.py create mode 100755 depend/zcash/qa/rpc-tests/mergetoaddress_mixednotes.py create mode 100755 depend/zcash/qa/rpc-tests/mergetoaddress_sapling.py create mode 100755 depend/zcash/qa/rpc-tests/mergetoaddress_sprout.py create mode 100755 depend/zcash/qa/rpc-tests/merkle_blocks.py create mode 100755 depend/zcash/qa/rpc-tests/mining_shielded_coinbase.py create mode 100755 depend/zcash/qa/rpc-tests/multi_rpc.py create mode 100755 depend/zcash/qa/rpc-tests/nodehandling.py create mode 100755 depend/zcash/qa/rpc-tests/nuparams.py create mode 100755 depend/zcash/qa/rpc-tests/orchard_reorg.py create mode 100755 depend/zcash/qa/rpc-tests/p2p-acceptblock.py create mode 100755 depend/zcash/qa/rpc-tests/p2p-fullblocktest.py create mode 100755 depend/zcash/qa/rpc-tests/p2p_node_bloom.py create mode 100755 depend/zcash/qa/rpc-tests/p2p_nu_peer_management.py create mode 100755 depend/zcash/qa/rpc-tests/p2p_txexpiringsoon.py create mode 100755 depend/zcash/qa/rpc-tests/p2p_txexpiry_dos.py create mode 100755 depend/zcash/qa/rpc-tests/post_heartwood_rollback.py create mode 100755 depend/zcash/qa/rpc-tests/prioritisetransaction.py create mode 100755 depend/zcash/qa/rpc-tests/proxy_test.py create mode 100755 depend/zcash/qa/rpc-tests/pruning.py create mode 100755 depend/zcash/qa/rpc-tests/rawtransactions.py create mode 100755 depend/zcash/qa/rpc-tests/receivedby.py create mode 100755 depend/zcash/qa/rpc-tests/regtest_signrawtransaction.py create mode 100755 depend/zcash/qa/rpc-tests/reindex.py create mode 100755 depend/zcash/qa/rpc-tests/remove_sprout_shielding.py create mode 100755 depend/zcash/qa/rpc-tests/reorg_limit.py create mode 100755 depend/zcash/qa/rpc-tests/rest.py create mode 100755 depend/zcash/qa/rpc-tests/rewind_index.py create mode 100755 depend/zcash/qa/rpc-tests/rpcbind_test.py create mode 100755 depend/zcash/qa/rpc-tests/sapling_rewind_check.py create mode 100755 depend/zcash/qa/rpc-tests/shorter_block_times.py create mode 100755 depend/zcash/qa/rpc-tests/signrawtransaction_offline.py create mode 100755 depend/zcash/qa/rpc-tests/signrawtransactions.py create mode 100755 depend/zcash/qa/rpc-tests/smartfees.py create mode 100755 depend/zcash/qa/rpc-tests/spentindex.py create mode 100755 depend/zcash/qa/rpc-tests/sprout_sapling_migration.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/__init__.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/authproxy.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/bignum.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/blockstore.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/blocktools.py create mode 100755 depend/zcash/qa/rpc-tests/test_framework/comptool.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/coverage.py create mode 100755 depend/zcash/qa/rpc-tests/test_framework/equihash.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/flyclient.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/key.py create mode 100755 depend/zcash/qa/rpc-tests/test_framework/mininode.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/netutil.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/script.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/socks5.py create mode 100755 depend/zcash/qa/rpc-tests/test_framework/test_framework.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/util.py create mode 100644 depend/zcash/qa/rpc-tests/test_framework/zip244.py create mode 100755 depend/zcash/qa/rpc-tests/threeofthreerestore.py create mode 100755 depend/zcash/qa/rpc-tests/timestampindex.py create mode 100755 depend/zcash/qa/rpc-tests/turnstile.py create mode 100755 depend/zcash/qa/rpc-tests/tx_expiry_helper.py create mode 100755 depend/zcash/qa/rpc-tests/txn_doublespend.py create mode 100755 depend/zcash/qa/rpc-tests/upgrade_golden.py create mode 100755 depend/zcash/qa/rpc-tests/wallet.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_1941.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_accounts.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_addresses.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_anchorfork.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_broadcast.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_changeaddresses.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_changeindicator.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_db_flush.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_deprecation.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_doublespend.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_import_export.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_isfromme.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_listnotes.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_listreceived.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_nullifiers.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_orchard.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_orchard_change.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_orchard_init.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_orchard_persistence.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_overwintertx.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_parsing_amounts.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_persistence.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_sapling.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_sendmany_any_taddr.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldcoinbase.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sapling.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sprout.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_nu5.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_sapling.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_shieldingcoinbase.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_treestate.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_unified_change.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_z_sendmany.py create mode 100755 depend/zcash/qa/rpc-tests/wallet_zero_value.py create mode 100755 depend/zcash/qa/rpc-tests/walletbackup.py create mode 100755 depend/zcash/qa/rpc-tests/zapwallettxes.py create mode 100755 depend/zcash/qa/rpc-tests/zcjoinsplit.py create mode 100755 depend/zcash/qa/rpc-tests/zcjoinsplitdoublespend.py create mode 100755 depend/zcash/qa/rpc-tests/zkey_import_export.py create mode 100755 depend/zcash/qa/rpc-tests/zmq_test.py create mode 100755 depend/zcash/qa/zcash/checksec.sh create mode 100644 depend/zcash/qa/zcash/create_benchmark_archive.py create mode 100755 depend/zcash/qa/zcash/create_wallet_200k_utxos.py create mode 100755 depend/zcash/qa/zcash/full_test_suite.py create mode 100755 depend/zcash/qa/zcash/performance-measurements.sh create mode 100644 depend/zcash/qa/zcash/postponed-updates.txt create mode 100755 depend/zcash/qa/zcash/smoke_tests.py create mode 100755 depend/zcash/qa/zcash/test-depends-sources-mirror.py create mode 100755 depend/zcash/qa/zcash/updatecheck.py create mode 100644 depend/zcash/rust-toolchain create mode 100755 depend/zcash/share/genbuild.sh create mode 100644 depend/zcash/share/rpcuser/README.md create mode 100755 depend/zcash/share/rpcuser/rpcuser.py create mode 100644 depend/zcash/src/.clang-format create mode 100644 depend/zcash/src/Makefile.am create mode 100644 depend/zcash/src/Makefile.bench.include create mode 100644 depend/zcash/src/Makefile.gtest.include create mode 100644 depend/zcash/src/Makefile.leveldb.include create mode 100644 depend/zcash/src/Makefile.test.include create mode 100644 depend/zcash/src/addrdb.cpp create mode 100644 depend/zcash/src/addrdb.h create mode 100644 depend/zcash/src/addressindex.h create mode 100644 depend/zcash/src/addrman.cpp create mode 100644 depend/zcash/src/addrman.h create mode 100644 depend/zcash/src/alert.cpp create mode 100644 depend/zcash/src/alert.h create mode 100644 depend/zcash/src/alertkeys.h create mode 100644 depend/zcash/src/amount.cpp create mode 100644 depend/zcash/src/amount.h create mode 100644 depend/zcash/src/arith_uint256.cpp create mode 100644 depend/zcash/src/arith_uint256.h create mode 100644 depend/zcash/src/asyncrpcoperation.cpp create mode 100644 depend/zcash/src/asyncrpcoperation.h create mode 100644 depend/zcash/src/asyncrpcqueue.cpp create mode 100644 depend/zcash/src/asyncrpcqueue.h create mode 100644 depend/zcash/src/base58.cpp create mode 100644 depend/zcash/src/base58.h create mode 100644 depend/zcash/src/bech32.cpp create mode 100644 depend/zcash/src/bech32.h create mode 100644 depend/zcash/src/bench/.gitignore create mode 100644 depend/zcash/src/bench/Examples.cpp create mode 100644 depend/zcash/src/bench/base58.cpp create mode 100644 depend/zcash/src/bench/bench.cpp create mode 100644 depend/zcash/src/bench/bench.h create mode 100644 depend/zcash/src/bench/bench_bitcoin.cpp create mode 100644 depend/zcash/src/bench/checkqueue.cpp create mode 100644 depend/zcash/src/bench/crypto_hash.cpp create mode 100644 depend/zcash/src/bench/lockedpool.cpp create mode 100644 depend/zcash/src/bench/perf.cpp create mode 100644 depend/zcash/src/bench/perf.h create mode 100644 depend/zcash/src/bench/prevector_destructor.cpp create mode 100644 depend/zcash/src/bench/rollingbloom.cpp create mode 100644 depend/zcash/src/bench/verification.cpp create mode 100644 depend/zcash/src/bitcoin-cli-res.rc create mode 100644 depend/zcash/src/bitcoin-cli.cpp create mode 100644 depend/zcash/src/bitcoin-tx-res.rc create mode 100644 depend/zcash/src/bitcoin-tx.cpp create mode 100644 depend/zcash/src/bitcoind-res.rc create mode 100644 depend/zcash/src/bitcoind.cpp create mode 100644 depend/zcash/src/bloom.cpp create mode 100644 depend/zcash/src/bloom.h create mode 100644 depend/zcash/src/chain.cpp create mode 100644 depend/zcash/src/chain.h create mode 100644 depend/zcash/src/chainparams.cpp create mode 100644 depend/zcash/src/chainparams.h create mode 100644 depend/zcash/src/chainparamsbase.cpp create mode 100644 depend/zcash/src/chainparamsbase.h create mode 100644 depend/zcash/src/chainparamsseeds.h create mode 100644 depend/zcash/src/checkpoints.cpp create mode 100644 depend/zcash/src/checkpoints.h create mode 100644 depend/zcash/src/checkqueue.h create mode 100644 depend/zcash/src/clientversion.cpp create mode 100644 depend/zcash/src/clientversion.h create mode 100644 depend/zcash/src/coincontrol.h create mode 100644 depend/zcash/src/coins.cpp create mode 100644 depend/zcash/src/coins.h create mode 100644 depend/zcash/src/compat.h create mode 100644 depend/zcash/src/compat/byteswap.h create mode 100644 depend/zcash/src/compat/endian.h create mode 100644 depend/zcash/src/compat/glibc_compat.cpp create mode 100644 depend/zcash/src/compat/glibc_sanity.cpp create mode 100644 depend/zcash/src/compat/glibcxx_sanity.cpp create mode 100644 depend/zcash/src/compat/sanity.h create mode 100644 depend/zcash/src/compat/strnlen.cpp create mode 100644 depend/zcash/src/compressor.cpp create mode 100644 depend/zcash/src/compressor.h create mode 100644 depend/zcash/src/config/.empty create mode 100644 depend/zcash/src/consensus/consensus.h create mode 100644 depend/zcash/src/consensus/funding.cpp create mode 100644 depend/zcash/src/consensus/funding.h create mode 100644 depend/zcash/src/consensus/params.cpp create mode 100644 depend/zcash/src/consensus/params.h create mode 100644 depend/zcash/src/consensus/upgrades.cpp create mode 100644 depend/zcash/src/consensus/upgrades.h create mode 100644 depend/zcash/src/consensus/validation.h create mode 100644 depend/zcash/src/core_io.h create mode 100644 depend/zcash/src/core_memusage.h create mode 100644 depend/zcash/src/core_read.cpp create mode 100644 depend/zcash/src/core_write.cpp create mode 100644 depend/zcash/src/crypto/aes.cpp create mode 100644 depend/zcash/src/crypto/aes.h create mode 100644 depend/zcash/src/crypto/chacha20.cpp create mode 100644 depend/zcash/src/crypto/chacha20.h create mode 100644 depend/zcash/src/crypto/common.h create mode 100644 depend/zcash/src/crypto/ctaes/COPYING create mode 100644 depend/zcash/src/crypto/ctaes/README.md create mode 100644 depend/zcash/src/crypto/ctaes/bench.c create mode 100644 depend/zcash/src/crypto/ctaes/ctaes.c create mode 100644 depend/zcash/src/crypto/ctaes/ctaes.h create mode 100644 depend/zcash/src/crypto/ctaes/test.c create mode 100644 depend/zcash/src/crypto/equihash.cpp create mode 100644 depend/zcash/src/crypto/equihash.h create mode 100644 depend/zcash/src/crypto/equihash.tcc create mode 100644 depend/zcash/src/crypto/hmac_sha256.cpp create mode 100644 depend/zcash/src/crypto/hmac_sha256.h create mode 100644 depend/zcash/src/crypto/hmac_sha512.cpp create mode 100644 depend/zcash/src/crypto/hmac_sha512.h create mode 100644 depend/zcash/src/crypto/ripemd160.cpp create mode 100644 depend/zcash/src/crypto/ripemd160.h create mode 100644 depend/zcash/src/crypto/sha1.cpp create mode 100644 depend/zcash/src/crypto/sha1.h create mode 100644 depend/zcash/src/crypto/sha256.cpp create mode 100644 depend/zcash/src/crypto/sha256.h create mode 100644 depend/zcash/src/crypto/sha512.cpp create mode 100644 depend/zcash/src/crypto/sha512.h create mode 100644 depend/zcash/src/dbwrapper.cpp create mode 100644 depend/zcash/src/dbwrapper.h create mode 100644 depend/zcash/src/deprecation.cpp create mode 100644 depend/zcash/src/deprecation.h create mode 100644 depend/zcash/src/experimental_features.cpp create mode 100644 depend/zcash/src/experimental_features.h create mode 100644 depend/zcash/src/fs.cpp create mode 100644 depend/zcash/src/fs.h create mode 100644 depend/zcash/src/fuzzing/CheckBlock/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/CheckBlock/input/0.bin create mode 100644 depend/zcash/src/fuzzing/CheckBlock/input/476431.bin create mode 100644 depend/zcash/src/fuzzing/CheckBlock/input/620000.bin create mode 100644 depend/zcash/src/fuzzing/DecodeHexTx/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/DecodeHexTx/input/coinbase.txt create mode 100644 depend/zcash/src/fuzzing/DecodeHexTx/input/manyoutputs.txt create mode 100644 depend/zcash/src/fuzzing/DecodeHexTx/input/sapling.txt create mode 100644 depend/zcash/src/fuzzing/DecodeHexTx/input/sprout.txt create mode 100644 depend/zcash/src/fuzzing/DeserializeAddrMan/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/DeserializeAddrMan/input/peers.dat-minus-4-byte-header create mode 100644 depend/zcash/src/fuzzing/DeserializeTx/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/DeserializeTx/input/coinbase.bin create mode 100644 depend/zcash/src/fuzzing/DeserializeTx/input/manyoutputs.bin create mode 100644 depend/zcash/src/fuzzing/DeserializeTx/input/sapling.bin create mode 100644 depend/zcash/src/fuzzing/DeserializeTx/input/sprout.bin create mode 100644 depend/zcash/src/fuzzing/ReadFeeEstimates/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/ReadFeeEstimates/input/fee_estimates.dat create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/dict create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/fuzz.cpp create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail1.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail10.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail11.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail12.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail13.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail14.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail15.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail16.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail17.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail18.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail19.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail2.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail20.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail21.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail22.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail23.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail24.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail25.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail26.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail27.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail28.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail29.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail3.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail30.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail31.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail32.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail33.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail34.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail35.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail36.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail37.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail38.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail39.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail4.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail40.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail41.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail42.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail5.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail6.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail7.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail8.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/fail9.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/pass1.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/pass2.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/pass3.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round1.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round2.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round3.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round4.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round5.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round6.json create mode 100644 depend/zcash/src/fuzzing/UniValue__Read/input/round7.json create mode 100644 depend/zcash/src/gtest/data/tx-orchard-duplicate-nullifiers.h create mode 100644 depend/zcash/src/gtest/json_test_vectors.cpp create mode 100644 depend/zcash/src/gtest/json_test_vectors.h create mode 100644 depend/zcash/src/gtest/main.cpp create mode 100644 depend/zcash/src/gtest/test_allocator.cpp create mode 100644 depend/zcash/src/gtest/test_block.cpp create mode 100644 depend/zcash/src/gtest/test_checkblock.cpp create mode 100644 depend/zcash/src/gtest/test_checktransaction.cpp create mode 100644 depend/zcash/src/gtest/test_coins.cpp create mode 100644 depend/zcash/src/gtest/test_consensus.cpp create mode 100644 depend/zcash/src/gtest/test_deprecation.cpp create mode 100644 depend/zcash/src/gtest/test_dynamicusage.cpp create mode 100644 depend/zcash/src/gtest/test_equihash.cpp create mode 100644 depend/zcash/src/gtest/test_feature_flagging.cpp create mode 100644 depend/zcash/src/gtest/test_foundersreward.cpp create mode 100644 depend/zcash/src/gtest/test_history.cpp create mode 100644 depend/zcash/src/gtest/test_httprpc.cpp create mode 100644 depend/zcash/src/gtest/test_joinsplit.cpp create mode 100644 depend/zcash/src/gtest/test_keys.cpp create mode 100644 depend/zcash/src/gtest/test_keystore.cpp create mode 100644 depend/zcash/src/gtest/test_libzcash_utils.cpp create mode 100644 depend/zcash/src/gtest/test_mempool.cpp create mode 100644 depend/zcash/src/gtest/test_mempoollimit.cpp create mode 100644 depend/zcash/src/gtest/test_merkletree.cpp create mode 100644 depend/zcash/src/gtest/test_metrics.cpp create mode 100644 depend/zcash/src/gtest/test_miner.cpp create mode 100644 depend/zcash/src/gtest/test_noteencryption.cpp create mode 100644 depend/zcash/src/gtest/test_pedersen_hash.cpp create mode 100644 depend/zcash/src/gtest/test_pow.cpp create mode 100644 depend/zcash/src/gtest/test_random.cpp create mode 100644 depend/zcash/src/gtest/test_rpc.cpp create mode 100644 depend/zcash/src/gtest/test_sapling_note.cpp create mode 100644 depend/zcash/src/gtest/test_sighash.cpp create mode 100644 depend/zcash/src/gtest/test_tautology.cpp create mode 100644 depend/zcash/src/gtest/test_timedata.cpp create mode 100644 depend/zcash/src/gtest/test_transaction.cpp create mode 100644 depend/zcash/src/gtest/test_transaction_builder.cpp create mode 100644 depend/zcash/src/gtest/test_transaction_builder.h create mode 100644 depend/zcash/src/gtest/test_txid.cpp create mode 100644 depend/zcash/src/gtest/test_upgrades.cpp create mode 100644 depend/zcash/src/gtest/test_validation.cpp create mode 100644 depend/zcash/src/gtest/test_zip32.cpp create mode 100644 depend/zcash/src/gtest/utils.cpp create mode 100644 depend/zcash/src/gtest/utils.h create mode 100644 depend/zcash/src/hash.cpp create mode 100644 depend/zcash/src/hash.h create mode 100644 depend/zcash/src/httprpc.cpp create mode 100644 depend/zcash/src/httprpc.h create mode 100644 depend/zcash/src/httpserver.cpp create mode 100644 depend/zcash/src/httpserver.h create mode 100644 depend/zcash/src/init.cpp create mode 100644 depend/zcash/src/init.h create mode 100644 depend/zcash/src/key.cpp create mode 100644 depend/zcash/src/key.h create mode 100644 depend/zcash/src/key_constants.h create mode 100644 depend/zcash/src/key_io.cpp create mode 100644 depend/zcash/src/key_io.h create mode 100644 depend/zcash/src/keystore.cpp create mode 100644 depend/zcash/src/keystore.h create mode 100644 depend/zcash/src/leveldb/.gitignore create mode 100644 depend/zcash/src/leveldb/.travis.yml create mode 100644 depend/zcash/src/leveldb/AUTHORS create mode 100644 depend/zcash/src/leveldb/CONTRIBUTING.md create mode 100644 depend/zcash/src/leveldb/LICENSE create mode 100644 depend/zcash/src/leveldb/Makefile create mode 100644 depend/zcash/src/leveldb/NEWS create mode 100644 depend/zcash/src/leveldb/README.md create mode 100644 depend/zcash/src/leveldb/TODO create mode 100644 depend/zcash/src/leveldb/WINDOWS.md create mode 100755 depend/zcash/src/leveldb/build_detect_platform create mode 100644 depend/zcash/src/leveldb/db/autocompact_test.cc create mode 100644 depend/zcash/src/leveldb/db/builder.cc create mode 100644 depend/zcash/src/leveldb/db/builder.h create mode 100644 depend/zcash/src/leveldb/db/c.cc create mode 100644 depend/zcash/src/leveldb/db/c_test.c create mode 100644 depend/zcash/src/leveldb/db/corruption_test.cc create mode 100644 depend/zcash/src/leveldb/db/db_bench.cc create mode 100644 depend/zcash/src/leveldb/db/db_impl.cc create mode 100644 depend/zcash/src/leveldb/db/db_impl.h create mode 100644 depend/zcash/src/leveldb/db/db_iter.cc create mode 100644 depend/zcash/src/leveldb/db/db_iter.h create mode 100644 depend/zcash/src/leveldb/db/db_test.cc create mode 100644 depend/zcash/src/leveldb/db/dbformat.cc create mode 100644 depend/zcash/src/leveldb/db/dbformat.h create mode 100644 depend/zcash/src/leveldb/db/dbformat_test.cc create mode 100644 depend/zcash/src/leveldb/db/dumpfile.cc create mode 100644 depend/zcash/src/leveldb/db/fault_injection_test.cc create mode 100644 depend/zcash/src/leveldb/db/filename.cc create mode 100644 depend/zcash/src/leveldb/db/filename.h create mode 100644 depend/zcash/src/leveldb/db/filename_test.cc create mode 100644 depend/zcash/src/leveldb/db/leveldbutil.cc create mode 100644 depend/zcash/src/leveldb/db/log_format.h create mode 100644 depend/zcash/src/leveldb/db/log_reader.cc create mode 100644 depend/zcash/src/leveldb/db/log_reader.h create mode 100644 depend/zcash/src/leveldb/db/log_test.cc create mode 100644 depend/zcash/src/leveldb/db/log_writer.cc create mode 100644 depend/zcash/src/leveldb/db/log_writer.h create mode 100644 depend/zcash/src/leveldb/db/memtable.cc create mode 100644 depend/zcash/src/leveldb/db/memtable.h create mode 100644 depend/zcash/src/leveldb/db/recovery_test.cc create mode 100644 depend/zcash/src/leveldb/db/repair.cc create mode 100644 depend/zcash/src/leveldb/db/skiplist.h create mode 100644 depend/zcash/src/leveldb/db/skiplist_test.cc create mode 100644 depend/zcash/src/leveldb/db/snapshot.h create mode 100644 depend/zcash/src/leveldb/db/table_cache.cc create mode 100644 depend/zcash/src/leveldb/db/table_cache.h create mode 100644 depend/zcash/src/leveldb/db/version_edit.cc create mode 100644 depend/zcash/src/leveldb/db/version_edit.h create mode 100644 depend/zcash/src/leveldb/db/version_edit_test.cc create mode 100644 depend/zcash/src/leveldb/db/version_set.cc create mode 100644 depend/zcash/src/leveldb/db/version_set.h create mode 100644 depend/zcash/src/leveldb/db/version_set_test.cc create mode 100644 depend/zcash/src/leveldb/db/write_batch.cc create mode 100644 depend/zcash/src/leveldb/db/write_batch_internal.h create mode 100644 depend/zcash/src/leveldb/db/write_batch_test.cc create mode 100644 depend/zcash/src/leveldb/doc/bench/db_bench_sqlite3.cc create mode 100644 depend/zcash/src/leveldb/doc/bench/db_bench_tree_db.cc create mode 100644 depend/zcash/src/leveldb/doc/benchmark.html create mode 100644 depend/zcash/src/leveldb/doc/impl.md create mode 100644 depend/zcash/src/leveldb/doc/index.md create mode 100644 depend/zcash/src/leveldb/doc/log_format.md create mode 100644 depend/zcash/src/leveldb/doc/table_format.md create mode 100644 depend/zcash/src/leveldb/helpers/memenv/memenv.cc create mode 100644 depend/zcash/src/leveldb/helpers/memenv/memenv.h create mode 100644 depend/zcash/src/leveldb/helpers/memenv/memenv_test.cc create mode 100644 depend/zcash/src/leveldb/include/leveldb/c.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/cache.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/comparator.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/db.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/dumpfile.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/env.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/filter_policy.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/iterator.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/options.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/slice.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/status.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/table.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/table_builder.h create mode 100644 depend/zcash/src/leveldb/include/leveldb/write_batch.h create mode 100644 depend/zcash/src/leveldb/issues/issue178_test.cc create mode 100644 depend/zcash/src/leveldb/issues/issue200_test.cc create mode 100644 depend/zcash/src/leveldb/port/README create mode 100644 depend/zcash/src/leveldb/port/atomic_pointer.h create mode 100644 depend/zcash/src/leveldb/port/port.h create mode 100644 depend/zcash/src/leveldb/port/port_example.h create mode 100644 depend/zcash/src/leveldb/port/port_posix.cc create mode 100644 depend/zcash/src/leveldb/port/port_posix.h create mode 100644 depend/zcash/src/leveldb/port/port_posix_sse.cc create mode 100644 depend/zcash/src/leveldb/port/port_win.cc create mode 100644 depend/zcash/src/leveldb/port/port_win.h create mode 100644 depend/zcash/src/leveldb/port/thread_annotations.h create mode 100644 depend/zcash/src/leveldb/port/win/stdint.h create mode 100644 depend/zcash/src/leveldb/table/block.cc create mode 100644 depend/zcash/src/leveldb/table/block.h create mode 100644 depend/zcash/src/leveldb/table/block_builder.cc create mode 100644 depend/zcash/src/leveldb/table/block_builder.h create mode 100644 depend/zcash/src/leveldb/table/filter_block.cc create mode 100644 depend/zcash/src/leveldb/table/filter_block.h create mode 100644 depend/zcash/src/leveldb/table/filter_block_test.cc create mode 100644 depend/zcash/src/leveldb/table/format.cc create mode 100644 depend/zcash/src/leveldb/table/format.h create mode 100644 depend/zcash/src/leveldb/table/iterator.cc create mode 100644 depend/zcash/src/leveldb/table/iterator_wrapper.h create mode 100644 depend/zcash/src/leveldb/table/merger.cc create mode 100644 depend/zcash/src/leveldb/table/merger.h create mode 100644 depend/zcash/src/leveldb/table/table.cc create mode 100644 depend/zcash/src/leveldb/table/table_builder.cc create mode 100644 depend/zcash/src/leveldb/table/table_test.cc create mode 100644 depend/zcash/src/leveldb/table/two_level_iterator.cc create mode 100644 depend/zcash/src/leveldb/table/two_level_iterator.h create mode 100644 depend/zcash/src/leveldb/util/arena.cc create mode 100644 depend/zcash/src/leveldb/util/arena.h create mode 100644 depend/zcash/src/leveldb/util/arena_test.cc create mode 100644 depend/zcash/src/leveldb/util/bloom.cc create mode 100644 depend/zcash/src/leveldb/util/bloom_test.cc create mode 100644 depend/zcash/src/leveldb/util/cache.cc create mode 100644 depend/zcash/src/leveldb/util/cache_test.cc create mode 100644 depend/zcash/src/leveldb/util/coding.cc create mode 100644 depend/zcash/src/leveldb/util/coding.h create mode 100644 depend/zcash/src/leveldb/util/coding_test.cc create mode 100644 depend/zcash/src/leveldb/util/comparator.cc create mode 100644 depend/zcash/src/leveldb/util/crc32c.cc create mode 100644 depend/zcash/src/leveldb/util/crc32c.h create mode 100644 depend/zcash/src/leveldb/util/crc32c_test.cc create mode 100644 depend/zcash/src/leveldb/util/env.cc create mode 100644 depend/zcash/src/leveldb/util/env_posix.cc create mode 100644 depend/zcash/src/leveldb/util/env_posix_test.cc create mode 100644 depend/zcash/src/leveldb/util/env_posix_test_helper.h create mode 100644 depend/zcash/src/leveldb/util/env_test.cc create mode 100644 depend/zcash/src/leveldb/util/env_win.cc create mode 100644 depend/zcash/src/leveldb/util/filter_policy.cc create mode 100644 depend/zcash/src/leveldb/util/hash.cc create mode 100644 depend/zcash/src/leveldb/util/hash.h create mode 100644 depend/zcash/src/leveldb/util/hash_test.cc create mode 100644 depend/zcash/src/leveldb/util/histogram.cc create mode 100644 depend/zcash/src/leveldb/util/histogram.h create mode 100644 depend/zcash/src/leveldb/util/logging.cc create mode 100644 depend/zcash/src/leveldb/util/logging.h create mode 100644 depend/zcash/src/leveldb/util/mutexlock.h create mode 100644 depend/zcash/src/leveldb/util/options.cc create mode 100644 depend/zcash/src/leveldb/util/posix_logger.h create mode 100644 depend/zcash/src/leveldb/util/random.h create mode 100644 depend/zcash/src/leveldb/util/status.cc create mode 100644 depend/zcash/src/leveldb/util/testharness.cc create mode 100644 depend/zcash/src/leveldb/util/testharness.h create mode 100644 depend/zcash/src/leveldb/util/testutil.cc create mode 100644 depend/zcash/src/leveldb/util/testutil.h create mode 100644 depend/zcash/src/limitedmap.h create mode 100644 depend/zcash/src/logging.cpp create mode 100644 depend/zcash/src/logging.h create mode 100644 depend/zcash/src/main.cpp create mode 100644 depend/zcash/src/main.h create mode 100644 depend/zcash/src/mempool_limit.cpp create mode 100644 depend/zcash/src/mempool_limit.h create mode 100644 depend/zcash/src/memusage.h create mode 100644 depend/zcash/src/merkleblock.cpp create mode 100644 depend/zcash/src/merkleblock.h create mode 100644 depend/zcash/src/metrics.cpp create mode 100644 depend/zcash/src/metrics.h create mode 100644 depend/zcash/src/miner.cpp create mode 100644 depend/zcash/src/miner.h create mode 100644 depend/zcash/src/net.cpp create mode 100644 depend/zcash/src/net.h create mode 100644 depend/zcash/src/netbase.cpp create mode 100644 depend/zcash/src/netbase.h create mode 100644 depend/zcash/src/noui.cpp create mode 100644 depend/zcash/src/noui.h create mode 100644 depend/zcash/src/obj/.gitignore create mode 100644 depend/zcash/src/policy/fees.cpp create mode 100644 depend/zcash/src/policy/fees.h create mode 100644 depend/zcash/src/policy/policy.cpp create mode 100644 depend/zcash/src/policy/policy.h create mode 100644 depend/zcash/src/pow.cpp create mode 100644 depend/zcash/src/pow.h create mode 100644 depend/zcash/src/pow/tromp/equi.h create mode 100644 depend/zcash/src/pow/tromp/equi_miner.h create mode 100644 depend/zcash/src/pow/tromp/osx_barrier.h create mode 100644 depend/zcash/src/prevector.h create mode 100644 depend/zcash/src/primitives/block.cpp create mode 100644 depend/zcash/src/primitives/block.h create mode 100644 depend/zcash/src/primitives/orchard.h create mode 100644 depend/zcash/src/primitives/transaction.cpp create mode 100644 depend/zcash/src/primitives/transaction.h create mode 100644 depend/zcash/src/primitives/tx_version_info.cpp create mode 100644 depend/zcash/src/proof_verifier.cpp create mode 100644 depend/zcash/src/proof_verifier.h create mode 100644 depend/zcash/src/protocol.cpp create mode 100644 depend/zcash/src/protocol.h create mode 100644 depend/zcash/src/pubkey.cpp create mode 100644 depend/zcash/src/pubkey.h create mode 100644 depend/zcash/src/random.cpp create mode 100644 depend/zcash/src/random.h create mode 100644 depend/zcash/src/rest.cpp create mode 100644 depend/zcash/src/reverse_iterator.h create mode 100644 depend/zcash/src/reverselock.h create mode 100644 depend/zcash/src/rpc/blockchain.cpp create mode 100644 depend/zcash/src/rpc/client.cpp create mode 100644 depend/zcash/src/rpc/client.h create mode 100644 depend/zcash/src/rpc/mining.cpp create mode 100644 depend/zcash/src/rpc/misc.cpp create mode 100644 depend/zcash/src/rpc/net.cpp create mode 100644 depend/zcash/src/rpc/protocol.cpp create mode 100644 depend/zcash/src/rpc/protocol.h create mode 100644 depend/zcash/src/rpc/rawtransaction.cpp create mode 100644 depend/zcash/src/rpc/register.h create mode 100644 depend/zcash/src/rpc/server.cpp create mode 100644 depend/zcash/src/rpc/server.h create mode 100644 depend/zcash/src/rust/README.md create mode 100644 depend/zcash/src/rust/bin/wallet_tool.rs create mode 100644 depend/zcash/src/rust/include/librustzcash.h create mode 100644 depend/zcash/src/rust/include/rust/VA_OPT.hpp create mode 100644 depend/zcash/src/rust/include/rust/address.h create mode 100644 depend/zcash/src/rust/include/rust/blake2b.h create mode 100644 depend/zcash/src/rust/include/rust/builder.h create mode 100644 depend/zcash/src/rust/include/rust/ed25519.h create mode 100644 depend/zcash/src/rust/include/rust/ed25519/types.h create mode 100644 depend/zcash/src/rust/include/rust/helpers.h create mode 100644 depend/zcash/src/rust/include/rust/history.h create mode 100644 depend/zcash/src/rust/include/rust/map.h create mode 100644 depend/zcash/src/rust/include/rust/metrics.h create mode 100644 depend/zcash/src/rust/include/rust/orchard.h create mode 100644 depend/zcash/src/rust/include/rust/orchard/incremental_merkle_tree.h create mode 100644 depend/zcash/src/rust/include/rust/orchard/keys.h create mode 100644 depend/zcash/src/rust/include/rust/orchard/wallet.h create mode 100644 depend/zcash/src/rust/include/rust/streams.h create mode 100644 depend/zcash/src/rust/include/rust/test_harness.h create mode 100644 depend/zcash/src/rust/include/rust/transaction.h create mode 100644 depend/zcash/src/rust/include/rust/types.h create mode 100644 depend/zcash/src/rust/include/rust/unified_keys.h create mode 100644 depend/zcash/src/rust/include/rust/zip339.h create mode 100644 depend/zcash/src/rust/include/tracing.h create mode 100644 depend/zcash/src/rust/src/address_ffi.rs create mode 100644 depend/zcash/src/rust/src/blake2b.rs create mode 100644 depend/zcash/src/rust/src/builder_ffi.rs create mode 100644 depend/zcash/src/rust/src/ed25519.rs create mode 100644 depend/zcash/src/rust/src/history_ffi.rs create mode 100644 depend/zcash/src/rust/src/incremental_merkle_tree.rs create mode 100644 depend/zcash/src/rust/src/incremental_merkle_tree_ffi.rs create mode 100644 depend/zcash/src/rust/src/metrics_ffi.rs create mode 100644 depend/zcash/src/rust/src/orchard_ffi.rs create mode 100644 depend/zcash/src/rust/src/orchard_keys_ffi.rs create mode 100644 depend/zcash/src/rust/src/rustzcash.rs create mode 100644 depend/zcash/src/rust/src/streams_ffi.rs create mode 100644 depend/zcash/src/rust/src/test_harness_ffi.rs create mode 100644 depend/zcash/src/rust/src/tests/key_agreement.rs create mode 100644 depend/zcash/src/rust/src/tests/key_components.rs create mode 100644 depend/zcash/src/rust/src/tests/mmr.rs create mode 100644 depend/zcash/src/rust/src/tests/mod.rs create mode 100644 depend/zcash/src/rust/src/tests/notes.rs create mode 100644 depend/zcash/src/rust/src/tests/res/tree1023.dat create mode 100644 depend/zcash/src/rust/src/tests/res/tree16.dat create mode 100644 depend/zcash/src/rust/src/tests/signatures.rs create mode 100644 depend/zcash/src/rust/src/tests/zip339.rs create mode 100644 depend/zcash/src/rust/src/tracing_ffi.rs create mode 100644 depend/zcash/src/rust/src/transaction_ffi.rs create mode 100644 depend/zcash/src/rust/src/unified_keys_ffi.rs create mode 100644 depend/zcash/src/rust/src/wallet.rs create mode 100644 depend/zcash/src/rust/src/zcashd_orchard.rs create mode 100644 depend/zcash/src/rust/src/zip339_ffi.rs create mode 100644 depend/zcash/src/scheduler.cpp create mode 100644 depend/zcash/src/scheduler.h create mode 100644 depend/zcash/src/script/interpreter.cpp create mode 100644 depend/zcash/src/script/interpreter.h create mode 100644 depend/zcash/src/script/ismine.cpp create mode 100644 depend/zcash/src/script/ismine.h create mode 100644 depend/zcash/src/script/script.cpp create mode 100644 depend/zcash/src/script/script.h create mode 100644 depend/zcash/src/script/script_error.cpp create mode 100644 depend/zcash/src/script/script_error.h create mode 100644 depend/zcash/src/script/sigcache.cpp create mode 100644 depend/zcash/src/script/sigcache.h create mode 100644 depend/zcash/src/script/sign.cpp create mode 100644 depend/zcash/src/script/sign.h create mode 100644 depend/zcash/src/script/standard.cpp create mode 100644 depend/zcash/src/script/standard.h create mode 100644 depend/zcash/src/script/zcash_script.cpp create mode 100644 depend/zcash/src/script/zcash_script.h create mode 100644 depend/zcash/src/secp256k1/.gitignore create mode 100644 depend/zcash/src/secp256k1/.travis.yml create mode 100644 depend/zcash/src/secp256k1/COPYING create mode 100644 depend/zcash/src/secp256k1/Makefile.am create mode 100644 depend/zcash/src/secp256k1/README.md create mode 100644 depend/zcash/src/secp256k1/SECURITY.md create mode 100755 depend/zcash/src/secp256k1/autogen.sh create mode 100644 depend/zcash/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 create mode 100644 depend/zcash/src/secp256k1/build-aux/m4/bitcoin_secp.m4 create mode 100644 depend/zcash/src/secp256k1/configure.ac create mode 100644 depend/zcash/src/secp256k1/contrib/lax_der_parsing.c create mode 100644 depend/zcash/src/secp256k1/contrib/lax_der_parsing.h create mode 100644 depend/zcash/src/secp256k1/contrib/lax_der_privatekey_parsing.c create mode 100644 depend/zcash/src/secp256k1/contrib/lax_der_privatekey_parsing.h create mode 100755 depend/zcash/src/secp256k1/contrib/travis.sh create mode 100644 depend/zcash/src/secp256k1/include/secp256k1.h create mode 100644 depend/zcash/src/secp256k1/include/secp256k1_ecdh.h create mode 100644 depend/zcash/src/secp256k1/include/secp256k1_extrakeys.h create mode 100644 depend/zcash/src/secp256k1/include/secp256k1_preallocated.h create mode 100644 depend/zcash/src/secp256k1/include/secp256k1_recovery.h create mode 100644 depend/zcash/src/secp256k1/include/secp256k1_schnorrsig.h create mode 100644 depend/zcash/src/secp256k1/libsecp256k1.pc.in create mode 100644 depend/zcash/src/secp256k1/obj/.gitignore create mode 100644 depend/zcash/src/secp256k1/sage/gen_exhaustive_groups.sage create mode 100644 depend/zcash/src/secp256k1/sage/gen_split_lambda_constants.sage create mode 100644 depend/zcash/src/secp256k1/sage/group_prover.sage create mode 100644 depend/zcash/src/secp256k1/sage/prove_group_implementations.sage create mode 100644 depend/zcash/src/secp256k1/sage/secp256k1_params.sage create mode 100644 depend/zcash/src/secp256k1/sage/weierstrass_prover.sage create mode 100644 depend/zcash/src/secp256k1/src/asm/field_10x26_arm.s create mode 100644 depend/zcash/src/secp256k1/src/assumptions.h create mode 100644 depend/zcash/src/secp256k1/src/basic-config.h create mode 100644 depend/zcash/src/secp256k1/src/bench.h create mode 100644 depend/zcash/src/secp256k1/src/bench_ecdh.c create mode 100644 depend/zcash/src/secp256k1/src/bench_ecmult.c create mode 100644 depend/zcash/src/secp256k1/src/bench_internal.c create mode 100644 depend/zcash/src/secp256k1/src/bench_recover.c create mode 100644 depend/zcash/src/secp256k1/src/bench_schnorrsig.c create mode 100644 depend/zcash/src/secp256k1/src/bench_sign.c create mode 100644 depend/zcash/src/secp256k1/src/bench_verify.c create mode 100644 depend/zcash/src/secp256k1/src/ecdsa.h create mode 100644 depend/zcash/src/secp256k1/src/ecdsa_impl.h create mode 100644 depend/zcash/src/secp256k1/src/eckey.h create mode 100644 depend/zcash/src/secp256k1/src/eckey_impl.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult_const.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult_const_impl.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult_gen.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult_gen_impl.h create mode 100644 depend/zcash/src/secp256k1/src/ecmult_impl.h create mode 100644 depend/zcash/src/secp256k1/src/field.h create mode 100644 depend/zcash/src/secp256k1/src/field_10x26.h create mode 100644 depend/zcash/src/secp256k1/src/field_10x26_impl.h create mode 100644 depend/zcash/src/secp256k1/src/field_5x52.h create mode 100644 depend/zcash/src/secp256k1/src/field_5x52_asm_impl.h create mode 100644 depend/zcash/src/secp256k1/src/field_5x52_impl.h create mode 100644 depend/zcash/src/secp256k1/src/field_5x52_int128_impl.h create mode 100644 depend/zcash/src/secp256k1/src/field_impl.h create mode 100644 depend/zcash/src/secp256k1/src/gen_context.c create mode 100644 depend/zcash/src/secp256k1/src/group.h create mode 100644 depend/zcash/src/secp256k1/src/group_impl.h create mode 100644 depend/zcash/src/secp256k1/src/hash.h create mode 100644 depend/zcash/src/secp256k1/src/hash_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/ecdh/Makefile.am.include create mode 100644 depend/zcash/src/secp256k1/src/modules/ecdh/main_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/ecdh/tests_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/extrakeys/Makefile.am.include create mode 100644 depend/zcash/src/secp256k1/src/modules/extrakeys/main_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/extrakeys/tests_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/recovery/Makefile.am.include create mode 100644 depend/zcash/src/secp256k1/src/modules/recovery/main_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/recovery/tests_exhaustive_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/recovery/tests_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/schnorrsig/Makefile.am.include create mode 100644 depend/zcash/src/secp256k1/src/modules/schnorrsig/main_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/schnorrsig/tests_exhaustive_impl.h create mode 100644 depend/zcash/src/secp256k1/src/modules/schnorrsig/tests_impl.h create mode 100644 depend/zcash/src/secp256k1/src/num.h create mode 100644 depend/zcash/src/secp256k1/src/num_gmp.h create mode 100644 depend/zcash/src/secp256k1/src/num_gmp_impl.h create mode 100644 depend/zcash/src/secp256k1/src/num_impl.h create mode 100644 depend/zcash/src/secp256k1/src/scalar.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_4x64.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_4x64_impl.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_8x32.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_8x32_impl.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_impl.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_low.h create mode 100644 depend/zcash/src/secp256k1/src/scalar_low_impl.h create mode 100644 depend/zcash/src/secp256k1/src/scratch.h create mode 100644 depend/zcash/src/secp256k1/src/scratch_impl.h create mode 100644 depend/zcash/src/secp256k1/src/secp256k1.c create mode 100644 depend/zcash/src/secp256k1/src/selftest.h create mode 100644 depend/zcash/src/secp256k1/src/testrand.h create mode 100644 depend/zcash/src/secp256k1/src/testrand_impl.h create mode 100644 depend/zcash/src/secp256k1/src/tests.c create mode 100644 depend/zcash/src/secp256k1/src/tests_exhaustive.c create mode 100644 depend/zcash/src/secp256k1/src/util.h create mode 100644 depend/zcash/src/secp256k1/src/valgrind_ctime_test.c create mode 100644 depend/zcash/src/sendalert.cpp create mode 100644 depend/zcash/src/serialize.h create mode 100644 depend/zcash/src/spentindex.h create mode 100644 depend/zcash/src/streams.h create mode 100644 depend/zcash/src/support/allocators/secure.h create mode 100644 depend/zcash/src/support/allocators/zeroafterfree.h create mode 100644 depend/zcash/src/support/cleanse.cpp create mode 100644 depend/zcash/src/support/cleanse.h create mode 100644 depend/zcash/src/support/events.h create mode 100644 depend/zcash/src/support/lockedpool.cpp create mode 100644 depend/zcash/src/support/lockedpool.h create mode 100644 depend/zcash/src/sync.cpp create mode 100644 depend/zcash/src/sync.h create mode 100644 depend/zcash/src/test/Checkpoints_tests.cpp create mode 100644 depend/zcash/src/test/DoS_tests.cpp create mode 100644 depend/zcash/src/test/Makefile create mode 100644 depend/zcash/src/test/README.md create mode 100644 depend/zcash/src/test/addrman_tests.cpp create mode 100644 depend/zcash/src/test/alert_tests.cpp create mode 100644 depend/zcash/src/test/allocator_tests.cpp create mode 100644 depend/zcash/src/test/arith_uint256_tests.cpp create mode 100644 depend/zcash/src/test/base32_tests.cpp create mode 100644 depend/zcash/src/test/base58_tests.cpp create mode 100644 depend/zcash/src/test/base64_tests.cpp create mode 100644 depend/zcash/src/test/bctest.py create mode 100644 depend/zcash/src/test/bech32_tests.cpp create mode 100644 depend/zcash/src/test/bip32_tests.cpp create mode 100755 depend/zcash/src/test/bitcoin-util-test.py create mode 100644 depend/zcash/src/test/bloom_tests.cpp create mode 100644 depend/zcash/src/test/buildenv.py.in create mode 100644 depend/zcash/src/test/checkblock_tests.cpp create mode 100644 depend/zcash/src/test/checkqueue_tests.cpp create mode 100644 depend/zcash/src/test/coins_tests.cpp create mode 100644 depend/zcash/src/test/compress_tests.cpp create mode 100644 depend/zcash/src/test/convertbits_tests.cpp create mode 100644 depend/zcash/src/test/crypto_tests.cpp create mode 100644 depend/zcash/src/test/data/README.md create mode 100644 depend/zcash/src/test/data/alertTests.raw create mode 100644 depend/zcash/src/test/data/base58_encode_decode.json create mode 100644 depend/zcash/src/test/data/base58_keys_invalid.json create mode 100644 depend/zcash/src/test/data/base58_keys_valid.json create mode 100644 depend/zcash/src/test/data/bitcoin-util-test.json create mode 100644 depend/zcash/src/test/data/blanktx.hex create mode 100644 depend/zcash/src/test/data/blanktx.json create mode 100644 depend/zcash/src/test/data/merkle_commitments.json create mode 100644 depend/zcash/src/test/data/merkle_commitments_sapling.json create mode 100644 depend/zcash/src/test/data/merkle_path.json create mode 100644 depend/zcash/src/test/data/merkle_path_sapling.json create mode 100644 depend/zcash/src/test/data/merkle_roots.json create mode 100644 depend/zcash/src/test/data/merkle_roots_orchard.h create mode 100644 depend/zcash/src/test/data/merkle_roots_sapling.json create mode 100644 depend/zcash/src/test/data/merkle_serialization.json create mode 100644 depend/zcash/src/test/data/merkle_serialization_sapling.json create mode 100644 depend/zcash/src/test/data/merkle_witness_serialization.json create mode 100644 depend/zcash/src/test/data/merkle_witness_serialization_sapling.json create mode 100644 depend/zcash/src/test/data/sapling_key_components.json create mode 100644 depend/zcash/src/test/data/script_invalid.json create mode 100644 depend/zcash/src/test/data/script_valid.json create mode 100644 depend/zcash/src/test/data/sighash.json create mode 100644 depend/zcash/src/test/data/tt-delin1-out.hex create mode 100644 depend/zcash/src/test/data/tt-delin1-out.json create mode 100644 depend/zcash/src/test/data/tt-delout1-out.hex create mode 100644 depend/zcash/src/test/data/tt-delout1-out.json create mode 100644 depend/zcash/src/test/data/tt-locktime317000-out.hex create mode 100644 depend/zcash/src/test/data/tt-locktime317000-out.json create mode 100644 depend/zcash/src/test/data/tx394b54bb.hex create mode 100644 depend/zcash/src/test/data/tx_invalid.json create mode 100644 depend/zcash/src/test/data/tx_valid.json create mode 100644 depend/zcash/src/test/data/txcreate1.hex create mode 100644 depend/zcash/src/test/data/txcreate1.json create mode 100644 depend/zcash/src/test/data/txcreate2.hex create mode 100644 depend/zcash/src/test/data/txcreate2.json create mode 100644 depend/zcash/src/test/data/txcreatedata_seq0.hex create mode 100644 depend/zcash/src/test/data/txcreatedata_seq0.json create mode 100644 depend/zcash/src/test/data/txcreatedata_seq1.hex create mode 100644 depend/zcash/src/test/data/txcreatedata_seq1.json create mode 100644 depend/zcash/src/test/data/txcreatesign.hex create mode 100644 depend/zcash/src/test/data/txcreatesign.json create mode 100644 depend/zcash/src/test/data/unified_addrs.json create mode 100644 depend/zcash/src/test/data/unified_full_viewing_keys.json create mode 100644 depend/zcash/src/test/data/zip0244.json create mode 100644 depend/zcash/src/test/dbwrapper_tests.cpp create mode 100644 depend/zcash/src/test/equihash_tests.cpp create mode 100644 depend/zcash/src/test/getarg_tests.cpp create mode 100644 depend/zcash/src/test/hash_tests.cpp create mode 100644 depend/zcash/src/test/key_tests.cpp create mode 100644 depend/zcash/src/test/limitedmap_tests.cpp create mode 100644 depend/zcash/src/test/main_tests.cpp create mode 100644 depend/zcash/src/test/mempool_tests.cpp create mode 100644 depend/zcash/src/test/miner_tests.cpp create mode 100644 depend/zcash/src/test/multisig_tests.cpp create mode 100644 depend/zcash/src/test/net_tests.cpp create mode 100644 depend/zcash/src/test/netbase_tests.cpp create mode 100644 depend/zcash/src/test/pmt_tests.cpp create mode 100644 depend/zcash/src/test/policyestimator_tests.cpp create mode 100644 depend/zcash/src/test/pow_tests.cpp create mode 100644 depend/zcash/src/test/prevector_tests.cpp create mode 100644 depend/zcash/src/test/raii_event_tests.cpp create mode 100644 depend/zcash/src/test/random_tests.cpp create mode 100644 depend/zcash/src/test/reverselock_tests.cpp create mode 100644 depend/zcash/src/test/rpc_tests.cpp create mode 100644 depend/zcash/src/test/sanity_tests.cpp create mode 100644 depend/zcash/src/test/scheduler_tests.cpp create mode 100644 depend/zcash/src/test/script_P2PKH_tests.cpp create mode 100644 depend/zcash/src/test/script_P2SH_tests.cpp create mode 100644 depend/zcash/src/test/script_standard_tests.cpp create mode 100644 depend/zcash/src/test/script_tests.cpp create mode 100644 depend/zcash/src/test/scriptnum10.h create mode 100644 depend/zcash/src/test/scriptnum_tests.cpp create mode 100644 depend/zcash/src/test/serialize_tests.cpp create mode 100644 depend/zcash/src/test/sha256compress_tests.cpp create mode 100644 depend/zcash/src/test/sighash_tests.cpp create mode 100644 depend/zcash/src/test/sigopcount_tests.cpp create mode 100644 depend/zcash/src/test/skiplist_tests.cpp create mode 100644 depend/zcash/src/test/streams_tests.cpp create mode 100644 depend/zcash/src/test/test_bitcoin.cpp create mode 100644 depend/zcash/src/test/test_bitcoin.h create mode 100644 depend/zcash/src/test/test_random.h create mode 100644 depend/zcash/src/test/test_util.cpp create mode 100644 depend/zcash/src/test/test_util.h create mode 100644 depend/zcash/src/test/torcontrol_tests.cpp create mode 100644 depend/zcash/src/test/transaction_tests.cpp create mode 100644 depend/zcash/src/test/txvalidationcache_tests.cpp create mode 100644 depend/zcash/src/test/uint256_tests.cpp create mode 100644 depend/zcash/src/test/univalue_tests.cpp create mode 100644 depend/zcash/src/test/util_tests.cpp create mode 100644 depend/zcash/src/threadsafety.h create mode 100644 depend/zcash/src/timedata.cpp create mode 100644 depend/zcash/src/timedata.h create mode 100644 depend/zcash/src/timestampindex.h create mode 100644 depend/zcash/src/tinyformat.h create mode 100644 depend/zcash/src/torcontrol.cpp create mode 100644 depend/zcash/src/torcontrol.h create mode 100644 depend/zcash/src/transaction_builder.cpp create mode 100644 depend/zcash/src/transaction_builder.h create mode 100644 depend/zcash/src/txdb.cpp create mode 100644 depend/zcash/src/txdb.h create mode 100644 depend/zcash/src/txmempool.cpp create mode 100644 depend/zcash/src/txmempool.h create mode 100644 depend/zcash/src/ui_interface.h create mode 100644 depend/zcash/src/uint252.h create mode 100644 depend/zcash/src/uint256.cpp create mode 100644 depend/zcash/src/uint256.h create mode 100644 depend/zcash/src/undo.h create mode 100644 depend/zcash/src/univalue/.gitignore create mode 100644 depend/zcash/src/univalue/.travis.yml create mode 100644 depend/zcash/src/univalue/COPYING create mode 100644 depend/zcash/src/univalue/Makefile.am create mode 100644 depend/zcash/src/univalue/README.md create mode 100644 depend/zcash/src/univalue/TODO create mode 100755 depend/zcash/src/univalue/autogen.sh create mode 100644 depend/zcash/src/univalue/build-aux/m4/.gitignore create mode 100644 depend/zcash/src/univalue/configure.ac create mode 100644 depend/zcash/src/univalue/gen/gen.cpp create mode 100644 depend/zcash/src/univalue/include/univalue.h create mode 100644 depend/zcash/src/univalue/lib/.gitignore create mode 100644 depend/zcash/src/univalue/lib/univalue.cpp create mode 100644 depend/zcash/src/univalue/lib/univalue_escapes.h create mode 100644 depend/zcash/src/univalue/lib/univalue_get.cpp create mode 100644 depend/zcash/src/univalue/lib/univalue_read.cpp create mode 100644 depend/zcash/src/univalue/lib/univalue_utffilter.h create mode 100644 depend/zcash/src/univalue/lib/univalue_write.cpp create mode 100644 depend/zcash/src/univalue/pc/libunivalue-uninstalled.pc.in create mode 100644 depend/zcash/src/univalue/pc/libunivalue.pc.in create mode 100644 depend/zcash/src/univalue/test/.gitignore create mode 100644 depend/zcash/src/univalue/test/fail1.json create mode 100644 depend/zcash/src/univalue/test/fail10.json create mode 100644 depend/zcash/src/univalue/test/fail11.json create mode 100644 depend/zcash/src/univalue/test/fail12.json create mode 100644 depend/zcash/src/univalue/test/fail13.json create mode 100644 depend/zcash/src/univalue/test/fail14.json create mode 100644 depend/zcash/src/univalue/test/fail15.json create mode 100644 depend/zcash/src/univalue/test/fail16.json create mode 100644 depend/zcash/src/univalue/test/fail17.json create mode 100644 depend/zcash/src/univalue/test/fail18.json create mode 100644 depend/zcash/src/univalue/test/fail19.json create mode 100644 depend/zcash/src/univalue/test/fail2.json create mode 100644 depend/zcash/src/univalue/test/fail20.json create mode 100644 depend/zcash/src/univalue/test/fail21.json create mode 100644 depend/zcash/src/univalue/test/fail22.json create mode 100644 depend/zcash/src/univalue/test/fail23.json create mode 100644 depend/zcash/src/univalue/test/fail24.json create mode 100644 depend/zcash/src/univalue/test/fail25.json create mode 100644 depend/zcash/src/univalue/test/fail26.json create mode 100644 depend/zcash/src/univalue/test/fail27.json create mode 100644 depend/zcash/src/univalue/test/fail28.json create mode 100644 depend/zcash/src/univalue/test/fail29.json create mode 100644 depend/zcash/src/univalue/test/fail3.json create mode 100644 depend/zcash/src/univalue/test/fail30.json create mode 100644 depend/zcash/src/univalue/test/fail31.json create mode 100644 depend/zcash/src/univalue/test/fail32.json create mode 100644 depend/zcash/src/univalue/test/fail33.json create mode 100644 depend/zcash/src/univalue/test/fail34.json create mode 100644 depend/zcash/src/univalue/test/fail35.json create mode 100644 depend/zcash/src/univalue/test/fail36.json create mode 100644 depend/zcash/src/univalue/test/fail37.json create mode 100644 depend/zcash/src/univalue/test/fail38.json create mode 100644 depend/zcash/src/univalue/test/fail39.json create mode 100644 depend/zcash/src/univalue/test/fail4.json create mode 100644 depend/zcash/src/univalue/test/fail40.json create mode 100644 depend/zcash/src/univalue/test/fail41.json create mode 100644 depend/zcash/src/univalue/test/fail42.json create mode 100644 depend/zcash/src/univalue/test/fail44.json create mode 100644 depend/zcash/src/univalue/test/fail45.json create mode 100644 depend/zcash/src/univalue/test/fail5.json create mode 100644 depend/zcash/src/univalue/test/fail6.json create mode 100644 depend/zcash/src/univalue/test/fail7.json create mode 100644 depend/zcash/src/univalue/test/fail8.json create mode 100644 depend/zcash/src/univalue/test/fail9.json create mode 100644 depend/zcash/src/univalue/test/no_nul.cpp create mode 100644 depend/zcash/src/univalue/test/object.cpp create mode 100644 depend/zcash/src/univalue/test/pass1.json create mode 100644 depend/zcash/src/univalue/test/pass2.json create mode 100644 depend/zcash/src/univalue/test/pass3.json create mode 100644 depend/zcash/src/univalue/test/pass4.json create mode 100644 depend/zcash/src/univalue/test/round1.json create mode 100644 depend/zcash/src/univalue/test/round2.json create mode 100644 depend/zcash/src/univalue/test/round3.json create mode 100644 depend/zcash/src/univalue/test/round4.json create mode 100644 depend/zcash/src/univalue/test/round5.json create mode 100644 depend/zcash/src/univalue/test/round6.json create mode 100644 depend/zcash/src/univalue/test/round7.json create mode 100644 depend/zcash/src/univalue/test/test_json.cpp create mode 100644 depend/zcash/src/univalue/test/unitester.cpp create mode 100644 depend/zcash/src/util.cpp create mode 100644 depend/zcash/src/util.h create mode 100644 depend/zcash/src/util/match.h create mode 100644 depend/zcash/src/utilmoneystr.cpp create mode 100644 depend/zcash/src/utilmoneystr.h create mode 100644 depend/zcash/src/utilstrencodings.cpp create mode 100644 depend/zcash/src/utilstrencodings.h create mode 100644 depend/zcash/src/utiltest.cpp create mode 100644 depend/zcash/src/utiltest.h create mode 100644 depend/zcash/src/utiltime.cpp create mode 100644 depend/zcash/src/utiltime.h create mode 100644 depend/zcash/src/validationinterface.cpp create mode 100644 depend/zcash/src/validationinterface.h create mode 100644 depend/zcash/src/version.h create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_common.cpp create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_common.h create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_mergetoaddress.cpp create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_mergetoaddress.h create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_saplingmigration.cpp create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_saplingmigration.h create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_sendmany.cpp create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_sendmany.h create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_shieldcoinbase.cpp create mode 100644 depend/zcash/src/wallet/asyncrpcoperation_shieldcoinbase.h create mode 100644 depend/zcash/src/wallet/crypter.cpp create mode 100644 depend/zcash/src/wallet/crypter.h create mode 100644 depend/zcash/src/wallet/db.cpp create mode 100644 depend/zcash/src/wallet/db.h create mode 100644 depend/zcash/src/wallet/gtest/test_note_selection.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_orchard_wallet.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_orchard_zkeys.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_paymentdisclosure.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_rpc_wallet.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_wallet.cpp create mode 100644 depend/zcash/src/wallet/gtest/test_wallet_zkeys.cpp create mode 100644 depend/zcash/src/wallet/orchard.cpp create mode 100644 depend/zcash/src/wallet/orchard.h create mode 100644 depend/zcash/src/wallet/paymentdisclosure.cpp create mode 100644 depend/zcash/src/wallet/paymentdisclosure.h create mode 100644 depend/zcash/src/wallet/paymentdisclosuredb.cpp create mode 100644 depend/zcash/src/wallet/paymentdisclosuredb.h create mode 100644 depend/zcash/src/wallet/rpcdisclosure.cpp create mode 100644 depend/zcash/src/wallet/rpcdump.cpp create mode 100644 depend/zcash/src/wallet/rpcwallet.cpp create mode 100644 depend/zcash/src/wallet/rpcwallet.h create mode 100644 depend/zcash/src/wallet/test/crypto_tests.cpp create mode 100644 depend/zcash/src/wallet/test/rpc_wallet_tests.cpp create mode 100644 depend/zcash/src/wallet/test/wallet_test_fixture.cpp create mode 100644 depend/zcash/src/wallet/test/wallet_test_fixture.h create mode 100644 depend/zcash/src/wallet/test/wallet_tests.cpp create mode 100644 depend/zcash/src/wallet/wallet.cpp create mode 100644 depend/zcash/src/wallet/wallet.h create mode 100644 depend/zcash/src/wallet/walletdb.cpp create mode 100644 depend/zcash/src/wallet/walletdb.h create mode 100644 depend/zcash/src/warnings.cpp create mode 100644 depend/zcash/src/warnings.h create mode 100644 depend/zcash/src/zcash/Address.cpp create mode 100644 depend/zcash/src/zcash/Address.hpp create mode 100644 depend/zcash/src/zcash/History.cpp create mode 100644 depend/zcash/src/zcash/History.hpp create mode 100644 depend/zcash/src/zcash/IncrementalMerkleTree.cpp create mode 100644 depend/zcash/src/zcash/IncrementalMerkleTree.hpp create mode 100644 depend/zcash/src/zcash/JoinSplit.cpp create mode 100644 depend/zcash/src/zcash/JoinSplit.hpp create mode 100644 depend/zcash/src/zcash/Note.cpp create mode 100644 depend/zcash/src/zcash/Note.hpp create mode 100644 depend/zcash/src/zcash/NoteEncryption.cpp create mode 100644 depend/zcash/src/zcash/NoteEncryption.hpp create mode 100644 depend/zcash/src/zcash/Proof.hpp create mode 100644 depend/zcash/src/zcash/Zcash.h create mode 100644 depend/zcash/src/zcash/address/mnemonic.cpp create mode 100644 depend/zcash/src/zcash/address/mnemonic.h create mode 100644 depend/zcash/src/zcash/address/orchard.cpp create mode 100644 depend/zcash/src/zcash/address/orchard.hpp create mode 100644 depend/zcash/src/zcash/address/sapling.cpp create mode 100644 depend/zcash/src/zcash/address/sapling.hpp create mode 100644 depend/zcash/src/zcash/address/sprout.cpp create mode 100644 depend/zcash/src/zcash/address/sprout.hpp create mode 100644 depend/zcash/src/zcash/address/transparent.cpp create mode 100644 depend/zcash/src/zcash/address/transparent.h create mode 100644 depend/zcash/src/zcash/address/unified.cpp create mode 100644 depend/zcash/src/zcash/address/unified.h create mode 100644 depend/zcash/src/zcash/address/zip32.cpp create mode 100644 depend/zcash/src/zcash/address/zip32.h create mode 100644 depend/zcash/src/zcash/prf.cpp create mode 100644 depend/zcash/src/zcash/prf.h create mode 100644 depend/zcash/src/zcash/util.cpp create mode 100644 depend/zcash/src/zcash/util.h create mode 100644 depend/zcash/src/zcbenchmarks.cpp create mode 100644 depend/zcash/src/zcbenchmarks.h create mode 100644 depend/zcash/src/zmq/zmqabstractnotifier.cpp create mode 100644 depend/zcash/src/zmq/zmqabstractnotifier.h create mode 100644 depend/zcash/src/zmq/zmqconfig.h create mode 100644 depend/zcash/src/zmq/zmqnotificationinterface.cpp create mode 100644 depend/zcash/src/zmq/zmqnotificationinterface.h create mode 100644 depend/zcash/src/zmq/zmqpublishnotifier.cpp create mode 100644 depend/zcash/src/zmq/zmqpublishnotifier.h create mode 100644 depend/zcash/test/lint/README.md create mode 100755 depend/zcash/test/lint/commit-script-check.sh create mode 100755 depend/zcash/test/lint/git-subtree-check.sh create mode 100755 depend/zcash/test/lint/lint-all.sh create mode 100755 depend/zcash/test/lint/lint-cargo-patches.sh create mode 100755 depend/zcash/test/lint/lint-include-guards.sh create mode 100755 depend/zcash/test/lint/lint-includes.sh create mode 100755 depend/zcash/test/lint/lint-locale-dependence.sh create mode 100755 depend/zcash/test/lint/lint-python-utf8-encoding.sh create mode 100755 depend/zcash/test/lint/lint-shebang.sh create mode 100755 depend/zcash/test/lint/lint-shell-locale.sh create mode 100755 depend/zcash/test/lint/lint-shell.sh create mode 100755 depend/zcash/test/lint/lint-whitespace.sh create mode 100755 depend/zcash/zcutil/afl/afl-build.sh create mode 100755 depend/zcash/zcutil/afl/afl-get.sh create mode 100755 depend/zcash/zcutil/afl/afl-getbuildrun.sh create mode 100755 depend/zcash/zcutil/afl/afl-run.sh create mode 100755 depend/zcash/zcutil/afl/zcash-wrapper create mode 120000 depend/zcash/zcutil/afl/zcash-wrapper-clang create mode 120000 depend/zcash/zcutil/afl/zcash-wrapper-clang++ create mode 120000 depend/zcash/zcutil/afl/zcash-wrapper-g++ create mode 120000 depend/zcash/zcutil/afl/zcash-wrapper-gcc create mode 100755 depend/zcash/zcutil/build-debian-package.sh create mode 100755 depend/zcash/zcutil/build.sh create mode 100755 depend/zcash/zcutil/clean.sh create mode 100755 depend/zcash/zcutil/cleanup-tags.sh create mode 100755 depend/zcash/zcutil/distclean.sh create mode 100755 depend/zcash/zcutil/fetch-params.sh create mode 100755 depend/zcash/zcutil/libfuzzer/libfuzzer-build.sh create mode 100755 depend/zcash/zcutil/libfuzzer/zcash-wrapper create mode 120000 depend/zcash/zcutil/libfuzzer/zcash-wrapper-clang create mode 120000 depend/zcash/zcutil/libfuzzer/zcash-wrapper-clang++ create mode 100755 depend/zcash/zcutil/make-release.py create mode 100755 depend/zcash/zcutil/release-notes.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c54f4dd7..4e44f6ab5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,28 @@ jobs: with: command: check + # Test that "cargo package" works. This make sure it's publishable, + # since we had issues where "cargo build" worked but "package" didn't. + package: + name: Package + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - nightly + steps: + - uses: actions/checkout@v1 + with: + submodules: true + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + - uses: actions-rs/cargo@v1 + with: + command: package + test-versions: name: Test Suite runs-on: ubuntu-latest diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1ccd6bfdc..000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "depend/zcash"] - path = depend/zcash - url = https://github.com/zcash/zcash.git - branch = master diff --git a/CHANGELOG.md b/CHANGELOG.md index eeab7a112..b1cffc7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [Unreleased] - ReleaseDate + ## [0.1.6] - 2022-05-16 ### Changed @@ -41,7 +43,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated `bindgen` to a non yanked version -[Unreleased]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.5...HEAD +[Unreleased]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.6...HEAD +[0.1.6]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.5...v0.1.6 [0.1.5]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.4...v0.1.5 [0.1.4]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.3...v0.1.4 [0.1.3]: https://github.com/ZcashFoundation/zcash_script/compare/v0.1.2...v0.1.3 diff --git a/Cargo.toml b/Cargo.toml index 23ff08091..57d18c55b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,17 +10,12 @@ description = "ffi bindings to zcashd's zcash_script library" documentation = "https://docs.rs/zcash_script" repository = "https://github.com/ZcashFoundation/zcash_script" include = [ - "/.github/workflows/ci.yml", - "/.gitignore", - "/.gitmodules", "Cargo.toml", - "Cargo.toml.orig", "/LICENSE", "/README.md", "build.rs", - "depend/check_uint128_t.c", - "src/blake2b.rs", - "src/lib.rs", + "src/*.rs", + "/depend/check_uint128_t.c", "/depend/zcash/src/script/zcash_script.h", "/depend/zcash/src/script/zcash_script.cpp", "/depend/zcash/src/utilstrencodings.cpp", diff --git a/README.md b/README.md index 8eac4c6fd..112b08711 100644 --- a/README.md +++ b/README.md @@ -30,42 +30,39 @@ To do that, check for versions in: - `librustzcash/Cargo.toml` in the revision pointed to by `zcash` (also check for patches) - `librustzcash//Cargo.toml` in the revision pointed to by `zcash` -### Cloning and checking out `depend/zcash` +### Updating `depend/zcash` -Clone this repository using: -```console -git clone --recurse-submodules -``` +We keep a copy of the zcash source in `depend/zcash` with the help of `git subtree`. +It has one single difference that must be enforced everytime it's updated: the root +`Cargo.toml` must be deleted, since otherwise cargo will ignore the entire folder +when publishing the crate (see https://github.com/rust-lang/cargo/issues/8597). -Or if you've already cloned: -```console -git submodule update --init -``` +If you need to update the zcash source, run: -To pull the latest version, use: ```console -git pull --recurse-submodules +git subtree pull -P depend/zcash https://github.com/zcash/zcash.git --squash ``` -### Updating `depend/zcash` - -If you need to change the submodule's base branch: -```console -git config -f .gitmodules submodule.depend/zcash.branch -``` +where `` is a reference to a branch, tag or commit (it should be a tag when preparing +a release, but it will be likely a branch or commit when testing). -To pull in recent changes from the upstream repo: +The command will likely report a conflict due to the deleted `Cargo.toml` file. +Just run ```console -git submodule update --remote +git rm depend/zcash/Cargo.toml ``` -To use a specific commit: +and then commit the updates. Note: after updating zcash, the PR that includes it must *not* be +squashed-and-merged, due to how subtree works. Otherwise you will get errors +when trying to update zcash again. + +If that ends up happening, you can always `git rm depend/zcash` and start over +(run the same command as above, but with `add` instead of `pull`); +our usage of `subtree` is to just have a convenient way of pulling copies of `zcash`. +(Unfortunately, switching to submodules is not a good solution due to the need of +deleting the `Cargo.toml`.) -```console -cd depend/zcash -git checkout -``` ### Publishing New Releases @@ -75,6 +72,7 @@ Releases for `zcash-script` are made with the help of [cargo release](https://gi * create a new branch batch the release commits into a PR * update `CHANGELOG.md` to document any major changes since the last release + https://github.com/rust-lang/cargo/issues/8597) * open a PR to merge your branch into `master` * locally run `cargo release -- ` where `level` can be `patch`, `minor`, or `major` ([source](https://github.com/sunng87/cargo-release/blob/master/docs/reference.md#bump-level)) diff --git a/depend/zcash b/depend/zcash deleted file mode 160000 index 16b49eadd..000000000 --- a/depend/zcash +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 16b49eadd56086aae10f2907e5b8e77b773f1813 diff --git a/depend/zcash/.cargo/config.offline b/depend/zcash/.cargo/config.offline new file mode 100644 index 000000000..8b7762d20 --- /dev/null +++ b/depend/zcash/.cargo/config.offline @@ -0,0 +1,8 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" + +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +# The directory for this source is set to RUST_VENDORED_SOURCES by src/Makefile.am diff --git a/depend/zcash/.gitattributes b/depend/zcash/.gitattributes new file mode 100644 index 000000000..c9cf4a7d9 --- /dev/null +++ b/depend/zcash/.gitattributes @@ -0,0 +1 @@ +src/clientversion.cpp export-subst diff --git a/depend/zcash/.github/ISSUE_TEMPLATE/bug-report.md b/depend/zcash/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 000000000..447787404 --- /dev/null +++ b/depend/zcash/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,65 @@ +--- +name: Bug report +about: Create a report about a bug in zcashd. +title: '' +labels: 'bug' +assignees: '' + +--- + + + +### Describe the issue +Please provide a general summary of the issue you're experiencing + +### Can you reliably reproduce the issue? +#### If so, please list the steps to reproduce below: +1. +2. +3. + +### Expected behaviour +Tell us what should happen + +### Actual behaviour + errors +Tell us what happens instead including any noticeable error output (any messages +displayed on-screen when e.g. a crash occurred) + +### The version of Zcash you were using: +Run `zcashd --version` to find out + +### Machine specs: +- OS name + version: +- CPU: +- RAM: +- Disk size: +- Disk Type (HD/SDD): +- Linux kernel version (uname -a): +- Compiler version (gcc --version): +- Linker version (ld -v): +- Assembler version (as --version): + +### Any extra information that might be useful in the debugging process. +This includes the relevant contents of `~/.zcash/debug.log`. You can paste raw +text, attach the file directly in the issue or link to the text via a pastebin +type site. Please also include any non-standard things you did during +compilation (extra flags, dependency version changes etc.) if applicable. + +### Do you have a backup of `~/.zcash` directory and/or take a VM snapshot? +- Backing up / making a copy of the `~/.zcash` directory might help make the + problem reproducible. Please redact appropriately. +- Taking a VM snapshot is really helpful for interactively testing fixes diff --git a/depend/zcash/.github/ISSUE_TEMPLATE/feature-request.md b/depend/zcash/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 000000000..57abb7286 --- /dev/null +++ b/depend/zcash/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,22 @@ +--- +name: Feature request +about: Suggest an idea for zcashd. +title: '' +labels: 'use case' +assignees: '' + +--- + +## Is your feature request related to a problem? Please describe. +A clear and concise description of what the problem is. Example: I'm always +frustrated when [...] + +## Describe the solution you'd like +A clear and concise description of what you want to happen. + +## Alternatives you've considered +A clear and concise description of any alternative solutions or features you've +considered. + +## Additional context +Add any other context or screenshots about the feature request here. diff --git a/depend/zcash/.github/ISSUE_TEMPLATE/ux-report.md b/depend/zcash/.github/ISSUE_TEMPLATE/ux-report.md new file mode 100644 index 000000000..118db34a2 --- /dev/null +++ b/depend/zcash/.github/ISSUE_TEMPLATE/ux-report.md @@ -0,0 +1,17 @@ +--- +name: UX report +about: Was zcashd hard to use? It's not you, it's us. We want to hear about it. +title: 'UX: ' +labels: 'usability' +assignees: '' + +--- + + + +## What were you trying to do + +## What happened diff --git a/depend/zcash/.github/dependabot.yml b/depend/zcash/.github/dependabot.yml new file mode 100644 index 000000000..5c4156c6a --- /dev/null +++ b/depend/zcash/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + timezone: Etc/UTC + open-pull-requests-limit: 10 + reviewers: + - str4d + assignees: + - str4d + labels: + - "A-CI" diff --git a/depend/zcash/.github/pull_request_template.md b/depend/zcash/.github/pull_request_template.md new file mode 100644 index 000000000..fcb24062c --- /dev/null +++ b/depend/zcash/.github/pull_request_template.md @@ -0,0 +1,5 @@ +Please ensure this checklist is followed for any pull requests for this repo. This checklist must be checked by both the PR creator and by anyone who reviews the PR. +* [ ] Relevant documentation for this PR has to be completed and reviewed by @mdr0id before the PR can be merged +* [ ] A test plan for the PR must be documented in the PR notes and included in the test plan for the next regular release + +As a note, all buildbot tests need to be passing and all appropriate code reviews need to be done before this PR can be merged diff --git a/depend/zcash/.github/workflows/book.yml b/depend/zcash/.github/workflows/book.yml new file mode 100644 index 000000000..12112f122 --- /dev/null +++ b/depend/zcash/.github/workflows/book.yml @@ -0,0 +1,32 @@ +name: zcashd book + +on: + push: + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Setup mdBook + uses: peaceiris/actions-mdbook@v1 + with: + mdbook-version: 'latest' + + - name: Install mdbook-katex + uses: actions-rs/cargo@v1 + with: + command: install + args: mdbook-katex + + - name: Build zcashd book + run: mdbook build doc/book/ + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./doc/book/book diff --git a/depend/zcash/.github/workflows/lints.yml b/depend/zcash/.github/workflows/lints.yml new file mode 100644 index 000000000..9310129cb --- /dev/null +++ b/depend/zcash/.github/workflows/lints.yml @@ -0,0 +1,106 @@ +name: Lints + +# We only run these lints on trial-merges of PRs to reduce noise. +on: pull_request + +jobs: + commit-script-check: + name: Scripted diffs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Check scripted diffs + run: ./test/lint/commit-script-check.sh ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} + + general-lints: + name: General + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Cargo patches + run: ./test/lint/lint-cargo-patches.sh + if: always() + + - name: Include guards + run: ./test/lint/lint-include-guards.sh + if: always() + + - name: Includes + run: ./test/lint/lint-includes.sh + if: always() + + - name: Locale dependence + run: ./test/lint/lint-locale-dependence.sh + if: always() + continue-on-error: true # Temporary until we get this passing + + - name: Shebang + run: ./test/lint/lint-shebang.sh + if: always() + continue-on-error: true # Temporary until we get this passing + + - name: Shell locale + run: ./test/lint/lint-shell-locale.sh + if: always() + continue-on-error: true # Temporary until we get this passing + + - name: Shellcheck + run: ./test/lint/lint-shell.sh + if: always() + continue-on-error: true # Temporary until we get this passing + + - name: Whitespace + run: ./test/lint/lint-whitespace.sh + if: always() + + python: + name: Python + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: sudo python3 -m pip install pyflakes + + - name: Pyflakes + run: pyflakes qa src zcutil + if: always() + + - name: UTF-8 encoding + run: ./test/lint/lint-python-utf8-encoding.sh + if: always() + + rust-clippy: + name: Clippy (1.59.0) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.59.0 + components: clippy + override: true + - name: Run clippy + uses: actions-rs/clippy-check@v1 + with: + name: Clippy (1.59.0) + token: ${{ secrets.GITHUB_TOKEN }} + args: --all-features --all-targets -- -D warnings + + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: 1.59.0 + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: -- --check diff --git a/depend/zcash/.gitignore b/depend/zcash/.gitignore new file mode 100644 index 000000000..bc02b55db --- /dev/null +++ b/depend/zcash/.gitignore @@ -0,0 +1,129 @@ +*.tar.gz +*.deb +*.exe +src/bitcoin +src/zcashd +src/zcashd-wallet-tool +src/zcash-cli +src/zcash-gtest +src/zcash-tx +src/test/test_bitcoin +zcutil/bin/ + +*zcashTest.pk +*zcashTest.vk + +# autoreconf +Makefile.in +aclocal.m4 +autom4te.cache/ +build-aux/config.guess +build-aux/config.sub +build-aux/depcomp +build-aux/install-sh +build-aux/ltmain.sh +build-aux/m4/libtool.m4 +build-aux/m4/lt~obsolete.m4 +build-aux/m4/ltoptions.m4 +build-aux/m4/ltsugar.m4 +build-aux/m4/ltversion.m4 +build-aux/missing +build-aux/compile +build-aux/test-driver +config.log +config.status +configure +libtool +src/config/bitcoin-config.h +src/config/bitcoin-config.h.in +src/config/stamp-h1 +share/setup.nsi +confdefs.h +conftest.cpp +conftest.err + +cache/ +venv-mnf/ +src/univalue/gen + +.deps +.dirstamp +.libs +.*.swp +*.*~* +*.bak +*.rej +*.orig +*.pyc +*.o +*.o.tmp +*.o-* +.zcash +*.a +*.lib +*.pb.cc +*.pb.h +.vscode + +*.log +*.trs +*.dmg + +*.json.h +*.raw.h + +#libtool object files +*.lo +*.la + +# Compilation +Makefile + +# Rust +.cargo/.configured-for-* +.cargo/config +target/ + +# Unit-tests +Makefile.test +src/test/buildenv.py + +# Resources cpp +qrc_*.cpp + +# Mac specific +.DS_Store +build + +#lcov +*.gcno +*.gcda +/*.info +test_bitcoin.coverage/ +zcash-gtest.coverage/ +total.coverage/ +coverage_percent.txt +afl-temp + +#build tests +linux-coverage-build +linux-build +win32-build +qa/pull-tester/tests_config.py +qa/pull-tester/tests_config.ini +qa/cache/* + +!src/leveldb*/Makefile + +/doc/doxygen/ + +libzcash_script.pc + +contrib/debian/files +contrib/debian/substvars + +src/fuzzing/*/input +src/fuzzing/*/output +src/fuzz.cpp + +.updatecheck-token diff --git a/depend/zcash/CONTRIBUTING.md b/depend/zcash/CONTRIBUTING.md new file mode 100644 index 000000000..ba01490e4 --- /dev/null +++ b/depend/zcash/CONTRIBUTING.md @@ -0,0 +1 @@ +Please read [our Development Guidelines](https://zcash.readthedocs.io/en/latest/rtd_pages/development_guidelines.html). diff --git a/depend/zcash/COPYING b/depend/zcash/COPYING new file mode 100644 index 000000000..e6e8c782d --- /dev/null +++ b/depend/zcash/COPYING @@ -0,0 +1,44 @@ +Copyright (c) 2016-2022 The Zcash developers +Copyright (c) 2009-2022 The Bitcoin Core developers +Copyright (c) 2009-2022 Bitcoin Developers + +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. + + +The MIT software license (https://www.opensource.org/licenses/mit-license.php) +above applies to the code directly included in this source distribution, with +the exception of certain Autoconf macros. Dependencies downloaded as part of +the build process may be covered by other open-source licenses. The MIT-licensed +source code is not considered a derived work of these Autoconf macros or of the +dependencies. For further details see 'contrib/debian/copyright'. + + +Although almost all of the Zcash code is licensed under "permissive" open source +licenses, users and distributors should note that when built using the default +build options, Zcash depends on Oracle Berkeley DB 6.2.x, which is licensed +under the GNU Affero General Public License. + + +Contributors should understand licensing implications before modifying the +following files in build-aux/m4 (see https://github.com/zcash/zcash/issues/2827): + + * ax_check_compile_flag.m4 + * ax_check_link_flag.m4 + * ax_check_preproc_flag.m4 + * ax_pthread.m4 diff --git a/depend/zcash/Cargo.lock b/depend/zcash/Cargo.lock new file mode 100644 index 000000000..2080a8daa --- /dev/null +++ b/depend/zcash/Cargo.lock @@ -0,0 +1,2407 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.6", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atomic-shim" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cd4b51d303cf3501c301e8125df442128d3c6d7c69f71b27833d253de47e77" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64ct" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" + +[[package]] +name = "bech32" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" + +[[package]] +name = "bellman" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d96d7f4f3dc9a699bdef1d19648f6f20ef966b51892d224582a4475be669cb5" +dependencies = [ + "bitvec", + "blake2s_simd", + "byteorder", + "crossbeam-channel", + "ff", + "group", + "lazy_static", + "log", + "num_cpus", + "pairing", + "rand_core 0.6.3", + "rayon", + "subtle", +] + +[[package]] +name = "bip0039" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0830ae4cc96b0617cc912970c2b17e89456fecbf55e8eed53a956f37ab50c41" +dependencies = [ + "hmac", + "pbkdf2", + "rand 0.8.5", + "sha2", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +dependencies = [ + "arrayref", + "arrayvec 0.7.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-modes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" +dependencies = [ + "block-padding", + "cipher", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "bls12_381" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62250ece575fa9b22068b3a8d59586f01d426dd7785522efd97632959e71c986" +dependencies = [ + "ff", + "group", + "pairing", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2", +] + +[[package]] +name = "bumpalo" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clearscreen" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ed49b0e894fe6264a58496c7ec4e9d3c46f66b59efae527cd5bee429d0a418" +dependencies = [ + "nix", + "terminfo", + "thiserror", + "which", + "winapi", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +dependencies = [ + "cfg-if 0.1.10", + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "ed25519-zebra" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +dependencies = [ + "curve25519-dalek", + "hex", + "rand_core 0.6.3", + "serde", + "sha2", + "thiserror", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "equihash" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4127688f6177e3f57521881cb1cfd90d1228214f9dc43b8efe6f6c6948cd8280" +dependencies = [ + "blake2b_simd 0.5.11", + "byteorder", +] + +[[package]] +name = "f4jumble" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a83e8d7fd0c526af4aad893b7c9fe41e2699ed8a776a6c74aecdeafe05afc75" +dependencies = [ + "blake2b_simd 1.0.0", +] + +[[package]] +name = "ff" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" +dependencies = [ + "bitvec", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fpe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd910db5f9ca4dc3116f8c46367825807aa2b942f72565f16b4be0b208a00a9e" +dependencies = [ + "block-modes", + "cipher", + "libm", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" + +[[package]] +name = "group" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" +dependencies = [ + "byteorder", + "ff", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "gumdrop" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc700f989d2f6f0248546222d9b4258f5b02a171a431f8285a81c08142629e3" +dependencies = [ + "gumdrop_derive", +] + +[[package]] +name = "gumdrop_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "halo2_gadgets" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f3914f58cc4af5e4fe83d48b02d582be18976bc7e96c3151aa2bf1c98e9f60" +dependencies = [ + "arrayvec 0.7.2", + "bitvec", + "ff", + "group", + "halo2_proofs", + "lazy_static", + "pasta_curves", + "rand 0.8.5", + "subtle", + "uint", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd 1.0.0", + "ff", + "group", + "pasta_curves", + "rand_core 0.6.3", + "rayon", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hdwallet" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd89bf343be18dbe1e505100e48168bbd084760e842a8fed0317d2361470193" +dependencies = [ + "lazy_static", + "rand_core 0.6.3", + "ring", + "secp256k1", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "http" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "hyper" +version = "0.14.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "incrementalmerkletree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "068c5bdd31006d55536655cf1eb0d22d84d28de7c725b419480fd5d005c83216" +dependencies = [ + "serde", +] + +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "ipnet" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c" + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "js-sys" +version = "0.3.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381", + "ff", + "group", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" + +[[package]] +name = "libm" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" + +[[package]] +name = "librustzcash" +version = "0.2.0" +dependencies = [ + "anyhow", + "backtrace", + "bellman", + "blake2b_simd 1.0.0", + "blake2s_simd", + "bls12_381", + "byteorder", + "clearscreen", + "ed25519-zebra", + "group", + "gumdrop", + "incrementalmerkletree", + "ipnet", + "jubjub", + "libc", + "memuse", + "metrics", + "metrics-exporter-prometheus", + "nonempty", + "orchard", + "rand 0.8.5", + "rand_core 0.6.3", + "secp256k1", + "secrecy", + "subtle", + "thiserror", + "time", + "tracing", + "tracing-appender", + "tracing-core", + "tracing-subscriber", + "zcash_address", + "zcash_encoding", + "zcash_history", + "zcash_note_encryption", + "zcash_primitives", + "zcash_proofs", + "zeroize", +] + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memuse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f69d25cd7528769ad3d897e99eb942774bff8b23165012af490351a44c5b583b" +dependencies = [ + "nonempty", +] + +[[package]] +name = "metrics" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55586aa936c35f34ba8aa5d97356d554311206e1ce1f9e68fe7b07288e5ad827" +dependencies = [ + "ahash", + "metrics-macros", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343a5ceb38235928e7a5687412590f07e6d281522dcd9ff51246f8856eef5fe5" +dependencies = [ + "hyper", + "ipnet", + "metrics", + "metrics-util", + "parking_lot", + "quanta", + "thiserror", + "tokio", +] + +[[package]] +name = "metrics-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0daa0ab3a0ae956d0e2c1f42511422850e577d36a255357d1a7d08d45ee3a2f1" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "metrics-util" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1174223789e331d9d47a4a953dac36e397db60fa8d2a111ac505388c6c7fe32e" +dependencies = [ + "ahash", + "aho-corasick", + "atomic-shim", + "crossbeam-epoch", + "crossbeam-utils", + "dashmap", + "hashbrown", + "indexmap", + "metrics", + "num_cpus", + "ordered-float", + "parking_lot", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "5.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +dependencies = [ + "memchr", + "version_check", +] + +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "ntapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "orchard" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f918076e191a68d55c5517a16e075ecfe58fc63ed112408263f3d6194597bfcf" +dependencies = [ + "aes", + "bitvec", + "blake2b_simd 1.0.0", + "ff", + "fpe", + "group", + "halo2_gadgets", + "halo2_proofs", + "hex", + "incrementalmerkletree", + "lazy_static", + "memuse", + "nonempty", + "pasta_curves", + "rand 0.8.5", + "reddsa", + "serde", + "subtle", + "zcash_note_encryption", +] + +[[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits", +] + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group", +] + +[[package]] +name = "parity-scale-codec" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b44461635bbb1a0300f100a841e571e7d919c81c73075ef5d152ffdb521066" +dependencies = [ + "arrayvec 0.7.2", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c45ed1f39709f5a89338fab50e59816b2e8815f5bb58276e7ddf9afd495f73f8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "password-hash" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" +dependencies = [ + "base64ct", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369d7785168ad7ff0cbe467d968ca3e19a927d8536b11ef9c21b4e454b15ba42" +dependencies = [ + "blake2b_simd 1.0.0", + "ff", + "group", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pbkdf2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +dependencies = [ + "crypto-mac", + "password-hash", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared", + "rand 0.7.3", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quanta" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" +dependencies = [ + "crossbeam-utils", + "libc", + "mach", + "once_cell", + "raw-cpuid", + "wasi 0.10.2+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.6", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-cpuid" +version = "10.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738bc47119e3eeccc7e94c4a506901aea5e7b4944ecd0829cbebf4af04ceda12" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "reddsa" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc8038c8b7e481bdf688d0585d4897ed0e9e0cee10aa365dde51238c20e4182" +dependencies = [ + "blake2b_simd 1.0.0", + "byteorder", + "group", + "jubjub", + "pasta_curves", + "rand_core 0.6.3", + "serde", + "thiserror", + "zeroize", +] + +[[package]] +name = "redox_syscall" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.6", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "ripemd" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1facec54cb5e0dc08553501fa740091086d0259ad0067e0d4103448e4cb22ed3" +dependencies = [ + "digest 0.10.3", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "secp256k1" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c42e6f1735c5f00f51e43e28d6634141f2bcad10931b2609ddd74a86d751260" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "sketches-ddsketch" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a77a8fd93886010f05e7ea0720e569d6d16c65329dbe3ec033bbbccccb017b" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "terminfo" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76971977e6121664ec1b960d1313aacfa75642adc93b9d4d53b247bd4cb1747e" +dependencies = [ + "dirs", + "fnv", + "nom", + "phf", + "phf_codegen", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +dependencies = [ + "itoa", + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "winapi", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9df98b037d039d03400d9dd06b0f8ce05486b5f25e9a2d7d36196e142ebbc52" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "thread_local", + "time", + "tracing", + "tracing-core", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uint" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" + +[[package]] +name = "web-sys" +version = "0.3.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +dependencies = [ + "tap", +] + +[[package]] +name = "zcash_address" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1322a31b757f0087f110cc4a85dc5c6ccf83d0533bac04c4d3d1ce9112cc602" +dependencies = [ + "bech32", + "bs58", + "f4jumble", + "zcash_encoding", +] + +[[package]] +name = "zcash_encoding" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb61ea88eb539bc0ac2068e5da99411dd4978595b3d7ff6a4b1562ddc8e8710" +dependencies = [ + "byteorder", + "nonempty", +] + +[[package]] +name = "zcash_history" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb611a28a4e13ac715ee712f4344d6b279b767daf6345dafefb2c4bf582b6679" +dependencies = [ + "blake2b_simd 1.0.0", + "byteorder", + "primitive-types", +] + +[[package]] +name = "zcash_note_encryption" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33f84ae538f05a8ac74c82527f06b77045ed9553a0871d9db036166a4c344e3a" +dependencies = [ + "chacha20", + "chacha20poly1305", + "rand_core 0.6.3", + "subtle", +] + +[[package]] +name = "zcash_primitives" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb1ef5719fb24b42450dcd6b10e6155793be5668f0d962ad8132b6e4d108635" +dependencies = [ + "aes", + "bip0039", + "bitvec", + "blake2b_simd 1.0.0", + "blake2s_simd", + "bls12_381", + "bs58", + "byteorder", + "chacha20poly1305", + "equihash", + "ff", + "fpe", + "group", + "hdwallet", + "hex", + "incrementalmerkletree", + "jubjub", + "lazy_static", + "memuse", + "nonempty", + "orchard", + "rand 0.8.5", + "rand_core 0.6.3", + "ripemd", + "secp256k1", + "sha2", + "subtle", + "zcash_encoding", + "zcash_note_encryption", +] + +[[package]] +name = "zcash_proofs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67054525b4897a97386ce562240f08ac9bcad07183130fe8d797224d712112d" +dependencies = [ + "bellman", + "blake2b_simd 1.0.0", + "bls12_381", + "byteorder", + "directories", + "ff", + "group", + "jubjub", + "lazy_static", + "rand_core 0.6.3", + "zcash_primitives", +] + +[[package]] +name = "zeroize" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/depend/zcash/INSTALL b/depend/zcash/INSTALL new file mode 100644 index 000000000..eecfe36e1 --- /dev/null +++ b/depend/zcash/INSTALL @@ -0,0 +1,5 @@ +Building Zcash + +See the Zcash documentation wiki (https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html) for instructions on building zcashd, +the intended-for-services, no-graphical-interface, reference +implementation of Zcash. diff --git a/depend/zcash/Makefile.am b/depend/zcash/Makefile.am new file mode 100644 index 000000000..d5a8eac63 --- /dev/null +++ b/depend/zcash/Makefile.am @@ -0,0 +1,176 @@ +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Pattern rule to print variables, e.g. make print-top_srcdir +print-%: + @echo $* = $($*) + +ACLOCAL_AMFLAGS = -I build-aux/m4 +SUBDIRS = src +if ENABLE_MAN +SUBDIRS += doc/man +endif +.PHONY: deploy FORCE + +GZIP_ENV="-9n" + +if BUILD_BITCOIN_LIBS +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libzcash_script.pc +endif + +BITCOIND_BIN=$(top_builddir)/src/$(BITCOIN_DAEMON_NAME)$(EXEEXT) +BITCOIN_CLI_BIN=$(top_builddir)/src/$(BITCOIN_CLI_NAME)$(EXEEXT) + +DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) + +BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ + $(top_srcdir)/contrib/devtools/security-check.py + +COVERAGE_INFO = baseline_filtered_combined.info baseline.info \ + leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ + baseline_filtered.info \ + leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info \ + zcash-gtest.info zcash-gtest_filtered.info zcash-gtest_coverage.info + +dist-hook: + -$(GIT) archive --format=tar HEAD -- src/clientversion.cpp | $(AMTAR) -C $(top_distdir) -xf - + +$(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE + $(MAKE) -C src $(patsubst src/%,%,$@) + +$(BITCOIND_BIN): FORCE + $(MAKE) -C src $(@F) + +$(BITCOIN_CLI_BIN): FORCE + $(MAKE) -C src $(@F) + +check-security: FORCE + $(MAKE) -C src check-security + +check-symbols: FORCE + $(MAKE) -C src check-symbols + +if USE_LCOV + +baseline.info: + $(LCOV) -c -i -d $(abs_builddir)/src -o $@ + +baseline_filtered.info: baseline.info + $(LCOV) -r $< "/usr/include/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ + +leveldb_baseline.info: baseline_filtered.info + $(LCOV) -c -i -d $(abs_builddir)/src/leveldb -b $(abs_builddir)/src/leveldb -o $@ + +leveldb_baseline_filtered.info: leveldb_baseline.info + $(LCOV) -r $< "/usr/include/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ + +baseline_filtered_combined.info: leveldb_baseline_filtered.info baseline_filtered.info + $(LCOV) -a leveldb_baseline_filtered.info -a baseline_filtered.info -o $@ + +test_bitcoin.info: baseline_filtered_combined.info + $(MAKE) -C src/ bitcoin_test_check + $(LCOV) -c -d $(abs_builddir)/src -t test_bitcoin -o $@ + $(LCOV) -z -d $(abs_builddir)/src + $(LCOV) -z -d $(abs_builddir)/src/leveldb + +test_bitcoin_filtered.info: test_bitcoin.info + $(LCOV) -r $< "/usr/include/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ + +zcash-gtest.info: baseline_filtered_combined.info + $(MAKE) -C src/ zcash-gtest_check + $(LCOV) -c -d $(abs_builddir)/src -t zcash-gtest -o $@ + $(LCOV) -z -d $(abs_builddir)/src + $(LCOV) -z -d $(abs_builddir)/src/leveldb + +zcash-gtest_filtered.info: zcash-gtest.info + $(LCOV) -r $< "/usr/include/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/*.h" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/boost/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gmock/*" \ + "$(abs_builddir)/depends/x86_64-pc-linux-gnu/include/gtest/*" \ + "$(abs_builddir)/src/gtest/*" \ + "$(abs_builddir)/src/test/*" \ + "$(abs_builddir)/src/wallet/gtest/*" \ + "$(abs_builddir)/src/wallet/test/*" \ + -o $@ + +test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ + +zcash-gtest_coverage.info: baseline_filtered_combined.info zcash-gtest_filtered.info + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a zcash-gtest_filtered.info -o $@ + +total_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info zcash-gtest_filtered.info + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -a zcash-gtest_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt + +test_bitcoin.coverage/.dirstamp: test_bitcoin_coverage.info + $(GENHTML) -s $< -o $(@D) + @touch $@ + +zcash-gtest.coverage/.dirstamp: zcash-gtest_coverage.info + $(GENHTML) -s $< -o $(@D) + @touch $@ + +cov-zcash: zcash-gtest.coverage/.dirstamp + +total.coverage/.dirstamp: total_coverage.info + $(GENHTML) -s $< -o $(@D) + @touch $@ + +cov: test_bitcoin.coverage/.dirstamp cov-zcash total.coverage/.dirstamp + +endif + +dist_bin_SCRIPTS = zcutil/fetch-params.sh +dist_noinst_SCRIPTS = autogen.sh zcutil/build-debian-package.sh zcutil/build.sh + +RUST_DIST = $(top_srcdir)/.cargo $(top_srcdir)/Cargo.toml $(top_srcdir)/Cargo.lock rust-toolchain + +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests qa/zcash $(DIST_DOCS) $(BIN_CHECKS) $(RUST_DIST) + +install-exec-hook: + mv $(DESTDIR)$(bindir)/fetch-params.sh $(DESTDIR)$(bindir)/zcash-fetch-params + +.INTERMEDIATE: $(COVERAGE_INFO) + +DISTCHECK_CONFIGURE_FLAGS = --enable-man + +clean-local: + rm -rf test_bitcoin.coverage/ zcash-gtest.coverage/ total.coverage/ + rm -rf afl-temp + rm -rf qa/pull-tester/__pycache__ + +distclean-local: + rm -f zcutil/bin/db_* + rmdir zcutil/bin 2>/dev/null || true diff --git a/depend/zcash/README.md b/depend/zcash/README.md new file mode 100644 index 000000000..016b0b7a2 --- /dev/null +++ b/depend/zcash/README.md @@ -0,0 +1,66 @@ +Zcash 5.0.0 + +=========== + +What is Zcash? +-------------- + +[Zcash](https://z.cash/) is an implementation of the "Zerocash" protocol. +Based on Bitcoin's code, Zcash intends to offer a far higher standard of privacy +through a sophisticated zero-knowledge proving scheme that preserves +confidentiality of transaction metadata. More technical details are available +in our [Protocol Specification](https://zips.z.cash/protocol/protocol.pdf). + +This software is the Zcash client. It downloads and stores the entire history +of Zcash transactions; depending on the speed of your computer and network +connection, the synchronization process could take a day or more once the +blockchain has reached a significant size. + +

+ +

+ +#### :lock: Security Warnings + +See important security warnings on the +[Security Information page](https://z.cash/support/security/). + +**Zcash is experimental and a work in progress.** Use it at your own risk. + +#### :ledger: Deprecation Policy + +This release is considered deprecated 16 weeks after the release day. There +is an automatic deprecation shutdown feature which will halt the node some +time after this 16-week period. The automatic feature is based on block +height. + +## Getting Started + +Please see our [user guide](https://zcash.readthedocs.io/en/latest/rtd_pages/rtd_docs/user_guide.html) for joining the main Zcash network. + +### Need Help? + +* :blue_book: See the documentation at the [ReadTheDocs](https://zcash.readthedocs.io) + for help and more information. +* :incoming_envelope: Ask for help on the [Zcash](https://forum.z.cash/) forum. +* :speech_balloon: Join our community on [Discord](https://discordapp.com/invite/PhJY6Pm) + +Participation in the Zcash project is subject to a +[Code of Conduct](code_of_conduct.md). + +### Building + +Build Zcash along with most dependencies from source by running the following command: + +``` +./zcutil/build.sh -j$(nproc) +``` + +Currently, Zcash is only officially supported on Debian and Ubuntu. See the +[Debian / Ubuntu build](https://zcash.readthedocs.io/en/latest/rtd_pages/Debian-Ubuntu-build.html) +for detailed instructions. + +License +------- + +For license information see the file [COPYING](COPYING). diff --git a/depend/zcash/SECURITY.md b/depend/zcash/SECURITY.md new file mode 100644 index 000000000..22f991c92 --- /dev/null +++ b/depend/zcash/SECURITY.md @@ -0,0 +1,66 @@ +This page is copyright The Electric Coin Company, 2019. It is posted in order to conform to this standard: https://github.com/RD-Crypto-Spec/Responsible-Disclosure/tree/d47a5a3dafa5942c8849a93441745fdd186731e6 + +# Security Disclosures +## Receiving Disclosures + +The Electric Coin Company is committed to working with researchers who submit security vulnerability notifications to us to resolve those issues on an appropriate timeline and perform a coordinated release, giving credit to the reporter if they would like. + +Please submit issues to security@z.cash, using the following PGP key: + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBFaegcoBCAC+G82ZBYYm1GoVn4dKa0WiLYD/Q+BuU89PS1X7A4eOOy8g9yS4 +wJKMzB0AxFsH/t85P7pPZwHw3i2gmiJKeIqEGhEBL08D3id2u6ZyCnwDuWs0i6My +MXWTwK5shvE61ZI/KPbjemoOG6MPF5QdrouNqei2Vk+4RjbRCyyS0A59GQi2dNZX +BMwTnHnUZ5qi6T0RFelqJ3dE5Nc/UwJPdAcg71c3b3dMOHjaDBMPB6+fTLBeidV6 +5B72nGO3eIYkMUNj+qCQmM/esRkmGmlDH/9WGMBOKCq7Yw3LyEoPOi5cba1m8SN2 +xFlNzkUGrlVrwZMF+1UdjvN7BGDypA3Dr/STABEBAAG0JVpjYXNoIFNlY3VyaXR5 +IFRlYW0gPHNlY3VyaXR5QHouY2FzaD6JATcEEwEIACEFAlaegcoCGwMFCwkIBwIG +FQgJCgsCBBYCAwECHgECF4AACgkQiPuLhti1poxlRAf/bZ6fhUby5bAbViAO4TzQ +yfbD0ksGeF8MHicPz7HqOYuXAE9GrKnVAOFptwRo94O+iRC5aXhW8OAP+38IWorv +gsAuag7Y8k0nlfNdrJRqqJpjyxtiuv+cd2o5dre8E9PVNE5IPv9qEJA4Zag3snmC +a+O4HAqKeXYddunFq2drLkTRlOwuFkGXJzwi3VSNVYCuuGyezFDuaD45ltmsXgid +jZSdnnc6L1BrEd9LVzahvFV0+fT4bNKQHQDk+f0RTnHed+m9NqAoC9K8ftPTQ/i4 +5+W/dXJATztWDrJ7ZevHXGR+RAhMNsT1psvnQsJzMkUz1GMdQOtk4PfuZLGSIiTM +ErkBDQRWnoHKAQgAp+w+xsPJWFdadE6Ok1aZC0Lk1J9xU/cqX1aBlkwi5SynwOkV +Eg1xNHLJMelp13bgDjLRsvaMbsseaCVk3goNln4atNbZpqz6FoM/f8pJx52LFD0j +CFFOVUlGEF0h+KdFr+3JHI+mg+3ifXTD4Dajj4lpu8kR/FQjftcxyttByz01wLRO +sK5BDC856WzHXAJuX6TpX4sGJujzKoLXR5V0SkUopqn9g4aJGnWuNh4kyOQI6fd7 +YZyPZhWDrXdgInCKAKAgq8r6hgSDMYFvmflp6+reCfeOe1VFF8q3Foio02YPIrQW +WjjH0w6nOvOKCEtxistz1sP6ZoYq4gR41LOwIQARAQABiQEfBBgBCAAJBQJWnoHK +AhsMAAoJEIj7i4bYtaaMiA4IALIy4xP/Btu86yT3b53t8cfYZddFSO8Nlg+y3EMu +1LchdSOpWgpXCvQ7d4ndWGsuBSmQ+jaRwU2UIkq2iIxf5cg63dJz9grAcF6MXCrO +t5BSowFC4m3RFaEaG6G6SjDVIA0ZEdEMFd9Gzc1ikqbVLyNuJXKmzz0evvbAJgVO +D0nht5ifwLjQxM4olvYHUwtT0wPhniH69ghFo8LQiMgncjaukDzbgANiuj07QYy/ +DlzhQUsp1qZvqZnVKqUJ3lFb86b6zoqoRNiUnvP9JB2v3kLG0T39UlcXUFnZJ/4H +CDHCrwSovQRMHtoOWZijBNobO2y1d0FkUpzNlNw44Ssw0Vo= +=6GYS +-----END PGP PUBLIC KEY BLOCK----- +``` + +## Sending Disclosures + +In the case where we become aware of security issues affecting other projects that has never affected Zcash, our intention is to inform those projects of security issues on a best effort basis. + +In the case where we fix a security issue in Zcash that also affects the following neighboring projects, our intention is to engage in responsible disclosures with them as described in https://github.com/RD-Crypto-Spec/Responsible-Disclosure, subject to the deviations described in the section at the bottom of this document. + +## Bilateral Responsible Disclosure Agreements + +We have set up agreements with the following neighboring projects to share vulnerability information, subject to the deviations described in the next section. + +Specifically, we have agreed to engage in responsible disclosures for security issues affecting this repository with the following contacts: + +- Zcash Foundation https://github.com/ZcashFoundation/zebra/security/policy +- Horizen security@horizen.com via PGP +- Komodo ca333@komodoplatform.com via PGP +- BitcoinABC https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/DISCLOSURE_POLICY.md + +## Deviations from the Standard + +Zcash is a technology that provides strong privacy. Notes are encrypted to their destination, and then the monetary base is kept via zero-knowledge proofs intended to only be creatable by the real holder of Zcash. If this fails, and a counterfeiting bug results, that counterfeiting bug might be exploited without any way for blockchain analyzers to identify the perpetrator or which data in the blockchain has been used to exploit the bug. Rollbacks before that point, such as have been executed in some other projects in such cases, are therefore impossible. + +The standard describes reporters of vulnerabilities including full details of an issue, in order to reproduce it. This is necessary for instance in the case of an external researcher both demonstrating and proving that there really is a security issue, and that security issue really has the impact that they say it has - allowing the development team to accurately prioritize and resolve the issue. + +In the case of a counterfeiting bug, however, just like in CVE-2019-7167, we might decide not to include those details with our reports to partners ahead of coordinated release, so long as we are sure that they are vulnerable. + diff --git a/depend/zcash/autogen.sh b/depend/zcash/autogen.sh new file mode 100755 index 000000000..69a20dc46 --- /dev/null +++ b/depend/zcash/autogen.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +export LC_ALL=C +set -e +srcdir="$(dirname $0)" +cd "$srcdir" +if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="$(command -v glibtoolize)"; then + LIBTOOLIZE="${GLIBTOOLIZE}" + export LIBTOOLIZE +fi +autoreconf --install --force --warnings=all diff --git a/depend/zcash/build-aux/m4/ax_boost_base.m4 b/depend/zcash/build-aux/m4/ax_boost_base.m4 new file mode 100644 index 000000000..296e05558 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_base.m4 @@ -0,0 +1,291 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# DESCRIPTION +# +# Test for the Boost C++ libraries of a particular version (or newer) +# +# If no path to the installed boost library is given the macro searches +# under /usr, /usr/local, /opt and /opt/local and evaluates the +# $BOOST_ROOT environment variable. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) +# +# And sets: +# +# HAVE_BOOST +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2009 Peter Adolphs +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 26 + +AC_DEFUN([AX_BOOST_BASE], +[ +AC_ARG_WITH([boost], + [AS_HELP_STRING([--with-boost@<:@=ARG@:>@], + [use Boost library from a standard location (ARG=yes), + from the specified location (ARG=), + or disable it (ARG=no) + @<:@ARG=yes@:>@ ])], + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ac_boost_path="" + else + want_boost="yes" + ac_boost_path="$withval" + fi + ], + [want_boost="yes"]) + + +AC_ARG_WITH([boost-libdir], + AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), + [ + if test -d "$withval" + then + ac_boost_lib_path="$withval" + else + AC_MSG_ERROR(--with-boost-libdir expected directory name) + fi + ], + [ac_boost_lib_path=""] +) + +if test "x$want_boost" = "xyes"; then + boost_lib_version_req=ifelse([$1], ,1.20.0,$1) + boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` + boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` + boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` + boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + if test "x$boost_lib_version_req_sub_minor" = "x" ; then + boost_lib_version_req_sub_minor="0" + fi + WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` + AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) + succeeded=no + + dnl On 64-bit systems check for system libraries in both lib64 and lib. + dnl The former is specified by FHS, but e.g. Debian does not adhere to + dnl this (as it rises problems for generic multi-arch support). + dnl The last entry in the list is chosen by default when no libraries + dnl are found, e.g. when only header-only libraries are installed! + libsubdirs="lib" + ax_arch=`uname -m` + case $ax_arch in + x86_64) + libsubdirs="lib64 libx32 lib lib64" + ;; + ppc64|s390x|sparc64|aarch64|ppc64le) + libsubdirs="lib64 lib lib64 ppc64le" + ;; + esac + + dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give + dnl them priority over the other paths since, if libs are found there, they + dnl are almost assuredly the ones desired. + AC_REQUIRE([AC_CANONICAL_HOST]) + libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs" + + case ${host_cpu} in + i?86) + libsubdirs="lib/i386-${host_os} $libsubdirs" + ;; + esac + + dnl some arches may advertise a cpu type that doesn't line up with their + dnl prefix's cpu type. For example, uname may report armv7l while libs are + dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's + dnl value for an extra chance of finding the correct path. + libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" + + dnl first we check the system location for boost libraries + dnl this location is chosen if boost libraries are installed with the --layout=system option + dnl or if you install boost with RPM + if test "$ac_boost_path" != ""; then + BOOST_CPPFLAGS="-I$ac_boost_path/include" + for ac_boost_path_tmp in $libsubdirs; do + if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then + BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" + break + fi + done + elif test "$cross_compiling" != yes; then + for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then + for libsubdir in $libsubdirs ; do + if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" + BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + break; + fi + done + fi + + dnl overwrite ld flags if we have required special directory with + dnl --with-boost-libdir parameter + if test "$ac_boost_lib_path" != ""; then + BOOST_LDFLAGS="-L$ac_boost_lib_path" + fi + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_REQUIRE([AC_PROG_CXX]) + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + + + + dnl if we found no boost with system layout we search for boost libraries + dnl built and installed without the --layout=system option or for a staged(not installed) version + if test "x$succeeded" != "xyes"; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + BOOST_LDFLAGS= + _version=0 + if test "$ac_boost_path" != ""; then + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + fi + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" + done + dnl if nothing found search for layout used in Windows distributions + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$ac_boost_path/boost" && test -r "$ac_boost_path/boost"; then + BOOST_CPPFLAGS="-I$ac_boost_path" + fi + fi + fi + else + if test "$cross_compiling" != yes; then + for ac_boost_path in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + best_path=$ac_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + if test "$ac_boost_lib_path" = ""; then + for libsubdir in $libsubdirs ; do + if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + BOOST_LDFLAGS="-L$best_path/$libsubdir" + fi + fi + + if test "x$BOOST_ROOT" != "x"; then + for libsubdir in $libsubdirs ; do + if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi + done + if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then + version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` + stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` + stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` + V_CHECK=`expr $stage_version_shorten \>\= $_version` + if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then + AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) + BOOST_CPPFLAGS="-I$BOOST_ROOT" + BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + fi + fi + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ],[ + ]) + AC_LANG_POP([C++]) + fi + + if test "$succeeded" != "yes" ; then + if test "$_version" = "0" ; then + AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) + else + AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).]) + fi + # execute ACTION-IF-NOT-FOUND (if present): + ifelse([$3], , :, [$3]) + else + AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_LDFLAGS) + AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) + # execute ACTION-IF-FOUND (if present): + ifelse([$2], , :, [$2]) + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" +fi + +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_chrono.m4 b/depend/zcash/build-aux/m4/ax_boost_chrono.m4 new file mode 100644 index 000000000..318ecea17 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_chrono.m4 @@ -0,0 +1,119 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_CHRONO +# +# DESCRIPTION +# +# Test for System library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_CHRONO_LIB) +# +# And sets: +# +# HAVE_BOOST_CHRONO +# +# LICENSE +# +# Copyright (c) 2012 Xiyue Deng +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +AC_DEFUN([AX_BOOST_CHRONO], +[ + AC_ARG_WITH([boost-chrono], + AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@], + [use the Chrono library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-chrono=boost_chrono-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_chrono_lib="" + else + want_boost="yes" + ax_boost_user_chrono_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Chrono library is available, + ax_cv_boost_chrono, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[boost::chrono::system_clock::time_point time;]])], + ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_chrono" = "xyes"; then + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + if test "x$ax_boost_user_chrono_lib" = "x"; then + ax_lib= + for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], + [link_chrono="no"]) + done + if test "x$link_chrono" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], + [link_chrono="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], + [link_chrono="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_chrono library!) + fi + if test "x$link_chrono" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_filesystem.m4 b/depend/zcash/build-aux/m4/ax_boost_filesystem.m4 new file mode 100644 index 000000000..f5c9d5647 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_filesystem.m4 @@ -0,0 +1,119 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_FILESYSTEM +# +# DESCRIPTION +# +# Test for Filesystem library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_FILESYSTEM_LIB) +# +# And sets: +# +# HAVE_BOOST_FILESYSTEM +# +# LICENSE +# +# Copyright (c) 2009 Thomas Porschberg +# Copyright (c) 2009 Michael Tindal +# Copyright (c) 2009 Roman Rybalko +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 26 + +AC_DEFUN([AX_BOOST_FILESYSTEM], +[ + AC_ARG_WITH([boost-filesystem], + AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@], + [use the Filesystem library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_filesystem_lib="" + else + want_boost="yes" + ax_boost_user_filesystem_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + LIBS_SAVED=$LIBS + LIBS="$LIBS $BOOST_SYSTEM_LIB" + export LIBS + + AC_CACHE_CHECK(whether the Boost::Filesystem library is available, + ax_cv_boost_filesystem, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[using namespace boost::filesystem; + path my_path( "foo/bar/data.txt" ); + return 0;]])], + ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no) + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_filesystem" = "xyes"; then + AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + ax_lib= + if test "x$ax_boost_user_filesystem_lib" = "x"; then + for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], + [link_filesystem="no"]) + done + if test "x$link_filesystem" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_filesystem* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], + [link_filesystem="no"]) + done + fi + else + for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], + [link_filesystem="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_filesystem library!) + fi + if test "x$link_filesystem" != "xyes"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + LIBS="$LIBS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_program_options.m4 b/depend/zcash/build-aux/m4/ax_boost_program_options.m4 new file mode 100644 index 000000000..2bdb59371 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_program_options.m4 @@ -0,0 +1,108 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_BOOST_PROGRAM_OPTIONS +# +# DESCRIPTION +# +# Test for program options library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. Further documentation is +# available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) +# +# And sets: +# +# HAVE_BOOST_PROGRAM_OPTIONS +# +# LICENSE +# +# Copyright (c) 2009 Thomas Porschberg +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 24 + +AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], +[ + AC_ARG_WITH([boost-program-options], + AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@], + [use the program options library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_program_options_lib="" + else + want_boost="yes" + ax_boost_user_program_options_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + export want_boost + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + AC_CACHE_CHECK([whether the Boost::Program_Options library is available], + ax_cv_boost_program_options, + [AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include + ]], + [[boost::program_options::error err("Error message"); + return 0;]])], + ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no) + AC_LANG_POP([C++]) + ]) + if test "$ax_cv_boost_program_options" = yes; then + AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + if test "x$ax_boost_user_program_options_lib" = "x"; then + for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.dylib* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.dylib.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], + [link_program_options="no"]) + done + if test "x$link_program_options" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_program_options*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], + [link_program_options="no"]) + done + fi + else + for ax_lib in $ax_boost_user_program_options_lib boost_program_options-$ax_boost_user_program_options_lib; do + AC_CHECK_LIB($ax_lib, main, + [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], + [link_program_options="no"]) + done + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_program_options library!) + fi + if test "x$link_program_options" != "xyes"; then + AC_MSG_ERROR([Could not link against [$ax_lib] !]) + fi + fi + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_system.m4 b/depend/zcash/build-aux/m4/ax_boost_system.m4 new file mode 100644 index 000000000..1c05450cb --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_system.m4 @@ -0,0 +1,122 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_system.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_SYSTEM +# +# DESCRIPTION +# +# Test for System library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_SYSTEM_LIB) +# +# And sets: +# +# HAVE_BOOST_SYSTEM +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Daniel Casimiro +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 18 + +AC_DEFUN([AX_BOOST_SYSTEM], +[ + AC_ARG_WITH([boost-system], + AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@], + [use the System library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-system=boost_system-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_system_lib="" + else + want_boost="yes" + ax_boost_user_system_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::System library is available, + ax_cv_boost_system, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS= + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[boost::system::error_category *a = 0;]])], + ax_cv_boost_system=yes, ax_cv_boost_system=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_system" = "xyes"; then + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + if test "x$ax_boost_user_system_lib" = "x"; then + ax_lib= + for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + if test "x$link_system" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], + [link_system="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_system library!) + fi + if test "x$link_system" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_thread.m4 b/depend/zcash/build-aux/m4/ax_boost_thread.m4 new file mode 100644 index 000000000..9f0bd0b23 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_thread.m4 @@ -0,0 +1,150 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_THREAD +# +# DESCRIPTION +# +# Test for Thread library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. Further documentation is available at +# . +# +# This macro calls: +# +# AC_SUBST(BOOST_THREAD_LIB) +# +# And sets: +# +# HAVE_BOOST_THREAD +# +# LICENSE +# +# Copyright (c) 2009 Thomas Porschberg +# Copyright (c) 2009 Michael Tindal +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 27 + +AC_DEFUN([AX_BOOST_THREAD], +[ + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_thread_lib="" + else + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_BUILD]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Thread library is available, + ax_cv_boost_thread, + [AC_LANG_PUSH([C++]) + CXXFLAGS_SAVE=$CXXFLAGS + + if test "x$host_os" = "xsolaris" ; then + CXXFLAGS="-pthreads $CXXFLAGS" + elif test "x$host_os" = "xmingw32" ; then + CXXFLAGS="-mthreads $CXXFLAGS" + else + CXXFLAGS="-pthread $CXXFLAGS" + fi + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[boost::thread_group thrds; + return 0;]])], + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + if test "x$host_os" = "xsolaris" ; then + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + elif test "x$host_os" = "xmingw32" ; then + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + else + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + fi + + AC_SUBST(BOOST_CPPFLAGS) + + AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + LDFLAGS_SAVE=$LDFLAGS + case "x$host_os" in + *bsd* ) + LDFLAGS="-pthread $LDFLAGS" + break; + ;; + esac + if test "x$ax_boost_user_thread_lib" = "x"; then + ax_lib= + for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + if test "x$link_thread" != "xyes"; then + for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + fi + + else + for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do + AC_CHECK_LIB($ax_lib, exit, + [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + [link_thread="no"]) + done + + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_thread library!) + fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + case "x$host_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + esac + + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_boost_unit_test_framework.m4 b/depend/zcash/build-aux/m4/ax_boost_unit_test_framework.m4 new file mode 100644 index 000000000..4efd1e2f1 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_boost_unit_test_framework.m4 @@ -0,0 +1,138 @@ +# ================================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_boost_unit_test_framework.html +# ================================================================================ +# +# SYNOPSIS +# +# AX_BOOST_UNIT_TEST_FRAMEWORK +# +# DESCRIPTION +# +# Test for Unit_Test_Framework library from the Boost C++ libraries. The +# macro requires a preceding call to AX_BOOST_BASE. Further documentation +# is available at . +# +# This macro calls: +# +# AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) +# +# And sets: +# +# HAVE_BOOST_UNIT_TEST_FRAMEWORK +# +# LICENSE +# +# Copyright (c) 2008 Thomas Porschberg +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 19 + +AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], +[ + AC_ARG_WITH([boost-unit-test-framework], + AS_HELP_STRING([--with-boost-unit-test-framework@<:@=special-lib@:>@], + [use the Unit_Test_Framework library from boost - it is possible to specify a certain library for the linker + e.g. --with-boost-unit-test-framework=boost_unit_test_framework-gcc ]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_unit_test_framework_lib="" + else + want_boost="yes" + ax_boost_user_unit_test_framework_lib="$withval" + fi + ], + [want_boost="yes"] + ) + + if test "x$want_boost" = "xyes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_CACHE_CHECK(whether the Boost::Unit_Test_Framework library is available, + ax_cv_boost_unit_test_framework, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], + [[using boost::unit_test::test_suite; + test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); return 0;]])], + ax_cv_boost_unit_test_framework=yes, ax_cv_boost_unit_test_framework=no) + AC_LANG_POP([C++]) + ]) + if test "x$ax_cv_boost_unit_test_framework" = "xyes"; then + AC_DEFINE(HAVE_BOOST_UNIT_TEST_FRAMEWORK,,[define if the Boost::Unit_Test_Framework library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + if test "x$ax_boost_user_unit_test_framework_lib" = "x"; then + saved_ldflags="${LDFLAGS}" + ax_lib= + for monitor_library in `ls $BOOSTLIBDIR/libboost_unit_test_framework*.so* $BOOSTLIBDIR/libboost_unit_test_framework*.dylib* $BOOSTLIBDIR/libboost_unit_test_framework*.a* 2>/dev/null` ; do + if test -r $monitor_library ; then + libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a.*$;\1;'` + ax_lib=${libextension} + link_unit_test_framework="yes" + else + link_unit_test_framework="no" + fi + + if test "x$link_unit_test_framework" = "xyes"; then + BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" + AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) + break + fi + done + if test "x$link_unit_test_framework" != "xyes"; then + for libextension in `ls $BOOSTLIBDIR/boost_unit_test_framework*.dll* $BOOSTLIBDIR/boost_unit_test_framework*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_unit_test_framework.*\)\.dll.*$;\1;' -e 's;^\(boost_unit_test_framework.*\)\.a.*$;\1;'` ; do + ax_lib=${libextension} + AC_CHECK_LIB($ax_lib, exit, + [BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"; AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) link_unit_test_framework="yes"; break], + [link_unit_test_framework="no"]) + done + fi + else + link_unit_test_framework="no" + saved_ldflags="${LDFLAGS}" + for ax_lib in boost_unit_test_framework-$ax_boost_user_unit_test_framework_lib $ax_boost_user_unit_test_framework_lib ; do + if test "x$link_unit_test_framework" = "xyes"; then + break; + fi + for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.so* $BOOSTLIBDIR/lib${ax_lib}.a* 2>/dev/null` ; do + if test -r $unittest_library ; then + libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;'` + ax_lib=${libextension} + link_unit_test_framework="yes" + else + link_unit_test_framework="no" + fi + + if test "x$link_unit_test_framework" = "xyes"; then + BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" + AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) + break + fi + done + done + fi + if test "x$ax_lib" = "x"; then + AC_MSG_ERROR(Could not find a version of the boost_unit_test_framework library!) + fi + if test "x$link_unit_test_framework" != "xyes"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) diff --git a/depend/zcash/build-aux/m4/ax_check_compile_flag.m4 b/depend/zcash/build-aux/m4/ax_check_compile_flag.m4 new file mode 100644 index 000000000..ca3639715 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_check_compile_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 4 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/depend/zcash/build-aux/m4/ax_check_link_flag.m4 b/depend/zcash/build-aux/m4/ax_check_link_flag.m4 new file mode 100644 index 000000000..eb01a6ce1 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 4 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/depend/zcash/build-aux/m4/ax_check_preproc_flag.m4 b/depend/zcash/build-aux/m4/ax_check_preproc_flag.m4 new file mode 100644 index 000000000..ca1d5ee2b --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_check_preproc_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's +# preprocessor or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the preprocessor's default +# flags when the check is done. The check is thus made with the flags: +# "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the +# preprocessor to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_PREPROC_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# 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 4 + +AC_DEFUN([AX_CHECK_PREPROC_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ + ax_check_save_flags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $4 $1" + AC_PREPROC_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + CPPFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_PREPROC_FLAGS diff --git a/depend/zcash/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/depend/zcash/build-aux/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000..43087b2e6 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,951 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/depend/zcash/build-aux/m4/ax_gcc_func_attribute.m4 b/depend/zcash/build-aux/m4/ax_gcc_func_attribute.m4 new file mode 100644 index 000000000..02b597357 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_gcc_func_attribute.m4 @@ -0,0 +1,223 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) +# +# DESCRIPTION +# +# This macro checks if the compiler supports one of GCC's function +# attributes; many other compilers also provide function attributes with +# the same syntax. Compiler warnings are used to detect supported +# attributes as unsupported ones are ignored by default so quieting +# warnings when using this macro will yield false positives. +# +# The ATTRIBUTE parameter holds the name of the attribute to be checked. +# +# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_. +# +# The macro caches its result in the ax_cv_have_func_attribute_ +# variable. +# +# The macro currently supports the following function attributes: +# +# alias +# aligned +# alloc_size +# always_inline +# artificial +# cold +# const +# constructor +# constructor_priority for constructor attribute with priority +# deprecated +# destructor +# dllexport +# dllimport +# error +# externally_visible +# flatten +# format +# format_arg +# gnu_inline +# hot +# ifunc +# leaf +# malloc +# noclone +# noinline +# nonnull +# noreturn +# nothrow +# optimize +# pure +# unused +# used +# visibility +# warning +# warn_unused_result +# weak +# weakref +# +# Unsupported function attributes will be tested with a prototype returning +# an int and not accepting any arguments and the result of the check might +# be wrong or meaningless so use with care. +# +# LICENSE +# +# Copyright (c) 2013 Gabriele Svelto +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ + AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) + + AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + m4_case([$1], + [alias], [ + int foo( void ) { return 0; } + int bar( void ) __attribute__(($1("foo"))); + ], + [aligned], [ + int foo( void ) __attribute__(($1(32))); + ], + [alloc_size], [ + void *foo(int a) __attribute__(($1(1))); + ], + [always_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [artificial], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [cold], [ + int foo( void ) __attribute__(($1)); + ], + [const], [ + int foo( void ) __attribute__(($1)); + ], + [constructor_priority], [ + int foo( void ) __attribute__((__constructor__(65535/2))); + ], + [constructor], [ + int foo( void ) __attribute__(($1)); + ], + [deprecated], [ + int foo( void ) __attribute__(($1(""))); + ], + [destructor], [ + int foo( void ) __attribute__(($1)); + ], + [dllexport], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [dllimport], [ + int foo( void ) __attribute__(($1)); + ], + [error], [ + int foo( void ) __attribute__(($1(""))); + ], + [externally_visible], [ + int foo( void ) __attribute__(($1)); + ], + [flatten], [ + int foo( void ) __attribute__(($1)); + ], + [format], [ + int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); + ], + [format_arg], [ + char *foo(const char *p) __attribute__(($1(1))); + ], + [gnu_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [hot], [ + int foo( void ) __attribute__(($1)); + ], + [ifunc], [ + int my_foo( void ) { return 0; } + static int (*resolve_foo(void))(void) { return my_foo; } + int foo( void ) __attribute__(($1("resolve_foo"))); + ], + [leaf], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [malloc], [ + void *foo( void ) __attribute__(($1)); + ], + [noclone], [ + int foo( void ) __attribute__(($1)); + ], + [noinline], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [nonnull], [ + int foo(char *p) __attribute__(($1(1))); + ], + [noreturn], [ + void foo( void ) __attribute__(($1)); + ], + [nothrow], [ + int foo( void ) __attribute__(($1)); + ], + [optimize], [ + __attribute__(($1(3))) int foo( void ) { return 0; } + ], + [pure], [ + int foo( void ) __attribute__(($1)); + ], + [unused], [ + int foo( void ) __attribute__(($1)); + ], + [used], [ + int foo( void ) __attribute__(($1)); + ], + [visibility], [ + int foo_def( void ) __attribute__(($1("default"))); + int foo_hid( void ) __attribute__(($1("hidden"))); + int foo_int( void ) __attribute__(($1("internal"))); + int foo_pro( void ) __attribute__(($1("protected"))); + ], + [warning], [ + int foo( void ) __attribute__(($1(""))); + ], + [warn_unused_result], [ + int foo( void ) __attribute__(($1)); + ], + [weak], [ + int foo( void ) __attribute__(($1)); + ], + [weakref], [ + static int foo( void ) { return 0; } + static int bar( void ) __attribute__(($1("foo"))); + ], + [ + m4_warn([syntax], [Unsupported attribute $1, the test may fail]) + int foo( void ) __attribute__(($1)); + ] + )], []) + ], + dnl GCC doesn't exit with an error if an unknown attribute is + dnl provided but only outputs a warning, so accept the attribute + dnl only if no warning were issued. + [AS_IF([test -s conftest.err], + [AS_VAR_SET([ac_var], [no])], + [AS_VAR_SET([ac_var], [yes])])], + [AS_VAR_SET([ac_var], [no])]) + ]) + + AS_IF([test yes = AS_VAR_GET([ac_var])], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, + [Define to 1 if the system has the `$1' function attribute])], []) + + AS_VAR_POPDEF([ac_var]) +]) diff --git a/depend/zcash/build-aux/m4/ax_pthread.m4 b/depend/zcash/build-aux/m4/ax_pthread.m4 new file mode 100644 index 000000000..d218d1af7 --- /dev/null +++ b/depend/zcash/build-aux/m4/ax_pthread.m4 @@ -0,0 +1,485 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# 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_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# 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 22 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix* | freebsd*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/depend/zcash/build-aux/m4/bitcoin_find_bdb.m4 b/depend/zcash/build-aux/m4/bitcoin_find_bdb.m4 new file mode 100644 index 000000000..e6c365271 --- /dev/null +++ b/depend/zcash/build-aux/m4/bitcoin_find_bdb.m4 @@ -0,0 +1,72 @@ +dnl Copyright (c) 2016-2019 The Zcash developers +dnl Copyright (c) 2013-2019 The Bitcoin Core developers +dnl Copyright (c) 2013-2019 Bitcoin Developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or https://www.opensource.org/licenses/mit-license.php . + +AC_DEFUN([BITCOIN_FIND_BDB62],[ + AC_MSG_CHECKING([for Berkeley DB C++ headers]) + BDB_CPPFLAGS= + BDB_LIBS= + bdbpath=X + bdb62path=X + bdbdirlist= + for _vn in 6.2 62 6 ''; do + for _pfx in b lib ''; do + bdbdirlist="$bdbdirlist ${_pfx}db${_vn}" + done + done + for searchpath in $bdbdirlist ''; do + test -n "${searchpath}" && searchpath="${searchpath}/" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !((DB_VERSION_MAJOR == 6 && DB_VERSION_MINOR >= 2) || DB_VERSION_MAJOR > 6) + #error "failed to find bdb 6.2+" + #endif + ]])],[ + if test "x$bdbpath" = "xX"; then + bdbpath="${searchpath}" + fi + ],[ + continue + ]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include <${searchpath}db_cxx.h> + ]],[[ + #if !(DB_VERSION_MAJOR == 6 && DB_VERSION_MINOR == 2) + #error "failed to find bdb 6.2" + #endif + ]])],[ + bdb62path="${searchpath}" + break + ],[]) + done + if test "x$bdbpath" = "xX"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + elif test "x$bdb62path" = "xX"; then + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdbpath}],db_cxx) + AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 6.2])],[ + AC_MSG_WARN([Found Berkeley DB other than 6.2; wallets opened by this build will not be portable!]) + ],[ + AC_MSG_ERROR([Found Berkeley DB other than 6.2, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) + ]) + else + BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb62path}],db_cxx) + bdbpath="${bdb62path}" + fi + AC_SUBST(BDB_CPPFLAGS) + + # TODO: Ideally this could find the library version and make sure it matches the headers being used + for searchlib in db_cxx-6.2 db_cxx; do + AC_CHECK_LIB([$searchlib],[main],[ + BDB_LIBS="-l${searchlib}" + break + ]) + done + if test "x$BDB_LIBS" = "x"; then + AC_MSG_ERROR([libdb_cxx missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) + fi + AC_SUBST(BDB_LIBS) +]) diff --git a/depend/zcash/build-aux/m4/bitcoin_subdir_to_include.m4 b/depend/zcash/build-aux/m4/bitcoin_subdir_to_include.m4 new file mode 100644 index 000000000..52da5ef9f --- /dev/null +++ b/depend/zcash/build-aux/m4/bitcoin_subdir_to_include.m4 @@ -0,0 +1,20 @@ +dnl Copyright (c) 2016-2019 The Zcash developers +dnl Copyright (c) 2013-2019 The Bitcoin Core developers +dnl Copyright (c) 2013-2019 Bitcoin Developers +dnl Distributed under the MIT software license, see the accompanying +dnl file COPYING or https://www.opensource.org/licenses/mit-license.php . + +dnl BITCOIN_SUBDIR_TO_INCLUDE([CPPFLAGS-VARIABLE-NAME],[SUBDIRECTORY-NAME],[HEADER-FILE]) +dnl SUBDIRECTORY-NAME must end with a path separator +AC_DEFUN([BITCOIN_SUBDIR_TO_INCLUDE],[ + if test "x$2" = "x"; then + AC_MSG_RESULT([default]) + else + echo "#include <$2$3.h>" >conftest.cpp + newinclpath=`${CXXCPP} ${CPPFLAGS} -M conftest.cpp 2>/dev/null | [ tr -d '\\n\\r\\\\' | sed -e 's/^.*[[:space:]:]\(\/[^[:space:]]*\)]$3[\.h[[:space:]].*$/\1/' -e t -e d`] + AC_MSG_RESULT([${newinclpath}]) + if test "x${newinclpath}" != "x"; then + eval "$1=\"\$$1\"' -I${newinclpath}'" + fi + fi +]) diff --git a/depend/zcash/build-aux/m4/l_atomic.m4 b/depend/zcash/build-aux/m4/l_atomic.m4 new file mode 100644 index 000000000..75c43f9a9 --- /dev/null +++ b/depend/zcash/build-aux/m4/l_atomic.m4 @@ -0,0 +1,46 @@ +dnl Copyright (c) 2015 Tim Kosse +dnl Copying and distribution of this file, with or without modification, are +dnl permitted in any medium without royalty provided the copyright notice +dnl and this notice are preserved. This file is offered as-is, without any +dnl warranty. + +# Some versions of gcc/libstdc++ require linking with -latomic if +# using the C++ atomic library. +# +# Sourced from http://bugs.debian.org/797228 + +m4_define([_CHECK_ATOMIC_testbody], [[ + #include + #include + + int main() { + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } +]]) + +AC_DEFUN([CHECK_ATOMIC], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether std::atomic can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -latomic" + AC_MSG_CHECKING([whether std::atomic needs -latomic]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure out how to use std::atomic]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/depend/zcash/code_of_conduct.md b/depend/zcash/code_of_conduct.md new file mode 100644 index 000000000..07e751de7 --- /dev/null +++ b/depend/zcash/code_of_conduct.md @@ -0,0 +1,65 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of +fostering an open and welcoming community, we pledge to respect all people who +contribute through reporting issues, posting feature requests, updating +documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free +experience for everyone, regardless of level of experience, gender, gender +identity and expression, sexual orientation, disability, personal appearance, +body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* The use of language or imagery that originates with, or has been + adopted as a symbol or "dog-whistle" for, any of: right-wing extremism, + anti-Semitism, Islamophobia, white supremacism, eugenics, homophobia, or + transphobia (whether or not the use by itself falls into those categories) +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic + addresses, without explicit permission +* Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. Note that contributors may be volunteers +who do not represent Electric Coin Company. They are free to express their own +opinions so long as they adhere to these guidelines. + +By adopting this Code of Conduct, project maintainers commit themselves to +fairly and consistently applying these principles to every aspect of managing +this project. Project maintainers who do not follow or enforce the Code of +Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting a project maintainer (see below). All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. Maintainers are +obligated to maintain confidentiality with regard to the reporter of an +incident. + +You may send reports to [our Conduct email](mailto:conduct@z.cash). + +If you wish to contact specific maintainers directly, the following have made +themselves available for conduct issues: + +- Daira Hopwood (daira at z.cash) +- Sean Bowe (sean at z.cash) + + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.3.0, available at +[https://www.contributor-covenant.org/version/1/3/0/][version] + +[homepage]: https://www.contributor-covenant.org +[version]: https://www.contributor-covenant.org/version/1/3/0/ + diff --git a/depend/zcash/configure.ac b/depend/zcash/configure.ac new file mode 100644 index 000000000..2d602f60f --- /dev/null +++ b/depend/zcash/configure.ac @@ -0,0 +1,1058 @@ +dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) +AC_PREREQ([2.60]) +define(_CLIENT_VERSION_MAJOR, 5) +define(_CLIENT_VERSION_MINOR, 0) +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))) +define(_CLIENT_VERSION_IS_RELEASE, true) +define(_COPYRIGHT_YEAR, 2022) +AC_INIT([Zcash],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_SUFFIX(_ZC_BUILD_VAL)],[https://github.com/zcash/zcash/issues],[zcash]) +AC_CONFIG_SRCDIR([src/main.cpp]) +AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([build-aux/m4]) + +BITCOIN_DAEMON_NAME=zcashd +BITCOIN_CLI_NAME=zcash-cli +BITCOIN_TX_NAME=zcash-tx + +dnl Unless the user specified ARFLAGS, force it to be cr +AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) +if test "x${ARFLAGS+set}" != "xset"; then + ARFLAGS="cr" +fi + +AC_CANONICAL_HOST + +AH_TOP([#ifndef BITCOIN_CONFIG_H]) +AH_TOP([#define BITCOIN_CONFIG_H]) +AH_BOTTOM([#endif //BITCOIN_CONFIG_H]) + +dnl faketime breaks configure and is only needed for make. Disable it here. +unset FAKETIME + +dnl Automake init set-up and checks +AM_INIT_AUTOMAKE([no-define subdir-objects foreign tar-pax]) + +dnl faketime messes with timestamps and causes configure to be re-run. +dnl --disable-maintainer-mode can be used to bypass this. +AM_MAINTAINER_MODE([enable]) + +dnl make the compilation flags quiet unless V=1 is used +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +dnl Compiler checks (here before libtool). +if test "x${CXXFLAGS+set}" = "xset"; then + CXXFLAGS_overridden=yes +else + CXXFLAGS_overridden=no +fi + +AC_PROG_CXX +m4_ifdef([AC_PROG_OBJCXX],[AC_PROG_OBJCXX]) + +dnl By default, libtool for mingw refuses to link static libs into a dll for +dnl fear of mixing pic/non-pic objects, and import/export complications. Since +dnl we have those under control, re-enable that functionality. +case $host in + *mingw*) + lt_cv_deplibs_check_method="pass_all" + ;; +esac +dnl Require C++17 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) +dnl Check if -latomic is required for +CHECK_ATOMIC + +dnl Libtool init checks. +LT_INIT([pic-only]) + +dnl Zcash macros for required programs. Configure exits with error if +dnl they are not detected. +AC_DEFUN( + ZC_REQUIRE_TOOL, + [ + AC_PATH_TOOL($1, $2, $2_notfound) + if test x${$1} = x$2_notfound + then + AC_MSG_ERROR("Required tool $2 was not found") + fi + ] +) + +AC_DEFUN( + ZC_REQUIRE_PROG, + [ + AC_PATH_PROG($1, $2, $2_notfound) + if test x${$1} = x$2_notfound + then + AC_MSG_ERROR("Required program $2 was not found") + fi + ] +) + +dnl Check/return PATH for base programs. +dnl Required tools and programs: +ZC_REQUIRE_TOOL(AR, ar) +ZC_REQUIRE_TOOL(RANLIB, ranlib) +ZC_REQUIRE_TOOL(STRIP, strip) +ZC_REQUIRE_PROG([GIT], [git]) +ZC_REQUIRE_PROG(RUSTC, rustc) +ZC_REQUIRE_PROG(CARGO, cargo) +dnl This one is still optional and checked by complicated logic below: +AC_PATH_PROG(CCACHE,ccache) +dnl This one is not currently used anywhere, thus not required: +AC_PATH_PROG(XGETTEXT,xgettext) +ZC_REQUIRE_PROG(HEXDUMP,hexdump) +AC_PATH_PROG(READELF,readelf) +ZC_REQUIRE_TOOL(CPPFILT,c++filt) + +AC_ARG_ENABLE([online-rust], + [AS_HELP_STRING([--enable-online-rust], + [enable Rust to fetch dependencies from the network (default is to use vendored dependencies)])], + [enable_online_rust=$enableval], + [enable_online_rust=no]) +AM_CONDITIONAL(ENABLE_ONLINE_RUST, test "$enable_online_rust" != no) + +# Enable wallet +AC_ARG_ENABLE([wallet], + [AS_HELP_STRING([--disable-wallet], + [disable wallet (enabled by default)])], + [enable_wallet=$enableval], + [enable_wallet=yes]) + +AC_ARG_ENABLE([mining], + [AS_HELP_STRING([--enable-mining], + [enable mining (default is yes)])], + [enable_mining=$enableval], + [enable_mining=yes]) + +AC_ARG_ENABLE(tests, + AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), + [use_tests=$enableval], + [use_tests=yes]) + +AC_ARG_ENABLE(bench, + AS_HELP_STRING([--enable-bench],[compile benchmarks (default is yes)]), + [use_bench=$enableval], + [use_bench=yes]) + +AC_ARG_ENABLE([fuzz-main], + [AS_HELP_STRING([--enable-fuzz-main], + [Replace main() with a stub for fuzzing (default is no)])], + [use_fuzz_main=$enableval], + [use_fuzz_main=no]) + +AC_ARG_ENABLE([hardening], + [AS_HELP_STRING([--disable-hardening], + [do not attempt to harden the resulting executables (default is to harden when possible)])], + [use_hardening=$enableval], + [use_hardening=auto]) + +AC_ARG_ENABLE([reduce-exports], + [AS_HELP_STRING([--enable-reduce-exports], + [attempt to reduce exported symbols in the resulting executables (default is no)])], + [use_reduce_exports=$enableval], + [use_reduce_exports=no]) + +AC_ARG_ENABLE([ccache], + [AS_HELP_STRING([--disable-ccache], + [do not use ccache for building (default is to use if found)])], + [use_ccache=$enableval], + [use_ccache=auto]) + +AC_ARG_ENABLE([lcov], + [AS_HELP_STRING([--enable-lcov], + [enable lcov testing (default is no)])], + [use_lcov=yes], + [use_lcov=no]) + +AC_ARG_ENABLE([glibc-back-compat], + [AS_HELP_STRING([--enable-glibc-back-compat], + [enable backwards compatibility with glibc])], + [use_glibc_compat=$enableval], + [use_glibc_compat=no]) + +AC_ARG_ENABLE([zmq], + [AS_HELP_STRING([--disable-zmq], + [disable ZMQ notifications])], + [use_zmq=$enableval], + [use_zmq=yes]) + +AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) + +AC_ARG_ENABLE(man, + [AS_HELP_STRING([--disable-man], + [do not install man pages (default is to install)])],, + enable_man=yes) +AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) + +# Enable debug +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [use compiler flags and macros suited for debugging (default is no)])], + [enable_debug=$enableval], + [enable_debug=no]) + +# Enable different -fsanitize options +AC_ARG_WITH([sanitizers], + [AS_HELP_STRING([--with-sanitizers], + [comma separated list of extra sanitizers to build with (default is none enabled)])], + [use_sanitizers=$withval]) + +# Enable gprof profiling +AC_ARG_ENABLE([gprof], + [AS_HELP_STRING([--enable-gprof], + [use gprof profiling compiler flags (default is no)])], + [enable_gprof=$enableval], + [enable_gprof=no]) + +# Turn warnings into errors +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [Treat all compiler warnings as errors (default is no)])], + [enable_werror=$enableval], + [enable_werror=no]) + +AC_LANG_PUSH([C++]) +AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) + +if test "x$enable_debug" = xyes; then + # Clear default -g -O2 flags + if test "x$CXXFLAGS_overridden" = xno; then + CXXFLAGS="" + fi + + # Disable all optimizations + AX_CHECK_COMPILE_FLAG([-O0], [[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]]) + + # Prefer -g3, fall back to -g if that is unavailable. + AX_CHECK_COMPILE_FLAG( + [-g3], + [[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g3"]], + [AX_CHECK_COMPILE_FLAG([-g],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g"]],,[[$CXXFLAG_WERROR]])], + [[$CXXFLAG_WERROR]]) + + AX_CHECK_PREPROC_FLAG([-DDEBUG],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG"]],,[[$CXXFLAG_WERROR]]) + AX_CHECK_PREPROC_FLAG([-DDEBUG_LOCKORDER],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG_LOCKORDER"]],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -ftrapv"],,[[$CXXFLAG_WERROR]]) +else + # Even with enable_debug=no we build with standard debug symbols + AX_CHECK_COMPILE_FLAG([-g],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g"]],,[[$CXXFLAG_WERROR]]) + + # -ftrapv and -fwrapv conflict, so we only set this if enable_debug=no + AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"],,[[$CXXFLAG_WERROR]]) +fi + +if test x$use_sanitizers != x; then + # First check if the compiler accepts flags. If an incompatible pair like + # -fsanitize=address,thread is used here, this check will fail. This will also + # fail if a bad argument is passed, e.g. -fsanitize=undfeined + AX_CHECK_COMPILE_FLAG( + [[-fsanitize=$use_sanitizers]], + [[SANITIZER_CXXFLAGS=-fsanitize=$use_sanitizers]], + [AC_MSG_ERROR([compiler did not accept requested flags])]) + + # Some compilers (e.g. GCC) require additional libraries like libasan, + # libtsan, libubsan, etc. Make sure linking still works with the sanitize + # flag. This is a separate check so we can give a better error message when + # the sanitize flags are supported by the compiler but the actual sanitizer + # libs are missing. + AX_CHECK_LINK_FLAG( + [[-fsanitize=$use_sanitizers]], + [[SANITIZER_LDFLAGS=-fsanitize=$use_sanitizers]], + [AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])]) + + AX_CHECK_COMPILE_FLAG( + [-fno-omit-frame-pointer], + [SANITIZER_CXXFLAGS="$SANITIZER_CXXFLAGS -fno-omit-frame-pointer"], + [AC_MSG_ERROR(Cannot enable -fno-omit-frame-pointer)]) + + # libc/libstdc++ static linking is not supported for TSan + case $use_sanitizers in + *thread*) + ;; + *) + AX_CHECK_LINK_FLAG( + [-static-libstdc++], + [SANITIZER_LDFLAGS="$SANITIZER_LDFLAGS -static-libstdc++"], + [AC_MSG_ERROR(Cannot statically link -static-libstdc++)]) + ;; + esac + + case $use_sanitizers in + *address*) + AX_CHECK_LINK_FLAG( + [-static-libasan], + [SANITIZER_LDFLAGS="$SANITIZER_LDFLAGS -static-libasan"], + [AC_MSG_ERROR(Cannot statically link -static-libasan)]) + ;; + *) + ;; + esac +fi + +ERROR_CXXFLAGS= +if test "x$enable_werror" = "xyes"; then + if test "x$CXXFLAG_WERROR" = "x"; then + AC_MSG_ERROR("enable-werror set but -Werror is not usable") + fi + ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror" +fi + +if test "x$CXXFLAGS_overridden" = "xno"; then + AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) + + ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all + ## unknown options if any other warning is produced. Test the -Wfoo case, and + ## set the -Wno-foo case if it works. + AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wself-assign],[CXXFLAGS="$CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[CXXFLAGS="$CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[CXXFLAGS="$CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) + + # Check for optional instruction set support. Enabling these does _not_ imply that all code will + # be compiled with them, rather that specific objects/libs may use them after checking for runtime + # compatibility. + AX_CHECK_COMPILE_FLAG([-msse4.2],[[SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]]) + +fi + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS" +AC_MSG_CHECKING(for assembler crc32 support) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #if defined(_MSC_VER) + #include + #elif defined(__GNUC__) && defined(__SSE4_2__) + #include + #endif + ]],[[ + uint64_t l = 0; + l = _mm_crc32_u8(l, 0); + l = _mm_crc32_u32(l, 0); + l = _mm_crc32_u64(l, 0); + return l; + ]])], + [ AC_MSG_RESULT(yes); enable_hwcrc32=yes], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + +CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" + +AC_ARG_WITH([utils], + [AS_HELP_STRING([--with-utils], + [build zcash-cli zcash-tx (default=yes)])], + [build_bitcoin_utils=$withval], + [build_bitcoin_utils=yes]) + +AC_ARG_WITH([libs], + [AS_HELP_STRING([--with-libs], + [build libraries (default=no)])], + [build_bitcoin_libs=$withval], + [build_bitcoin_libs=no]) + +AC_ARG_WITH([daemon], + [AS_HELP_STRING([--with-daemon], + [build bitcoind daemon (default=yes)])], + [build_bitcoind=$withval], + [build_bitcoind=yes]) + +use_pkgconfig=yes +case $host in + *mingw*) + + dnl pkgconfig does more harm than good with MinGW + use_pkgconfig=no + + TARGET_OS=windows + AC_CHECK_LIB([kernel32], [GetModuleFileNameA],, AC_MSG_ERROR(libkernel32 missing)) + AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) + AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) + AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) + AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) + AC_CHECK_LIB([shell32], [SHGetSpecialFolderPathW],, AC_MSG_ERROR(libshell32 missing)) + AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) + AC_CHECK_LIB([ole32], [CoCreateInstance],, AC_MSG_ERROR(libole32 missing)) + AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) + AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) + AC_CHECK_LIB([advapi32], [CryptAcquireContextW],, AC_MSG_ERROR(libadvapi32 missing)) + AC_CHECK_LIB([ws2_32], [WSAStartup],, AC_MSG_ERROR(libws2_32 missing)) + AC_CHECK_LIB([shlwapi], [PathRemoveFileSpecW],, AC_MSG_ERROR(libshlwapi missing)) + AC_CHECK_LIB([iphlpapi], [GetAdaptersAddresses],, AC_MSG_ERROR(libiphlpapi missing)) + AC_CHECK_LIB([ntdll], [main],, AC_MSG_ERROR(libntdll missing)) + AC_CHECK_LIB([bcrypt], [main],, AC_MSG_ERROR(libbcrypt missing)) + + dnl -static is interpreted by libtool, where it has a different meaning. + dnl In libtool-speak, it's -all-static. + AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"]) + + AC_PATH_PROG([MAKENSIS], [makensis], none) + if test x$MAKENSIS = xnone; then + AC_MSG_WARN("makensis not found. Cannot create installer.") + fi + + ZC_REQUIRE_TOOL(WINDRES, windres) + + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" + LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" + + dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. + dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override + dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are + dnl also overridden to prevent their insertion later. + dnl This should only affect dll's. + archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" + postdeps_CXX= + + dnl We require Windows 7 (NT 6.1) or later + AX_CHECK_LINK_FLAG([[-Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1]],[LDFLAGS="$LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1"],,[[$LDFLAG_WERROR]]) + ;; + *darwin*) + TARGET_OS=darwin + LEVELDB_TARGET_FLAGS="-DOS_MACOSX" + if test x$cross_compiling != xyes; then + BUILD_OS=darwin + AC_CHECK_PROG([PORT],port, port) + if test x$PORT = xport; then + dnl add default macports paths + CPPFLAGS="$CPPFLAGS -isystem /opt/local/include" + LIBS="$LIBS -L/opt/local/lib" + if test -d /opt/local/include/db62; then + CPPFLAGS="$CPPFLAGS -I/opt/local/include/db62" + LIBS="$LIBS -L/opt/local/lib/db62" + fi + fi + + AC_CHECK_PROG([BREW],brew, brew) + 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). + + bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null` + if test x$bdb_prefix != x; then + CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include" + LIBS="$LIBS -L$bdb_prefix/lib" + fi + fi + else + case $build_os in + *darwin*) + BUILD_OS=darwin + ;; + *) + AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) + AC_PATH_TOOL([OTOOL], [otool], otool) + AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) + + dnl libtool will try to strip the static lib, which is a problem for + dnl cross-builds because strip attempts to call a hard-coded ld, + dnl which may not exist in the path. Stripping the .a is not + dnl necessary, so just disable it. + old_striplib= + ;; + esac + fi + + AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) + CPPFLAGS="$CPPFLAGS -DMAC_OSX" + OBJCXXFLAGS="$CXXFLAGS" + ;; + *android*) + dnl make sure android stays above linux for hosts like *linux-android* + TARGET_OS=android + LEVELDB_TARGET_FLAGS="-DOS_ANDROID" + ;; + *linux*) + TARGET_OS=linux + LEVELDB_TARGET_FLAGS="-DOS_LINUX" + ;; + *kfreebsd*) + LEVELDB_TARGET_FLAGS="-DOS_KFREEBSD" + ;; + *freebsd*) + LEVELDB_TARGET_FLAGS="-DOS_FREEBSD" + ;; + *openbsd*) + LEVELDB_TARGET_FLAGS="-DOS_OPENBSD" + ;; + *netbsd*) + LEVELDB_TARGET_FLAGS="-DOS_NETBSD" + ;; + *dragonfly*) + LEVELDB_TARGET_FLAGS="-DOS_DRAGONFLYBSD" + ;; + *solaris*) + LEVELDB_TARGET_FLAGS="-DOS_SOLARIS" + ;; + *hpux*) + LEVELDB_TARGET_FLAGS="-DOS_HPUX" + ;; + *) + AC_MSG_ERROR(Cannot build leveldb for $host. Please file a bug report.) + ;; +esac + +if test x$use_pkgconfig = xyes; then + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [ + PKG_PROG_PKG_CONFIG + if test x"$PKG_CONFIG" = "x"; then + AC_MSG_ERROR(pkg-config not found.) + fi + ]) +fi + +if test x$use_lcov = xyes; then + ZC_REQUIRE_TOOL(GCOV, gcov) + ZC_REQUIRE_PROG(LCOV, lcov) + ZC_REQUIRE_PROG(GENHTML, genhtml) + + LCOV="$LCOV --gcov-tool=$GCOV --rc lcov_branch_coverage=1" + GENHTML="$GENHTML --branch-coverage" + AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], + [AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) +fi + +dnl Check for endianness +AC_C_BIGENDIAN + +dnl Check for pthread compile/link requirements +AX_PTHREAD + +# The following macro will add the necessary defines to bitcoin-config.h, but +# they also need to be passed down to any subprojects. Pull the results out of +# the cache and add them to CPPFLAGS. +AC_SYS_LARGEFILE +# detect POSIX or GNU variant of strerror_r +AC_FUNC_STRERROR_R + +if test x$ac_cv_sys_file_offset_bits != x && + test x$ac_cv_sys_file_offset_bits != xno && + test x$ac_cv_sys_file_offset_bits != xunknown; then + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" +fi + +if test x$ac_cv_sys_large_files != x && + test x$ac_cv_sys_large_files != xno && + test x$ac_cv_sys_large_files != xunknown; then + CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=$ac_cv_sys_large_files" +fi + +AX_GCC_FUNC_ATTRIBUTE([visibility]) +AX_GCC_FUNC_ATTRIBUTE([dllexport]) +AX_GCC_FUNC_ATTRIBUTE([dllimport]) + +if test x$use_glibc_compat != xno; then + + #glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link + #in anyway for back-compat. + AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing)) + + #__fdelt_chk's params and return type have changed from long unsigned int to long int. + # See which one is present here. + AC_MSG_CHECKING(__fdelt_chk type) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#ifdef _FORTIFY_SOURCE + #undef _FORTIFY_SOURCE + #endif + #define _FORTIFY_SOURCE 2 + #include + extern "C" long unsigned int __fdelt_warn(long unsigned int);]],[[]])], + [ fdelt_type="long unsigned int"], + [ fdelt_type="long int"]) + AC_MSG_RESULT($fdelt_type) + AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk]) +else + AC_SEARCH_LIBS([clock_gettime],[rt]) +fi + +if test "x$enable_gprof" = xyes; then + dnl -pg is incompatible with -pie. Since hardening and profiling together doesn't make sense, + dnl we simply make them mutually exclusive here. Additionally, hardened toolchains may force + dnl -pie by default, in which case it needs to be turned off with -no-pie. + + if test x$use_hardening = xyes; then + AC_MSG_ERROR(gprof profiling is not compatible with hardening. Reconfigure with --disable-hardening or --disable-gprof) + fi + use_hardening=no + AX_CHECK_COMPILE_FLAG([-pg],[GPROF_CXXFLAGS="-pg"], + [AC_MSG_ERROR(gprof profiling requested but not available)], [[$CXXFLAG_WERROR]]) + + AX_CHECK_LINK_FLAG([[-no-pie]], [GPROF_LDFLAGS="-no-pie"]) + AX_CHECK_LINK_FLAG([[-pg]],[GPROF_LDFLAGS="$GPROF_LDFLAGS -pg"], + [AC_MSG_ERROR(gprof profiling requested but not available)], [[$GPROF_LDFLAGS]]) +fi + +if test x$TARGET_OS != xwindows; then + # All windows code is PIC, forcing it on just adds useless compile warnings + AX_CHECK_COMPILE_FLAG([-fPIC],[PIC_FLAGS="-fPIC"]) +fi + +if test x$use_fuzz_main == xyes; then + CFLAGS="$CFLAGS -DZCASH_FUZZ=1" + CXXFLAGS="$CXXFLAGS -DZCASH_FUZZ=1" +fi + +if test x$use_hardening != xno; then + use_hardening=yes + AX_CHECK_COMPILE_FLAG([-Wformat],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wformat"],[AC_MSG_ERROR(Cannot enable -Wformat)]) + AX_CHECK_COMPILE_FLAG([-Wformat-security],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wformat-security"],[AC_MSG_ERROR(Cannot enable -Wformat-security)],[-Wformat]) + AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"],[AC_MSG_ERROR(Cannot enable -Wstack-protector)]) + AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"],[AC_MSG_ERROR(Cannot enable -fstack-protector-all)]) + + AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ + AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ + HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" + ],[AC_MSG_ERROR(Cannot enable -U_FORTIFY_SOURCE)]) + HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -D_FORTIFY_SOURCE=2" + ],[AC_MSG_ERROR(Cannot enable -D_FORTIFY_SOURCE=2)]) + + if test x$TARGET_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_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)]) + AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"],[AC_MSG_ERROR(Cannot enable --nxcompat)]) + AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"],[AC_MSG_ERROR(Cannot enable ASLR)]) + fi + + case $host in + *mingw*) + AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) + ;; + esac +fi + +dnl this flag screws up non-darwin gcc even when the check fails. special-case it. +if test x$TARGET_OS = xdarwin; then + AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) +fi + +AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) +AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])]) +AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])]) + +AC_CHECK_DECLS([strnlen]) + +AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,, + [#if HAVE_ENDIAN_H + #include + #elif HAVE_SYS_ENDIAN_H + #include + #endif]) + +AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, + [#if HAVE_BYTESWAP_H + #include + #endif]) + +AC_CHECK_DECLS([__builtin_clz, __builtin_clzl, __builtin_clzll]) + +dnl Check for MSG_NOSIGNAL +AC_MSG_CHECKING(for MSG_NOSIGNAL) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = MSG_NOSIGNAL; ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MSG_NOSIGNAL, 1,[Define this symbol if you have MSG_NOSIGNAL]) ], + [ AC_MSG_RESULT(no)] +) + +AC_MSG_CHECKING([for visibility attribute]) +AC_LINK_IFELSE([AC_LANG_SOURCE([ + int foo_def( void ) __attribute__((visibility("default"))); + int main(){} + ])], + [ + AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE,1,[Define if the visibility attribute is supported.]) + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + if test x$use_reduce_exports = xyes; then + AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.]) + fi + ] +) + +if test x$use_reduce_exports = xyes; then + AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], + [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) +fi + +LEVELDB_CPPFLAGS= +LIBLEVELDB= +LIBMEMENV= +AM_CONDITIONAL([EMBEDDED_LEVELDB],[true]) +AC_SUBST(LEVELDB_CPPFLAGS) +AC_SUBST(LIBLEVELDB) +AC_SUBST(LIBMEMENV) + +if test x$enable_wallet != xno; then + dnl Check for libdb_cxx only if wallet enabled + BITCOIN_FIND_BDB62 +fi + +if test x$build_bitcoin_utils$build_bitcoind$use_tests = xnonono; then + use_boost=no +else + use_boost=yes +fi + +if test x$use_boost = xyes; then + +dnl Check for boost libs +dnl We need Boost >= 1.62 to fix a potential security bug (https://github.com/zcash/zcash/issues/1241) +AX_BOOST_BASE([1.62]) +AX_BOOST_SYSTEM +AX_BOOST_FILESYSTEM +AX_BOOST_PROGRAM_OPTIONS +AX_BOOST_THREAD +AX_BOOST_CHRONO + +fi + +if test x$use_reduce_exports = xyes; then + CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS" + AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"]) +fi + +if test x$use_tests = xyes; then + + if test x$HEXDUMP = x; then + AC_MSG_ERROR(hexdump is required for tests) + fi + + + if test x$use_boost = xyes; then + + AX_BOOST_UNIT_TEST_FRAMEWORK + + dnl Determine if -DBOOST_TEST_DYN_LINK is needed + AC_MSG_CHECKING([for dynamic linked boost test]) + TEMP_LIBS="$LIBS" + LIBS="$LIBS $BOOST_LDFLAGS $BOOST_UNIT_TEST_FRAMEWORK_LIB" + TEMP_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + AC_LINK_IFELSE([AC_LANG_SOURCE([ + #define BOOST_TEST_DYN_LINK + #define BOOST_TEST_MAIN + #include + + ])], + [AC_MSG_RESULT(yes)] + [TESTDEFS="$TESTDEFS -DBOOST_TEST_DYN_LINK"], + [AC_MSG_RESULT(no)]) + LIBS="$TEMP_LIBS" + CPPFLAGS="$TEMP_CPPFLAGS" + + fi +fi + +if test x$use_boost = xyes; then +BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" +fi + +if test x$use_pkgconfig = xyes; then + : dnl + m4_ifdef( + [PKG_CHECK_MODULES], + [ + if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) + if test x$TARGET_OS != xwindows; then + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) + fi + fi + + if test "x$use_zmq" = "xyes"; then + PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) + else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + fi + ] + ) +else + + if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then + AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) + AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) + if test x$TARGET_OS != xwindows; then + AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) + fi + fi + + if test "x$use_zmq" = "xyes"; then + AC_CHECK_HEADER([zmq.h], + [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], + [AC_MSG_WARN([zmq.h not found, disabling zmq support]) + use_zmq=no + AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) + AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, + [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) + use_zmq=no + AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) + else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) + fi + + if test "x$use_zmq" = "xyes"; then + dnl Assume libzmq was built for static linking + case $host in + *mingw*) + ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" + ;; + esac + fi +fi + +RUST_LIBS="" +case $host in + *mingw*) + RUST_LIBS="$RUST_LIBS -luserenv" + ;; + *) + RUST_LIBS="$RUST_LIBS -ldl" + ;; +esac + +# Additional Zcash flags +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 -lsodium $RUST_LIBS" + +AC_MSG_CHECKING([whether to build bitcoind]) +AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) +AC_MSG_RESULT($build_bitcoind) + +AC_MSG_CHECKING([whether to build utils (zcash-cli zcash-tx)]) +AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) +AC_MSG_RESULT($build_bitcoin_utils) + +AC_MSG_CHECKING([whether to build libraries]) +AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) +if test x$build_bitcoin_libs = xyes; then + AC_DEFINE(HAVE_SCRIPT_LIB, 1, [Define this symbol if the script lib has been built]) + AC_CONFIG_FILES([libzcash_script.pc:libzcash_script.pc.in]) +fi + +AC_MSG_RESULT($build_bitcoin_libs) + +AC_LANG_POP + +if test "x$use_ccache" != "xno"; then + AC_MSG_CHECKING(if ccache should be used) + if test x$CCACHE = x; then + if test "x$use_ccache" = "xyes"; then + AC_MSG_ERROR([ccache not found.]); + else + use_ccache=no + fi + else + use_ccache=yes + CC="$ac_cv_path_CCACHE $CC" + CXX="$ac_cv_path_CCACHE $CXX" + fi + AC_MSG_RESULT($use_ccache) +fi +if test "x$use_ccache" = "xyes"; then + AX_CHECK_PREPROC_FLAG([-Qunused-arguments],[CPPFLAGS="-Qunused-arguments $CPPFLAGS"]) +fi + +dnl enable wallet +AC_MSG_CHECKING([if wallet should be enabled]) +if test x$enable_wallet != xno; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED([ENABLE_WALLET],[1],[Define to 1 to enable wallet functions]) + +else + AC_MSG_RESULT(no) +fi + +dnl enable mining +AC_MSG_CHECKING([if mining should be enabled]) +if test x$enable_mining != xno; then + AC_MSG_RESULT(yes) + AC_DEFINE(ENABLE_MINING, 1, [Define to 1 to enable mining functions]) + +else + AC_MSG_RESULT(no) +fi + +AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) + +AC_MSG_CHECKING([whether to build test_bitcoin]) +if test x$use_tests = xyes; then + AC_MSG_RESULT([yes]) + BUILD_TEST="yes" +else + AC_MSG_RESULT([no]) + BUILD_TEST="" +fi + +AC_MSG_CHECKING([whether to reduce exports]) +if test x$use_reduce_exports = xyes; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$use_tests = xnononono; then + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon or --enable-tests]) +fi + +AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) +AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin]) +AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows]) +AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes]) +AM_CONDITIONAL([ENABLE_MINING],[test x$enable_mining = xyes]) +AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) +AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes]) +AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) +AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) +AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) +AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = xyes]) + +AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) +AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) +AC_DEFINE(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION, [Build revision]) +AC_DEFINE(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD, [Version Build]) +AC_DEFINE(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE, [Version is release]) +AC_DEFINE(COPYRIGHT_YEAR, _COPYRIGHT_YEAR, [Version is release]) +AC_SUBST(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR) +AC_SUBST(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR) +AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) +AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) +AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) +AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) +AC_SUBST(BITCOIN_DAEMON_NAME) +AC_SUBST(BITCOIN_CLI_NAME) +AC_SUBST(BITCOIN_TX_NAME) + +AC_SUBST(RUST_TARGET) +AC_SUBST(RUST_VENDORED_SOURCES) +AC_SUBST(RELDFLAGS) +AC_SUBST(DEBUG_CPPFLAGS) +AC_SUBST(DEBUG_CXXFLAGS) +AC_SUBST(ERROR_CXXFLAGS) +AC_SUBST(GPROF_CXXFLAGS) +AC_SUBST(GPROF_LDFLAGS) +AC_SUBST(HARDENED_CXXFLAGS) +AC_SUBST(HARDENED_CPPFLAGS) +AC_SUBST(HARDENED_LDFLAGS) +AC_SUBST(PIC_FLAGS) +AC_SUBST(PIE_FLAGS) +AC_SUBST(SANITIZER_CXXFLAGS) +AC_SUBST(SANITIZER_LDFLAGS) +AC_SUBST(SSE42_CXXFLAGS) +AC_SUBST(LIBTOOL_APP_LDFLAGS) +AC_SUBST(BOOST_LIBS) +AC_SUBST(TESTDEFS) +AC_SUBST(LEVELDB_TARGET_FLAGS) +AC_SUBST(EVENT_LIBS) +AC_SUBST(EVENT_PTHREADS_LIBS) +AC_SUBST(ZMQ_LIBS) +AC_SUBST(LIBZCASH_LIBS) +AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile src/test/buildenv.py]) +AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) +AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) + +dnl boost's m4 checks do something really nasty: they export these vars. As a +dnl result, they leak into secp256k1's configure and crazy things happen. +dnl Until this is fixed upstream and we've synced, we'll just un-export them. +CPPFLAGS_TEMP="$CPPFLAGS" +unset CPPFLAGS +CPPFLAGS="$CPPFLAGS_TEMP" + +LDFLAGS_TEMP="$LDFLAGS" +unset LDFLAGS +LDFLAGS="$LDFLAGS_TEMP" + +LIBS_TEMP="$LIBS" +unset LIBS +LIBS="$LIBS_TEMP" + +PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" +unset PKG_CONFIG_PATH +PKG_CONFIG_PATH="$PKGCONFIG_PATH_TEMP" + +PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" +unset PKG_CONFIG_LIBDIR +PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" + +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-benchmark=no --with-bignum=no --enable-module-recovery" +AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue]) + +AC_OUTPUT + +dnl Taken from https://wiki.debian.org/RpathIssue +case $host in + *-*-linux-gnu) + AC_MSG_RESULT([Fixing libtool for -rpath problems.]) + sed < libtool > libtool-2 \ + 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' + mv libtool-2 libtool + chmod 755 libtool + ;; +esac + +dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows +case ${OS} in + *Windows*) + sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' qa/pull-tester/tests_config.py > qa/pull-tester/tests_config-2.py + mv qa/pull-tester/tests_config-2.py qa/pull-tester/tests_config.py + chmod +x qa/pull-tester/tests_config.py + ;; +esac + +echo +echo "Options used to compile and link:" +echo " with wallet = $enable_wallet" +echo " with zmq = $use_zmq" +echo " with test = $use_tests" +echo " sanitizers = $use_sanitizers" +echo " debug enabled = $enable_debug" +echo " gprof enabled = $enable_gprof" +echo " werror = $enable_werror" +echo +echo " target os = $TARGET_OS" +echo " build os = $BUILD_OS" +echo +echo " CC = $CC" +echo " CFLAGS = $CFLAGS" +echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" +echo " CXX = $CXX" +echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " ARFLAGS = $ARFLAGS" +echo diff --git a/depend/zcash/contrib/README.md b/depend/zcash/contrib/README.md new file mode 100644 index 000000000..4ec9fffa5 --- /dev/null +++ b/depend/zcash/contrib/README.md @@ -0,0 +1,43 @@ +*** Warning: This document has not been updated for Zcash and may be inaccurate. *** + +Wallet Tools +--------------------- + +### [BitRPC](/contrib/bitrpc) ### +Allows for sending of all standard Bitcoin commands via RPC rather than as command line args. + +Repository Tools +--------------------- + +### [Developer tools](/contrib/devtools) ### +Specific tools for developers working on this repository. +Contains the script `github-merge.sh` for merging github pull requests securely and signing them using GPG. + +### [Linearize](/contrib/linearize) ### +Construct a linear, no-fork, best version of the blockchain. + +### [Qos](/contrib/qos) ### + +A Linux bash script that will set up traffic control (tc) to limit the outgoing bandwidth for connections to the Bitcoin network. This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. + +### [Seeds](/contrib/seeds) ### +Utility to generate the pnSeed[] array that is compiled into the client. + +Build Tools and Keys +--------------------- + +### [Debian](/contrib/debian) ### +Contains files used to package bitcoind/bitcoin-qt +for Debian-based Linux systems. If you compile bitcoind/bitcoin-qt yourself, there are some useful files here. + +### [Gitian-descriptors](/contrib/gitian-descriptors) ### +Gavin's notes on getting gitian builds up and running using KVM. + +### [Gitian-downloader](/contrib/gitian-downloader) +Various PGP files of core developers. + +Test and Verify Tools +--------------------- + +### [TestGen](/contrib/testgen) ### +Utilities to generate test vectors for the data-driven Bitcoin tests. \ No newline at end of file diff --git a/depend/zcash/contrib/bitrpc/README.md b/depend/zcash/contrib/bitrpc/README.md new file mode 100644 index 000000000..f5ef2f040 --- /dev/null +++ b/depend/zcash/contrib/bitrpc/README.md @@ -0,0 +1,8 @@ +### BitRPC +Allows for sending of all standard Bitcoin commands via RPC rather than as command line args. + +### Looking for Wallet Tools? +BitRPC.py is able to do the exact same thing as `walletchangepass.py` and `walletunlock.py`. Their respective commands in BitRPC.py are: + + bitrpc.py walletpassphrasechange + bitrpc.py walletpassphrase \ No newline at end of file diff --git a/depend/zcash/contrib/bitrpc/bitrpc.py b/depend/zcash/contrib/bitrpc/bitrpc.py new file mode 100644 index 000000000..1c3d40f22 --- /dev/null +++ b/depend/zcash/contrib/bitrpc/bitrpc.py @@ -0,0 +1,335 @@ +from jsonrpc import ServiceProxy +import sys +import string +import getpass + +# ===== BEGIN USER SETTINGS ===== +# if you do not set these you will be prompted for a password for every command +rpcuser = "" +rpcpass = "" +# ====== END USER SETTINGS ====== + + +if rpcpass == "": + access = ServiceProxy("http://127.0.0.1:8232") +else: + access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8232") +cmd = sys.argv[1].lower() + +if cmd == "backupwallet": + try: + path = raw_input("Enter destination path/filename: ") + print access.backupwallet(path) + except Exception as inst: + print inst + +elif cmd == "encryptwallet": + try: + pwd = getpass.getpass(prompt="Enter passphrase: ") + pwd2 = getpass.getpass(prompt="Repeat passphrase: ") + if pwd == pwd2: + access.encryptwallet(pwd) + print "\n---Wallet encrypted. Server stopping, restart to run with encrypted wallet---\n" + else: + print "\n---Passphrases do not match---\n" + except Exception as inst: + print inst + +elif cmd == "getaccount": + try: + addr = raw_input("Enter a Bitcoin address: ") + print access.getaccount(addr) + except Exception as inst: + print inst + +elif cmd == "getaccountaddress": + try: + acct = raw_input("Enter an account name: ") + print access.getaccountaddress(acct) + except Exception as inst: + print inst + +elif cmd == "getaddressesbyaccount": + try: + acct = raw_input("Enter an account name: ") + print access.getaddressesbyaccount(acct) + except Exception as inst: + print inst + +elif cmd == "getbalance": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getbalance(acct, mc) + except: + print access.getbalance() + except Exception as inst: + print inst + +elif cmd == "getblockbycount": + try: + height = raw_input("Height: ") + print access.getblockbycount(height) + except Exception as inst: + print inst + +elif cmd == "getblockcount": + try: + print access.getblockcount() + except Exception as inst: + print inst + +elif cmd == "getblocknumber": + try: + print access.getblocknumber() + except Exception as inst: + print inst + +elif cmd == "getconnectioncount": + try: + print access.getconnectioncount() + except Exception as inst: + print inst + +elif cmd == "getdifficulty": + try: + print access.getdifficulty() + except Exception as inst: + print inst + +elif cmd == "getgenerate": + try: + print access.getgenerate() + except Exception as inst: + print inst + +elif cmd == "gethashespersec": + try: + print access.gethashespersec() + except Exception as inst: + print inst + +elif cmd == "getinfo": + try: + print access.getinfo() + except Exception as inst: + print inst + +elif cmd == "getnewaddress": + try: + acct = raw_input("Enter an account name: ") + try: + print access.getnewaddress(acct) + except: + print access.getnewaddress() + except Exception as inst: + print inst + +elif cmd == "getreceivedbyaccount": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaccount(acct, mc) + except: + print access.getreceivedbyaccount() + except Exception as inst: + print inst + +elif cmd == "getreceivedbyaddress": + try: + addr = raw_input("Enter a Bitcoin address (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaddress(addr, mc) + except: + print access.getreceivedbyaddress() + except Exception as inst: + print inst + +elif cmd == "gettransaction": + try: + txid = raw_input("Enter a transaction ID: ") + print access.gettransaction(txid) + except Exception as inst: + print inst + +elif cmd == "getwork": + try: + data = raw_input("Data (optional): ") + try: + print access.gettransaction(data) + except: + print access.gettransaction() + except Exception as inst: + print inst + +elif cmd == "help": + try: + cmd = raw_input("Command (optional): ") + try: + print access.help(cmd) + except: + print access.help() + except Exception as inst: + print inst + +elif cmd == "listaccounts": + try: + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.listaccounts(mc) + except: + print access.listaccounts() + except Exception as inst: + print inst + +elif cmd == "listreceivedbyaccount": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaccount(mc, incemp) + except: + print access.listreceivedbyaccount() + except Exception as inst: + print inst + +elif cmd == "listreceivedbyaddress": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaddress(mc, incemp) + except: + print access.listreceivedbyaddress() + except Exception as inst: + print inst + +elif cmd == "listtransactions": + try: + acct = raw_input("Account (optional): ") + count = raw_input("Number of transactions (optional): ") + frm = raw_input("Skip (optional):") + try: + print access.listtransactions(acct, count, frm) + except: + print access.listtransactions() + except Exception as inst: + print inst + +elif cmd == "move": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.move(frm, to, amt, mc, comment) + except: + print access.move(frm, to, amt) + except Exception as inst: + print inst + +elif cmd == "sendfrom": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendfrom(frm, to, amt, mc, comment, commentto) + except: + print access.sendfrom(frm, to, amt) + except Exception as inst: + print inst + +elif cmd == "sendmany": + try: + frm = raw_input("From: ") + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.sendmany(frm,to,mc,comment) + except: + print access.sendmany(frm,to) + except Exception as inst: + print inst + +elif cmd == "sendtoaddress": + try: + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + amt = raw_input("Amount:") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendtoaddress(to,amt,comment,commentto) + except: + print access.sendtoaddress(to,amt) + except Exception as inst: + print inst + +elif cmd == "setaccount": + try: + addr = raw_input("Address: ") + acct = raw_input("Account:") + print access.setaccount(addr,acct) + except Exception as inst: + print inst + +elif cmd == "setgenerate": + try: + gen= raw_input("Generate? (true/false): ") + cpus = raw_input("Max processors/cores (-1 for unlimited, optional):") + try: + print access.setgenerate(gen, cpus) + except: + print access.setgenerate(gen) + except Exception as inst: + print inst + +elif cmd == "settxfee": + try: + amt = raw_input("Amount:") + print access.settxfee(amt) + except Exception as inst: + print inst + +elif cmd == "stop": + try: + print access.stop() + except Exception as inst: + print inst + +elif cmd == "validateaddress": + try: + addr = raw_input("Address: ") + print access.validateaddress(addr) + except Exception as inst: + print inst + +elif cmd == "walletpassphrase": + try: + pwd = getpass.getpass(prompt="Enter wallet passphrase: ") + access.walletpassphrase(pwd, 60) + print "\n---Wallet unlocked---\n" + except Exception as inst: + print inst + +elif cmd == "walletpassphrasechange": + try: + pwd = getpass.getpass(prompt="Enter old wallet passphrase: ") + pwd2 = getpass.getpass(prompt="Enter new wallet passphrase: ") + access.walletpassphrasechange(pwd, pwd2) + print + print "\n---Passphrase changed---\n" + except Exception as inst: + print inst + +else: + print "Command not found or not supported" diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.apt b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.apt new file mode 100644 index 000000000..40ee4b8a4 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.apt @@ -0,0 +1,42 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG=latest +FROM electriccoinco/zcashd-build-$FROMBASEOS$FROMBASEOS_BUILD_TAG + +ARG DUMBINIT_VERSION=1.2.2 +RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMBINIT_VERSION}/dumb-init_${DUMBINIT_VERSION}_amd64 +RUN chmod +x /usr/bin/dumb-init + +# Buildbot user +ARG BUILDBOT_USER=zcbbworker +ARG BUILDBOT_UID=2001 +RUN useradd --home-dir /home/$BUILDBOT_USER \ + --shell /bin/bash \ + --create-home \ + --uid $BUILDBOT_UID\ + $BUILDBOT_USER + +USER $BUILDBOT_USER +WORKDIR /home/$BUILDBOT_USER + +ADD bbworker-requirements.txt requirements.txt +RUN python -m venv venv \ + && . venv/bin/activate \ + && python -m pip install wheel \ + && python -m pip install -r requirements.txt + +# Buildbot worker +ARG BASEOS +ENV BUILDBOT_WORKER_NAME=$BASEOS-docker +ENV BUILDBOT_WORKER_PASS=thisgetssetwhenpodisstarted +ENV BUILDBOT_MASTER_HOST=dev-ci.z.cash +ENV BUILDBOT_MASTER_PORT=9899 + +WORKDIR /home/$BUILDBOT_USER +RUN venv/bin/buildbot-worker create-worker $BUILDBOT_WORKER_NAME \ + $BUILDBOT_MASTER_HOST:$BUILDBOT_MASTER_PORT \ + $BUILDBOT_WORKER_NAME $BUILDBOT_WORKER_PASS \ + && echo "OS: $BASEOS" > $BUILDBOT_WORKER_NAME/info/host +ADD bbworker-buildbot.tac $BUILDBOT_WORKER_NAME/buildbot.tac + +WORKDIR /home/$BUILDBOT_USER/$BUILDBOT_WORKER_NAME +CMD ["/usr/bin/dumb-init", "../venv/bin/twistd", "--pidfile=", "-ny", "buildbot.tac"] diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.arch b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.arch new file mode 100644 index 000000000..c3e6ff9d7 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.arch @@ -0,0 +1,35 @@ +FROM electriccoinco/zcashd-build-arch + +# Buildbot user +ARG BUILDBOT_USER=zcbbworker +ARG BUILDBOT_UID=2001 +RUN useradd --home-dir /home/$BUILDBOT_USER \ + --shell /bin/bash \ + --create-home \ + --uid $BUILDBOT_UID\ + $BUILDBOT_USER + +USER $BUILDBOT_USER +WORKDIR /home/$BUILDBOT_USER + +ADD bbworker-requirements.txt requirements.txt +RUN python -m venv venv \ + && . venv/bin/activate \ + && python -m pip install wheel \ + && python -m pip install -r requirements.txt + +# Buildbot worker +ARG BUILDBOT_WORKER_NAME=arch-docker +ARG BUILDBOT_WORKER_PASS=thisgetssetwhenpodisstarted +ARG BUILDBOT_MASTER_HOST=dev-ci.z.cash +ARG BUILDBOT_MASTER_PORT=9899 + +WORKDIR /home/$BUILDBOT_USER +RUN venv/bin/buildbot-worker create-worker $BUILDBOT_WORKER_NAME \ + $BUILDBOT_MASTER_HOST:$BUILDBOT_MASTER_PORT \ + $BUILDBOT_WORKER_NAME $BUILDBOT_WORKER_PASS \ + && echo "OS: Centos 8" > $BUILDBOT_WORKER_NAME/info/host +ADD bbworker-buildbot.tac $BUILDBOT_WORKER_NAME/buildbot.tac + +WORKDIR /home/$BUILDBOT_USER/$BUILDBOT_WORKER_NAME +CMD ["/usr/bin/dumb-init", "../venv/bin/twistd", "--pidfile=", "-ny", "buildbot.tac"] diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.centos8 b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.centos8 new file mode 100644 index 000000000..fbc02101b --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-bbworker.centos8 @@ -0,0 +1,35 @@ +FROM electriccoinco/zcashd-build-centos8 + +# Buildbot user +ARG BUILDBOT_USER=zcbbworker +ARG BUILDBOT_UID=2001 +RUN useradd --home-dir /home/$BUILDBOT_USER \ + --shell /bin/bash \ + --create-home \ + --uid $BUILDBOT_UID\ + $BUILDBOT_USER + +USER $BUILDBOT_USER +WORKDIR /home/$BUILDBOT_USER + +ADD bbworker-requirements.txt requirements.txt +RUN python3 -m venv venv \ + && . venv/bin/activate \ + && python -m pip install wheel \ + && python -m pip install -r requirements.txt + +# Buildbot worker +ARG BUILDBOT_WORKER_NAME=centos8-docker +ARG BUILDBOT_WORKER_PASS=thisgetssetwhenpodisstarted +ARG BUILDBOT_MASTER_HOST=dev-ci.z.cash +ARG BUILDBOT_MASTER_PORT=9899 + +WORKDIR /home/$BUILDBOT_USER +RUN venv/bin/buildbot-worker create-worker $BUILDBOT_WORKER_NAME \ + $BUILDBOT_MASTER_HOST:$BUILDBOT_MASTER_PORT \ + $BUILDBOT_WORKER_NAME $BUILDBOT_WORKER_PASS \ + && echo "OS: Centos 8" > $BUILDBOT_WORKER_NAME/info/host +ADD bbworker-buildbot.tac $BUILDBOT_WORKER_NAME/buildbot.tac + +WORKDIR /home/$BUILDBOT_USER/$BUILDBOT_WORKER_NAME +CMD ["/usr/bin/dumb-init", "../venv/bin/twistd", "--pidfile=", "-ny", "buildbot.tac"] diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build-python.apt b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build-python.apt new file mode 100644 index 000000000..8b73e9bb7 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build-python.apt @@ -0,0 +1,30 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG +FROM $FROMBASEOS:$FROMBASEOS_BUILD_TAG +ARG DEBIAN_FRONTEND=noninteractive + +ADD apt-package-list.txt /tmp/apt-package-list.txt +RUN apt-get update \ + && apt-get install -y $(tr "\n" " " < /tmp/apt-package-list.txt) \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3 1 + +ARG PYTHONVERSION=3.7.5 +RUN apt-get install -y \ + build-essential \ + zlib1g-dev \ + libncurses5-dev \ + libgdbm-dev \ + libnss3-dev \ + libssl-dev \ + libreadline-dev \ + libffi-dev \ + curl +WORKDIR /tmp +RUN curl https://www.python.org/ftp/python/$PYTHONVERSION/Python-$PYTHONVERSION.tar.xz -o python.tar.xz \ + && tar -xf python.tar.xz \ + && cd Python-$PYTHONVERSION \ + && ./configure --enable-optimizations \ + && make -j 8 \ + && make altinstall \ + && update-alternatives --install /usr/bin/python python /usr/local/bin/python3.7 1 +RUN update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.7 1 \ No newline at end of file diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.apt b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.apt new file mode 100644 index 000000000..3b7fd9541 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.apt @@ -0,0 +1,9 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG +FROM $FROMBASEOS:$FROMBASEOS_BUILD_TAG +ARG DEBIAN_FRONTEND=noninteractive + +ADD apt-package-list.txt /tmp/apt-package-list.txt +RUN apt-get update \ + && apt-get install -y $(tr "\n" " " < /tmp/apt-package-list.txt) \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3 1 diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.arch b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.arch new file mode 100644 index 000000000..c75f5a190 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.arch @@ -0,0 +1,23 @@ +ARG ARCHLINUX_TAG +FROM archlinux:$ARCHLINUX_TAG + +RUN pacman -Syyu --noconfirm \ + && pacman -S --noconfirm \ + base-devel \ + git \ + python3 \ + python-pip \ + wget + +RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 +RUN chmod +x /usr/bin/dumb-init +RUN python -m pip install virtualenv +# AUR for libtinfo5 Source: https://dev.to/cloudx/testing-our-package-build-in-the-docker-world-34p0 +RUN useradd builduser -m \ + && passwd -d builduser \ + && cd /home/builduser \ + && git clone "https://aur.archlinux.org/ncurses5-compat-libs.git" ncurses5-compat-libs \ + && chown builduser -R ncurses5-compat-libs \ + && (printf 'builduser ALL=(ALL) ALL\n' | tee -a /etc/sudoers) \ + && sudo -u builduser bash -c 'gpg --keyserver pool.sks-keyservers.net --recv-keys 702353E0F7E48EDB' \ + && sudo -u builduser bash -c 'cd ~/ncurses5-compat-libs && makepkg -si --noconfirm' \ No newline at end of file diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.centos8 b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.centos8 new file mode 100644 index 000000000..b5fb3eb20 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-build.centos8 @@ -0,0 +1,14 @@ +FROM centos:8 + +RUN yum update -y \ + && dnf group install -y "Development Tools" \ + && yum install -y \ + ncurses-compat-libs \ + python3 \ + python3-devel \ + wget + +RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 +RUN chmod +x /usr/bin/dumb-init +RUN alternatives --set python /usr/bin/python3 \ + && python3 -m pip install virtualenv diff --git a/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-gitian.apt b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-gitian.apt new file mode 100644 index 000000000..5ca2a8757 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/Dockerfile-gitian.apt @@ -0,0 +1,8 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG=latest +FROM electriccoinco/zcashd-build-$FROMBASEOS$FROMBASEOS_BUILD_TAG + +RUN useradd -ms /bin/bash -U debian +USER debian:debian +WORKDIR /home/debian +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/depend/zcash/contrib/ci-builders/buildbot/README.md b/depend/zcash/contrib/ci-builders/buildbot/README.md new file mode 100644 index 000000000..46cd3affb --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/README.md @@ -0,0 +1,42 @@ +# zcashd ci Docker images + +These Dockerfiles can be used to build zcashd. + +The current objective is to build a base image for each distribution that includes the system packages to build zcashd. From `build` images, more targeted images are created. + +The process is meant to be automated, but an example `docker-build.sh` script is included. + + +## build images +`apt-package-list.txt` contains the required packages for debian based systems. + +`Dockerfile-build.apt` uses that file, and some build time arguments, to build apt based build images. + +Currently available images are hosted at +https://hub.docker.com/r/electriccoinco/zcashd-build/tags + + +## gitian images + +`Dockerfile-gitian.apt` uses the build images to generate images for use with [gitian-builder](https://github.com/devrandom/gitian-builder) + +Currently available images are hosted at https://hub.docker.com/r/electriccoinco/zcashd-gitian/tags + + +## bbworker images + +`Dockerfile-bbworker.apt` uses the build images for use with [buildbot](https://buildbot.net) + +- bbworker-buildbot.tac is a required worker boot file (most is overridden at instancitation) +- bbworker-requirements.txt is the python package requirements for the buildbot worker + +Currently available images are hosted at https://hub.docker.com/r/electriccoinco/zcashd-bbworker/tags + + +### Stand alone, best effort images + +Additional buildbot workers for Centos8 and Arch. + +- Dockerfile-bbworker.arch +- Dockerfile-bbworker.centos8 + diff --git a/depend/zcash/contrib/ci-builders/buildbot/apt-package-list.txt b/depend/zcash/contrib/ci-builders/buildbot/apt-package-list.txt new file mode 100644 index 000000000..484f31953 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/apt-package-list.txt @@ -0,0 +1,23 @@ +autoconf +bsdmainutils +build-essential +cmake +curl +g++-aarch64-linux-gnu +git +lcov +libcap-dev +libffi-dev +libtinfo5 +libtool +libssl-dev +libz-dev +libbz2-dev +mingw-w64 +pkg-config +python3 +python3-dev +python3-venv +valgrind +wget +zstd diff --git a/depend/zcash/contrib/ci-builders/buildbot/bbworker-buildbot.tac b/depend/zcash/contrib/ci-builders/buildbot/bbworker-buildbot.tac new file mode 100644 index 000000000..477ae27d3 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/bbworker-buildbot.tac @@ -0,0 +1,40 @@ +import fnmatch +import os +import sys + +from twisted.application import service +from twisted.python.log import FileLogObserver +from twisted.python.log import ILogObserver + +from buildbot_worker.bot import Worker + +# setup worker +basedir = os.environ.get("BUILDBOT_BASEDIR", + os.path.abspath(os.path.dirname(__file__))) +application = service.Application('buildbot-worker') + + +application.setComponent(ILogObserver, FileLogObserver(sys.stdout).emit) +# and worker on the same process! +buildmaster_host = os.environ.get("BUILDMASTER", 'localhost') +port = int(os.environ.get("BUILDMASTER_PORT", 9989)) +workername = os.environ.get("WORKERNAME", 'docker') +passwd = os.environ.get("WORKERPASS") + +# delete the password from the environ so that it is not leaked in the log +blacklist = os.environ.get("WORKER_ENVIRONMENT_BLACKLIST", "WORKERPASS").split() +for name in list(os.environ.keys()): + for toremove in blacklist: + if fnmatch.fnmatch(name, toremove): + del os.environ[name] + +keepalive = 600 +umask = None +maxdelay = 300 +allow_shutdown = None +maxretries = 10 + +s = Worker(buildmaster_host, port, workername, passwd, basedir, + keepalive, umask=umask, maxdelay=maxdelay, + allow_shutdown=allow_shutdown, maxRetries=maxretries) +s.setServiceParent(application) diff --git a/depend/zcash/contrib/ci-builders/buildbot/bbworker-requirements.txt b/depend/zcash/contrib/ci-builders/buildbot/bbworker-requirements.txt new file mode 100644 index 000000000..012268cae --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/bbworker-requirements.txt @@ -0,0 +1,9 @@ +buildbot-worker +pyblake2 +pyflakes +pyutil +pyzmq +requests +simplejson +twisted[tls] +wheel diff --git a/depend/zcash/contrib/ci-builders/buildbot/docker-build.sh b/depend/zcash/contrib/ci-builders/buildbot/docker-build.sh new file mode 100755 index 000000000..fb806e8dc --- /dev/null +++ b/depend/zcash/contrib/ci-builders/buildbot/docker-build.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -exo pipefail + +# Debian 9 +docker build . -f Dockerfile-build-python.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=9 -t electriccoinco/zcashd-build-debian9 +docker push electriccoinco/zcashd-build-debian9 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=debian --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=9 -t electriccoinco/zcashd-bbworker-debian9 +docker push electriccoinco/zcashd-bbworker-debian9 + +# Debian 10 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=10 -t electriccoinco/zcashd-build-debian10 +docker push electriccoinco/zcashd-build-debian10 +docker build . -f Dockerfile-gitian.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=10 -t electriccoinco/zcashd-gitian-debian10 +docker push electriccoinco/zcashd-gitian-debian10 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=debian --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=10 -t electriccoinco/zcashd-bbworker-debian10 +docker push electriccoinco/zcashd-bbworker-debian10 + +# Debian 11 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=bullseye -t electriccoinco/zcashd-build-debian11 +docker push electriccoinco/zcashd-build-debian11 +docker build . -f Dockerfile-gitian.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=bullseye -t electriccoinco/zcashd-gitian-debian11 +docker push electriccoinco/zcashd-gitian-debian11 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=debian --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=bullseye -t electriccoinco/zcashd-bbworker-debian11 +docker push electriccoinco/zcashd-bbworker-debian11 + +# Ubuntu 16.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=16.04 -t electriccoinco/zcashd-build-ubuntu1604 +docker push electriccoinco/zcashd-build-ubuntu1604 +docker build . -f Dockerfile-gitian.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1604 -t electriccoinco/zcashd-gitian-ubuntu1604 +docker push electriccoinco/zcashd-gitian-ubuntu1604 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1604 -t electriccoinco/zcashd-bbworker-ubuntu1604 +docker push electriccoinco/zcashd-bbworker-ubuntu1604 + +# Ubuntu 18.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=18.04 -t electriccoinco/zcashd-build-ubuntu1804 +docker push electriccoinco/zcashd-build-ubuntu1804 +docker build . -f Dockerfile-gitian.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1804 -t electriccoinco/zcashd-gitian-ubuntu1804 +docker push electriccoinco/zcashd-gitian-ubuntu1804 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1804 -t electriccoinco/zcashd-bbworker-ubuntu1804 +docker push electriccoinco/zcashd-bbworker-ubuntu1804 + +# Ubuntu 20.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=20.04 -t electriccoinco/zcashd-build-ubuntu2004 +docker push electriccoinco/zcashd-build-ubuntu2004 +docker build . -f Dockerfile-gitian.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=2004 -t electriccoinco/zcashd-gitian-ubuntu2004 +docker push electriccoinco/zcashd-gitian-ubuntu2004 +docker build . -f Dockerfile-bbworker.apt --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=2004 -t electriccoinco/zcashd-bbworker-ubuntu2004 +docker push electriccoinco/zcashd-bbworker-ubuntu2004 + +# Centos8 +docker build . -f Dockerfile-build.centos8 -t electriccoinco/zcashd-build-centos8 +docker build . -f Dockerfile-bbworker.centos8 -t electriccoinco/zcashd-bbworker-centos8 +docker push electriccoinco/zcashd-build-centos8 +docker push electriccoinco/zcashd-bbworker-centos8 + +# Arch 20200908 +docker build . -f Dockerfile-build.arch --build-arg ARCHLINUX_TAG=20200908 -t electriccoinco/zcashd-build-arch +docker build . -f Dockerfile-bbworker.arch -t electriccoinco/zcashd-bbworker-arch +docker push electriccoinco/zcashd-build-arch +docker push electriccoinco/zcashd-bbworker-arch \ No newline at end of file diff --git a/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.apt b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.apt new file mode 100644 index 000000000..3b7fd9541 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.apt @@ -0,0 +1,9 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG +FROM $FROMBASEOS:$FROMBASEOS_BUILD_TAG +ARG DEBIAN_FRONTEND=noninteractive + +ADD apt-package-list.txt /tmp/apt-package-list.txt +RUN apt-get update \ + && apt-get install -y $(tr "\n" " " < /tmp/apt-package-list.txt) \ + && update-alternatives --install /usr/bin/python python /usr/bin/python3 1 diff --git a/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.arch b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.arch new file mode 100644 index 000000000..f1a1666b2 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.arch @@ -0,0 +1,14 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG +FROM $FROMBASEOS:$FROMBASEOS_BUILD_TAG + +RUN pacman -Syyu --noconfirm \ + && pacman -S --noconfirm \ + base-devel \ + git \ + python3 \ + python-pip \ + ncurses \ + wget + +RUN sudo link /lib/libtinfo.so.6 /lib/libtinfo.so.5 diff --git a/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.centos8 b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.centos8 new file mode 100644 index 000000000..b5fb3eb20 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-build.centos8 @@ -0,0 +1,14 @@ +FROM centos:8 + +RUN yum update -y \ + && dnf group install -y "Development Tools" \ + && yum install -y \ + ncurses-compat-libs \ + python3 \ + python3-devel \ + wget + +RUN wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_amd64 +RUN chmod +x /usr/bin/dumb-init +RUN alternatives --set python /usr/bin/python3 \ + && python3 -m pip install virtualenv diff --git a/depend/zcash/contrib/ci-builders/tekton/Dockerfile-tekton-worker b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-tekton-worker new file mode 100644 index 000000000..6e880dd46 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/Dockerfile-tekton-worker @@ -0,0 +1,11 @@ +ARG FROMBASEOS +ARG FROMBASEOS_BUILD_TAG +FROM electriccoinco/zcashd-build-$FROMBASEOS$FROMBASEOS_BUILD_TAG + +ADD requirements.txt requirements.txt +RUN python -m venv venv \ + && . venv/bin/activate \ + && pip install --upgrade pip \ + && python -m pip install -r requirements.txt + +ADD ./zcash-params /home/.zcash-params diff --git a/depend/zcash/contrib/ci-builders/tekton/README.md b/depend/zcash/contrib/ci-builders/tekton/README.md new file mode 100644 index 000000000..667caf5ab --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/README.md @@ -0,0 +1,35 @@ +# zcashd ci Docker images + +These Dockerfiles can be used to build zcashd. + +The current objective is to build a base image for each distribution that includes the system packages to build zcashd. From `build` images, more targeted images are created. + +The process is meant to be automated, but an example `docker-build.sh` script is included. + + +## build images +`apt-package-tekton-list.txt` contains the required packages for debian based systems. + +`Dockerfile-build.apt` uses that file, and some build time arguments, to build apt based build images. + +Currently available images are hosted at +https://hub.docker.com/r/electriccoinco/zcashd-build/tags + + + +## Tekton worker images + +`Dockerfile-tekton-worker` uses the above build images as a base and layers on toolchains needed for testing + +- requirements.txt is the python package requirements for the tekton worker + +Currently available images are hosted at https://hub.docker.com/r/electriccoinco + + +### Stand alone, best effort images + +Additional Tekton base builders for Centos8 and Arch. Can be used with `Dockerfile-tekton-worker` to create Tekton workers. + +- Dockerfile-build.arch +- Dockerfile-build.centos8 + diff --git a/depend/zcash/contrib/ci-builders/tekton/apt-package-tekton-list.txt b/depend/zcash/contrib/ci-builders/tekton/apt-package-tekton-list.txt new file mode 100644 index 000000000..002363de3 --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/apt-package-tekton-list.txt @@ -0,0 +1,24 @@ +autoconf +bsdmainutils +build-essential +cmake +curl +g++-aarch64-linux-gnu +git +lcov +libcap-dev +libffi-dev +libtinfo5 +libtool +libssl-dev +libz-dev +libbz2-dev +mingw-w64 +pkg-config +python3 +python3-pip +python3-dev +python3-venv +valgrind +wget +zstd diff --git a/depend/zcash/contrib/ci-builders/tekton/docker-build.sh b/depend/zcash/contrib/ci-builders/tekton/docker-build.sh new file mode 100755 index 000000000..1f7c4eb8f --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/docker-build.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -exo pipefail + +# Debian 9 +docker build . -f Dockerfile-build-python.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=9 -t electriccoinco/zcashd-build-debian9 +docker push electriccoinco/zcashd-build-debian9 + +docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=debian --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=9 -t electriccoinco/zcashd-worker-debian9 +docker push electriccoinco/zcashd-worker-debian9 + +# Debian 10 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=10 -t electriccoinco/zcashd-build-debian10 +docker push electriccoinco/zcashd-build-debian10 + +docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=debian --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=10 -t electriccoinco/zcashd-worker-debian10 +docker push electriccoinco/zcashd-worker-debian10 + +# Debian 11 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=bullseye -t electriccoinco/zcashd-build-debian11 +docker push electriccoinco/zcashd-build-debian11 + +docker build . -f Dockerfile-tekton-worker --build-arg FROMBASEOS=debian --build-arg FROMBASEOS_BUILD_TAG=11 -t electriccoinco/zcashd-worker-debian11 +docker push electriccoinco/zcashd-worker-debian11 + +# Ubuntu 16.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=16.04 -t electriccoinco/zcashd-build-ubuntu1604 +docker push electriccoinco/zcashd-build-ubuntu1604 + +docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1604 -t electriccoinco/zcashd-worker-ubuntu1604 +docker push electriccoinco/zcashd-worker-ubuntu1604 + +# Ubuntu 18.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=18.04 -t electriccoinco/zcashd-build-ubuntu1804 +docker push electriccoinco/zcashd-build-ubuntu1804 + +docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=1804 -t electriccoinco/zcashd-worker-ubuntu1804 +docker push electriccoinco/zcashd-worker-ubuntu1804 + +# Ubuntu 20.04 +docker build . -f Dockerfile-build.apt --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=20.04 -t electriccoinco/zcashd-build-ubuntu2004 +docker push electriccoinco/zcashd-build-ubuntu2004 + +docker build . -f Dockerfile-tekton-worker --build-arg BASEOS=ubuntu --build-arg FROMBASEOS=ubuntu --build-arg FROMBASEOS_BUILD_TAG=2004 -t electriccoinco/zcashd-worker-ubuntu2004 +docker push electriccoinco/zcashd-worker-ubuntu2004 + +# Centos8 +docker build . -f Dockerfile-build.centos8 -t electriccoinco/zcashd-build-centos8 +docker push electriccoinco/zcashd-build-centos8 + +docker build . -f Dockerfile-tekton-worker --build-arg FROMBASEOS=centos --build-arg FROMBASEOS_BUILD_TAG=8 -t electriccoinco/zcashd-worker-centos8 +docker push electriccoinco/zcashd-worker-centos8 + +# Arch 20210418.0.20194 +docker build . -f Dockerfile-build.arch --build-arg FROMBASEOS=archlinux --build-arg FROMBASEOS_BUILD_TAG=base-20210418.0.20194 -t electriccoinco/zcashd-build-archlinux +docker push electriccoinco/zcashd-build-archlinux + +docker build . -f Dockerfile-tekton-worker --build-arg FROMBASEOS=archlinux -t electriccoinco/zcashd-worker-archlinux +docker push electriccoinco/zcashd-worker-archlinux \ No newline at end of file diff --git a/depend/zcash/contrib/ci-builders/tekton/requirements.txt b/depend/zcash/contrib/ci-builders/tekton/requirements.txt new file mode 100644 index 000000000..14f84708a --- /dev/null +++ b/depend/zcash/contrib/ci-builders/tekton/requirements.txt @@ -0,0 +1,8 @@ +wheel +pyblake2 +pyflakes +pyutil +pyzmq +requests +simplejson +twisted[tls] diff --git a/depend/zcash/contrib/ci-workers/README.md b/depend/zcash/contrib/ci-workers/README.md new file mode 100644 index 000000000..8ce9dc764 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/README.md @@ -0,0 +1,62 @@ +# Zcash CI workers + +This folder contains the Ansible playbooks for configuring a fresh OS +installation for use as a Buildbot worker in Zcash's CI. + +# Criteria for Adding Workers + +a. Don't add workers until users complain about a problem on a platform that + doesn't yet have workers. However, if we anticipate many users will use a + platform, we may pre-emptively add an unsupported worker for it. + +b. Prioritize the platforms that seem to have the most users. + +c. When adding workers, start by adding workers for the "most common" variant of + any distro. Then if users later encounter problems with a sub-variant, we can + consider adding new workers at that point. Example: add Ubuntu Desktop before + Xubuntu, on the assumption the former has a larger population base, and the + latter only materially differs in the GUI. + +# Setting up a latent worker on Amazon EC2 + +1. Add a regular (non-latent) worker to the master.cfg for dev-ci.z.cash, and + deploy the changes. + - This enables the Ansible playbook to run to completion, ending in the worker + connecting to the master. + +2. Start a basic EC2 instance using the template AMI for the target OS. + - Choose the smallest instance size, it won't be used for building Zcash. + +3. Figure out which user to log into the instance with. + - E.g. for the Ubuntu template, use "ubuntu" instead of "root" + - If you get an Ansible error later with a message like "Failed to connect to + the host via ssh: Received message too long 1349281121\r\n", that means the + instance is sending a text string in response to the SSH connection, and the + Ansible protocol is balking. Try manually logging in with the same + credentials to diagnose. + +4. Create `inventory/hosts` containing the following: + + [zcash-ci-worker-unix] + some-name ansible_host= ansible_ssh_user= + +5. Run `ansible-playbook -e buildbot_worker_host_template=templates/host.ec2.j2 -i inventory/hosts unix.yml`, + passing in the worker's Buildbot name and password. + - After a successful run, the worker should be connected to dev-ci.z.cash and + visible in its worker list. + +6. Create an AMI from the instance. This is the worker AMI to put into the + master.cfg for dev-ci.z.cash. + - 16 GB of storage should be sufficient. + +7. SSH into the instance, and edit the worker config to connect to ci.z.cash. + +8. Create an AMI from the instance. This is the worker AMI to put into the + master.cfg for ci.z.cash. + - 16 GB of storage should be sufficient. + +9. Delete the instance (it is no longer needed). + +10. Edit the master.cfg to turn the new worker into a latent (using the new AMI + IDs), add it to the appropriate worker groups, set up new builders etc. + - Deploy this via the normal PR review process. diff --git a/depend/zcash/contrib/ci-workers/ansible.cfg b/depend/zcash/contrib/ci-workers/ansible.cfg new file mode 100644 index 000000000..c58fea3c0 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/ansible.cfg @@ -0,0 +1,2 @@ +[ssh_connection] +pipelining = True diff --git a/depend/zcash/contrib/ci-workers/files/bashrc b/depend/zcash/contrib/ci-workers/files/bashrc new file mode 100644 index 000000000..aaad18b92 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/files/bashrc @@ -0,0 +1,2 @@ +export PATH=$HOME/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +export EDITOR=vim diff --git a/depend/zcash/contrib/ci-workers/grind.yml b/depend/zcash/contrib/ci-workers/grind.yml new file mode 100644 index 000000000..ef7e5758e --- /dev/null +++ b/depend/zcash/contrib/ci-workers/grind.yml @@ -0,0 +1,27 @@ +--- +# Configure a Buildbot worker +- include: unix.yml + +- name: Install grind-specific worker dependencies + hosts: zcash-ci-worker-unix + become: true + + vars_files: + - vars/default.yml + + tasks: + - name: Get dependencies for distribution + include_vars: "{{ item }}" + with_first_found: + - files: + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int }}.yml" + - "vars/{{ ansible_distribution }}.yml" + - "vars/{{ ansible_os_family }}.yml" + skip: true + + - name: Install required packages + package: + name: "{{ item }}" + state: present + with_items: "{{ grind_deps }}" diff --git a/depend/zcash/contrib/ci-workers/tasks/install-brew.yml b/depend/zcash/contrib/ci-workers/tasks/install-brew.yml new file mode 100644 index 000000000..5faedad0b --- /dev/null +++ b/depend/zcash/contrib/ci-workers/tasks/install-brew.yml @@ -0,0 +1,10 @@ +--- +- name: Check if brew is installed + stat: + path: /usr/local/bin/brew + register: brew_check + +- name: Fail if brew is unavailable + fail: + msg: 'brew is not installed! Please install Homebrew: https://docs.brew.sh/Installation.html' + when: not brew_check.stat.exists diff --git a/depend/zcash/contrib/ci-workers/tasks/install-pip.yml b/depend/zcash/contrib/ci-workers/tasks/install-pip.yml new file mode 100644 index 000000000..8beff50ef --- /dev/null +++ b/depend/zcash/contrib/ci-workers/tasks/install-pip.yml @@ -0,0 +1,8 @@ +--- +- name: Fetch pip installer + get_url: + url: https://bootstrap.pypa.io/get-pip.py + dest: /tmp/get-pip.py + +- name: Install pip + command: "{{ ansible_python.executable }} /tmp/get-pip.py" diff --git a/depend/zcash/contrib/ci-workers/templates/buildbot-worker.plist.j2 b/depend/zcash/contrib/ci-workers/templates/buildbot-worker.plist.j2 new file mode 100644 index 000000000..225c73b8a --- /dev/null +++ b/depend/zcash/contrib/ci-workers/templates/buildbot-worker.plist.j2 @@ -0,0 +1,23 @@ + + + + + Label + net.buildbot.worker + ProgramArguments + + {{ buildbot_worker_dir }}/venv/bin/buildbot-worker + start + {{ buildbot_worker_name }} + + WorkingDirectory + {{ buildbot_worker_dir }} + UserName + {{ buildbot_worker_user }} + KeepAlive + + NetworkState + + + + diff --git a/depend/zcash/contrib/ci-workers/templates/buildbot-worker.service.j2 b/depend/zcash/contrib/ci-workers/templates/buildbot-worker.service.j2 new file mode 100644 index 000000000..625323be6 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/templates/buildbot-worker.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=Buildbot worker +Wants=network.target +After=network.target + +[Service] +Type=forking +PIDFile={{ buildbot_worker_dir }}/{{ buildbot_worker_name }}/twistd.pid +WorkingDirectory={{ buildbot_worker_dir }} +ExecStart={{ buildbot_worker_dir }}/venv/bin/buildbot-worker start {{ buildbot_worker_name }} +ExecReload={{ buildbot_worker_dir }}/venv/bin/buildbot-worker restart {{ buildbot_worker_name }} +ExecStop={{ buildbot_worker_dir }}/venv/bin/buildbot-worker stop {{ buildbot_worker_name }} +Restart=always +User={{ buildbot_worker_user }} + +[Install] +WantedBy=multi-user.target diff --git a/depend/zcash/contrib/ci-workers/templates/host.ec2.j2 b/depend/zcash/contrib/ci-workers/templates/host.ec2.j2 new file mode 100644 index 000000000..dee692e02 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/templates/host.ec2.j2 @@ -0,0 +1 @@ +OS: {{ ansible_distribution }} {{ ansible_distribution_version }} diff --git a/depend/zcash/contrib/ci-workers/templates/host.j2 b/depend/zcash/contrib/ci-workers/templates/host.j2 new file mode 100644 index 000000000..65c4cb709 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/templates/host.j2 @@ -0,0 +1,3 @@ +OS: {{ ansible_distribution }} {{ ansible_distribution_version }} +Memory: {{ ansible_memtotal_mb }} MB +CPU: {{ ansible_processor if ansible_processor is string else ansible_processor[1] }} ({{ ansible_processor_cores }} cores) diff --git a/depend/zcash/contrib/ci-workers/unix.yml b/depend/zcash/contrib/ci-workers/unix.yml new file mode 100644 index 000000000..cbb693401 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/unix.yml @@ -0,0 +1,209 @@ +--- +- name: Configure a Buildbot worker for Zcash CI + hosts: zcash-ci-worker-unix + become: true + gather_facts: False + + vars_files: + - vars/default.yml + - vars/buildbot.yml + + vars_prompt: + - name: "buildbot_worker_admin" + prompt: "Admin details" + default: "Zcash " + - name: "buildbot_worker_name" + prompt: "Buildbot worker name (provided by ZECC)" + private: no + - name: "buildbot_worker_password" + prompt: "Buildbot worker password (provided by ZECC)" + + pre_tasks: + - name: Install Python 2.7 for Ansible and Buildbot + raw: test -e /usr/bin/python || test -e /usr/bin/python2 || test -e /usr/bin/python2.7 || test -e /usr/local/bin/python2.7 || (test -e /usr/bin/apt && apt -qqy update && apt install -qqy python) || (test -e /usr/bin/dnf && dnf install -qqy python2) || (test -e /usr/sbin/pkg && pkg install -qqy python2) + register: output + changed_when: + - output.stdout != "" + - output.stdout != "\r\n" + + - name: Check if Python is in the configured location + raw: test -e {{ ansible_python_interpreter }} + ignore_errors: true + register: python_check + when: ansible_python_interpreter is defined + + - name: Fail if configured Python is unavailable + fail: + msg: "Python is not accessible at {{ ansible_python_interpreter }} on this host! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary." + when: ansible_python_interpreter is defined and python_check.rc == 1 + + - name: Check if Python is in the default location + raw: test -e /usr/bin/python + ignore_errors: true + register: python_check + when: ansible_python_interpreter is undefined + + - name: Fail if default Python is unavailable + fail: + msg: Python is not accessible at /usr/bin/python on this host! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary. + when: ansible_python_interpreter is undefined and python_check.rc == 1 + + - name: Gathering Facts + setup: + tags: deps + + - name: Fail if Python is the wrong version + fail: + msg: "The Python binary at {{ ansible_python.executable }} is version {{ ansible_python_version }}! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary." + when: ansible_python.version.major != 2 or ansible_python.version.minor != 7 + + tasks: + - name: Get dependencies for distribution + include_vars: "{{ item }}" + with_first_found: + - files: + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int }}.yml" + - "vars/{{ ansible_distribution }}.yml" + - "vars/{{ ansible_os_family }}.yml" + skip: true + tags: deps + + - name: Collate dependencies + set_fact: + package_deps: "{{ buildbot_deps + fetch_deps + conf_deps + build_deps + link_deps + dist_deps }}" + python_modules: "{{ buildbot_modules + rpc_test_modules }}" + tags: deps + + - name: Install Homebrew [MacOSX] + include: tasks/install-brew.yml + when: ansible_distribution == 'MacOSX' + tags: deps + + - name: Update rolling release [Arch Linux] + pacman: + update_cache: yes + upgrade: yes + when: ansible_distribution == 'Archlinux' + tags: deps + + - name: Install required packages + package: + name: "{{ item }}" + state: present + with_items: "{{ package_deps }}" + become_user: "{{ ansible_ssh_user if ansible_distribution == 'MacOSX' else 'root' }}" + tags: deps + + - name: Install pip [CentOS, MacOSX] + include: tasks/install-pip.yml + when: ansible_distribution in ['CentOS', 'MacOSX'] + + - name: Install required Python system modules + pip: + name: "{{ item }}" + state: latest + executable: "{{ '/usr/local/bin/pip' if ansible_distribution == 'MacOSX' else omit }}" + with_items: "{{ system_modules }}" + + - name: Set up the Buildbot worker user + user: + name: "{{ buildbot_worker_user }}" + comment: Buildbot worker + shell: /bin/bash + state: present + + - name: Get absolute path to Buildbot worker home directory + command: echo ~ + register: homedir + become_user: "{{ buildbot_worker_user }}" + + - name: Save absolute path to Buildbot worker home directory + set_fact: + buildbot_worker_dir: "{{ homedir.stdout }}" + + - name: Install required Python modules + pip: + name: "{{ item }}" + state: latest + virtualenv: "~{{ buildbot_worker_user }}/venv" + virtualenv_command: "{{ '/usr/local/bin/virtualenv' if ansible_distribution == 'MacOSX' else omit }}" + with_items: "{{ python_modules }}" + become_user: "{{ buildbot_worker_user }}" + notify: restart buildbot-worker + + - name: Create Buildbot worker + command: > + ~{{ buildbot_worker_user }}/venv/bin/buildbot-worker create-worker ~/{{ buildbot_worker_name }} + {{ buildbot_master_host }}:{{ buildbot_master_port }} + {{ buildbot_worker_name|quote }} {{ buildbot_worker_password|quote }} + args: + creates: "~/{{ buildbot_worker_name }}/buildbot.tac" + become_user: "{{ buildbot_worker_user }}" + + - name: Set admin details for Buildbot worker + copy: + content: "{{ buildbot_worker_admin }}" + dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/admin" + owner: "{{ buildbot_worker_user }}" + group: "{{ omit if ansible_distribution == 'MacOSX' else buildbot_worker_user }}" + mode: "0644" + + - name: Set host details for Buildbot worker + template: + src: "{{ buildbot_worker_host_template }}" + dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/host" + owner: "{{ buildbot_worker_user }}" + group: "{{ omit if ansible_distribution == 'MacOSX' else buildbot_worker_user }}" + mode: "0644" + + - name: Install custom bashrc for virtualenv + copy: + src: bashrc + dest: "~{{ buildbot_worker_user }}/.bashrc" + owner: "{{ buildbot_worker_user }}" + group: "{{ omit if ansible_distribution == 'MacOSX' else buildbot_worker_user }}" + mode: "0644" + + - name: Copy Buildbot worker systemd service unit + template: + src: templates/buildbot-worker.service.j2 + dest: "/etc/systemd/system/buildbot-worker.service" + owner: root + group: root + mode: "0644" + when: ansible_distribution != 'MacOSX' + notify: reload systemd + + - name: Copy Buildbot worker launchd service unit + template: + src: templates/buildbot-worker.plist.j2 + dest: "/Library/LaunchDaemons/net.buildbot.worker.plist" + owner: root + group: wheel + mode: "0644" + when: ansible_distribution == 'MacOSX' + + - name: Start Buildbot worker + service: + name: buildbot-worker + state: started + enabled: yes + when: ansible_distribution != 'MacOSX' + + - name: Load Buildbot worker service [MacOSX] + command: launchctl load /Library/LaunchDaemons/net.buildbot.worker.plist + when: ansible_distribution == 'MacOSX' + + - name: Start Buildbot worker [MacOSX] + command: launchctl start net.buildbot.worker + when: ansible_distribution == 'MacOSX' + + handlers: + - name: restart buildbot-worker + service: + name: buildbot-worker + state: restarted + + - name: reload systemd + command: /bin/systemctl daemon-reload diff --git a/depend/zcash/contrib/ci-workers/vars/Archlinux.yml b/depend/zcash/contrib/ci-workers/vars/Archlinux.yml new file mode 100644 index 000000000..50e5577c3 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/Archlinux.yml @@ -0,0 +1,7 @@ +--- +buildbot_deps: + - python2-pip +build_deps: + - cmake + - multilib/gcc + - make diff --git a/depend/zcash/contrib/ci-workers/vars/CentOS.yml b/depend/zcash/contrib/ci-workers/vars/CentOS.yml new file mode 100644 index 000000000..f577af5c0 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/CentOS.yml @@ -0,0 +1,13 @@ +--- +buildbot_deps: [] # Empty to remove python-pip +build_deps: + - bzip2 + - cmake + - gcc + - gcc-c++ + - make + - patch +dist_deps: + - pkgconfig # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - python-devel + - redhat-rpm-config diff --git a/depend/zcash/contrib/ci-workers/vars/Debian.yml b/depend/zcash/contrib/ci-workers/vars/Debian.yml new file mode 100644 index 000000000..b6a46f0cd --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/Debian.yml @@ -0,0 +1,6 @@ +--- +build_deps: + - build-essential # Depends on g++, libc6-dev, make + - cmake +dist_deps: + - python-dev diff --git a/depend/zcash/contrib/ci-workers/vars/Fedora.yml b/depend/zcash/contrib/ci-workers/vars/Fedora.yml new file mode 100644 index 000000000..2a7351c69 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/Fedora.yml @@ -0,0 +1,11 @@ +--- +build_deps: + - cmake + - gcc + - gcc-c++ + - make + - patch +dist_deps: + - pkgconfig # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - python-devel + - redhat-rpm-config diff --git a/depend/zcash/contrib/ci-workers/vars/FreeBSD.yml b/depend/zcash/contrib/ci-workers/vars/FreeBSD.yml new file mode 100644 index 000000000..4b1f01997 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/FreeBSD.yml @@ -0,0 +1,10 @@ +--- +buildbot_deps: + - py27-pip +build_deps: + - cmake + - gcc + - gmake +dist_deps: + - bash + - pkgconf # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in diff --git a/depend/zcash/contrib/ci-workers/vars/MacOSX.yml b/depend/zcash/contrib/ci-workers/vars/MacOSX.yml new file mode 100644 index 000000000..80b1ae608 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/MacOSX.yml @@ -0,0 +1,6 @@ +--- +buildbot_deps: + - coreutils # For gnproc etc. +# Most are already installed +build_deps: + - cmake diff --git a/depend/zcash/contrib/ci-workers/vars/Ubuntu.yml b/depend/zcash/contrib/ci-workers/vars/Ubuntu.yml new file mode 100644 index 000000000..0d0f584b4 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/Ubuntu.yml @@ -0,0 +1,4 @@ +--- +build_deps: + - build-essential # Depends on g++, libc6-dev, make + - cmake diff --git a/depend/zcash/contrib/ci-workers/vars/buildbot.yml b/depend/zcash/contrib/ci-workers/vars/buildbot.yml new file mode 100644 index 000000000..38e3fd25a --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/buildbot.yml @@ -0,0 +1,5 @@ +--- +buildbot_worker_user: zcbbworker +buildbot_master_host: dev-ci.z.cash +buildbot_master_port: 9899 +buildbot_worker_host_template: templates/host.j2 diff --git a/depend/zcash/contrib/ci-workers/vars/default.yml b/depend/zcash/contrib/ci-workers/vars/default.yml new file mode 100644 index 000000000..a0b0da9e6 --- /dev/null +++ b/depend/zcash/contrib/ci-workers/vars/default.yml @@ -0,0 +1,53 @@ +--- +# These variables can be overridden in distribution files. + +# Dependencies required to install Buildbot +buildbot_deps: + - python-pip # So we can install Python modules + +# Dependencies required to download files +fetch_deps: + - curl # For depends/ + - git + - wget # For zcutil/fetch-params.sh + +# Dependencies required to configure Zcash +conf_deps: + - autoconf + - automake + - m4 + - pkg-config + +# Dependencies required to compile Zcash +build_deps: + - cmake + - g++ + - gcc + - make + +# Dependencies required to link Zcash +link_deps: + - libtool + +# Additional distribution-specific dependencies +dist_deps: [] + +# Additional grind-specific dependencies +grind_deps: + - lcov + - valgrind + +# Python modules required on the system +system_modules: + - virtualenv + +# Python modules required for a Zcash Buildbot worker +buildbot_modules: + - pip # Needs to be updated first so Buildbot installs + - buildbot-worker + - pyflakes + +# Python modules required to run the Zcash RPC test suite +rpc_test_modules: + - pyblake2 + - pyzmq diff --git a/depend/zcash/contrib/debian/changelog b/depend/zcash/contrib/debian/changelog new file mode 100644 index 000000000..00834e186 --- /dev/null +++ b/depend/zcash/contrib/debian/changelog @@ -0,0 +1,593 @@ +zcash (5.0.0) stable; urgency=medium + + * 5.0.0 release. + + -- Electric Coin Company Tue, 10 May 2022 19:52:28 -0600 + +zcash (5.0.0~rc1) stable; urgency=medium + + * 5.0.0-rc1 release. + + -- Electric Coin Company Mon, 09 May 2022 15:35:33 +0000 + +zcash (4.7.0) stable; urgency=medium + + * 4.7.0 release. + + -- Electric Coin Company Wed, 13 Apr 2022 22:04:00 -0600 + +zcash (4.6.0+2) stable; urgency=medium + + * 4.6.0-2 release. + + -- Electric Coin Company Mon, 04 Apr 2022 21:53:34 +0000 + +zcash (4.7.0~rc1) stable; urgency=medium + + * 4.7.0-rc1 release. + + -- Electric Coin Company Tue, 22 Mar 2022 21:14:02 +0000 + +zcash (4.6.0+1) stable; urgency=medium + + * 4.6.0-1 release. + + -- Electric Coin Company Wed, 05 Jan 2022 20:18:43 +0000 + +zcash (4.6.0) stable; urgency=medium + + * 4.6.0 release. + + -- Electric Coin Company Thu, 23 Dec 2021 00:35:41 +0000 + +zcash (4.6.0~rc1) stable; urgency=medium + + * 4.6.0-rc1 release. + + -- Electric Coin Company Sat, 18 Dec 2021 04:25:50 +0000 + +zcash (4.5.1+1) stable; urgency=medium + + * 4.5.1-1 release. + + -- Electric Coin Company Fri, 08 Oct 2021 17:03:31 +0000 + +zcash (4.5.1) stable; urgency=medium + + * 4.5.1 release. + + -- Electric Coin Company Wed, 29 Sep 2021 01:49:51 +0100 + +zcash (4.5.0) stable; urgency=medium + + * 4.5.0 release. + + -- Electric Coin Company Thu, 23 Sep 2021 04:20:16 +0100 + +zcash (4.5.0~rc1) stable; urgency=medium + + * 4.5.0-rc1 release. + + -- Electric Coin Company Thu, 16 Sep 2021 23:34:14 +0100 + +zcash (4.4.1) stable; urgency=medium + + * 4.4.1 release. + + -- Electric Coin Company Wed, 09 Jun 2021 23:19:49 +0100 + +zcash (4.4.1~rc1) stable; urgency=medium + + * 4.4.1-rc1 release. + + -- Electric Coin Company Tue, 08 Jun 2021 22:45:20 +0100 + +zcash (4.4.0) stable; urgency=medium + + * 4.4.0 release. + + -- Electric Coin Company Thu, 15 Apr 2021 16:55:39 +1200 + +zcash (4.4.0~rc1) stable; urgency=medium + + * 4.4.0-rc1 release. + + -- Electric Coin Company Fri, 09 Apr 2021 17:40:36 +1200 + +zcash (4.3.0) stable; urgency=medium + + * 4.3.0 release. + + -- Electric Coin Company Wed, 24 Feb 2021 20:17:10 +0000 + +zcash (4.3.0~rc1) stable; urgency=medium + + * 4.3.0-rc1 release. + + -- Electric Coin Company Fri, 19 Feb 2021 22:05:06 +0000 + +zcash (4.2.0) stable; urgency=medium + + * 4.2.0 release. + + -- Electric Coin Company Mon, 21 Dec 2020 12:55:52 -0700 + +zcash (4.2.0~rc1) stable; urgency=medium + + * 4.2.0-rc1 release. + + -- Electric Coin Company Sat, 19 Dec 2020 09:53:28 -0700 + +zcash (4.1.1) stable; urgency=medium + + * 4.1.1 release. + + -- Electric Coin Company Mon, 16 Nov 2020 10:23:40 -0700 + +zcash (4.1.0) stable; urgency=medium + + * 4.1.0 release. + + -- Electric Coin Company Mon, 02 Nov 2020 13:40:54 -0700 + +zcash (4.1.0~rc1) stable; urgency=medium + + * 4.1.0-rc1 release. + + -- Electric Coin Company Wed, 28 Oct 2020 02:51:45 +0800 + +zcash (4.0.0) stable; urgency=medium + + * 4.0.0 release. + + -- Electric Coin Company Tue, 01 Sep 2020 13:31:19 -0600 + +zcash (4.0.0~rc1) stable; urgency=medium + + * 4.0.0-rc1 release. + + -- Electric Coin Company Wed, 26 Aug 2020 10:17:07 -0600 + +zcash (3.1.0) stable; urgency=medium + + * 3.1.0 release. + + -- Electric Coin Company Tue, 28 Jul 2020 07:02:06 +0800 + +zcash (3.1.0~rc2) stable; urgency=medium + + * 3.1.0-rc2 release. + + -- Electric Coin Company Wed, 15 Jul 2020 21:51:09 +0800 + +zcash (3.1.0~rc1) stable; urgency=medium + + * 3.1.0-rc1 release. + + -- Electric Coin Company Tue, 14 Jul 2020 14:38:11 +0800 + +zcash (3.0.0) stable; urgency=medium + + * 3.0.0 release. + + -- Electric Coin Company Fri, 22 May 2020 11:48:24 -0600 + +zcash (3.0.0~rc1) stable; urgency=medium + + * 3.0.0-rc1 release. + + -- Electric Coin Company Thu, 21 May 2020 07:34:53 -0600 + +zcash (2.1.2+3) stable; urgency=medium + + * 2.1.2-3 release. + + -- Electric Coin Company Fri, 08 May 2020 12:41:23 -0600 + +zcash (2.1.2+2) stable; urgency=medium + + * 2.1.2-2 release. + + -- Electric Coin Company Fri, 08 May 2020 11:43:55 -0600 + +zcash (2.1.2+1) stable; urgency=medium + + * 2.1.2-1 release. + + -- Electric Coin Company Wed, 06 May 2020 10:52:57 -0600 + +zcash (2.1.2) stable; urgency=medium + + * 2.1.2 release. + + -- Electric Coin Company Wed, 22 Apr 2020 10:46:06 -0600 + +zcash (2.1.2~rc1) stable; urgency=medium + + * 2.1.2-rc1 release. + + -- Electric Coin Company Wed, 15 Apr 2020 17:47:45 -0600 + +zcash (2.1.1+1) stable; urgency=critical + + * 2.1.1-1 release. + + -- Electric Coin Company Thu, 06 Feb 2020 16:53:19 -0700 + +zcash (2.1.1) stable; urgency=medium + + * 2.1.1 release. + + -- Electric Coin Company Fri, 17 Jan 2020 10:27:31 -0700 + +zcash (2.1.1~rc2) stable; urgency=medium + + * 2.1.1-rc2 release. + + -- Electric Coin Company Mon, 13 Jan 2020 17:56:29 -0700 + +zcash (2.1.1~rc1) stable; urgency=medium + + * 2.1.1-rc1 release. + + -- Electric Coin Company Tue, 07 Jan 2020 20:13:52 -0700 + +zcash (2.1.0+1) stable; urgency=medium + + * 2.1.0-1 release. + + -- Electric Coin Company Fri, 08 Nov 2019 18:56:32 +0000 + +zcash (2.1.0) stable; urgency=medium + + * 2.1.0 release. + + -- Electric Coin Company Sat, 02 Nov 2019 11:01:00 -0600 + +zcash (2.1.0~rc1) stable; urgency=medium + + * 2.1.0-rc1 release. + + -- Electric Coin Company Tue, 22 Oct 2019 14:52:02 -0600 + +zcash (2.0.7+3) stable; urgency=critical + + * 2.0.7-3 release. + + -- Electric Coin Company Tue, 24 Sep 2019 21:01:13 +0100 + +zcash (2.0.7+2) stable; urgency=medium + + * 2.0.7-2 release. + + -- Electric Coin Company Fri, 30 Aug 2019 17:47:52 -0600 + +zcash (2.0.7+1) stable; urgency=medium + + * 2.0.7-1 release. + + -- Electric Coin Company Thu, 29 Aug 2019 13:07:52 -0600 + +zcash (2.0.7) stable; urgency=medium + + * 2.0.7 release. + + -- Electric Coin Company Mon, 19 Aug 2019 15:09:14 -0600 + +zcash (2.0.7~rc1) stable; urgency=medium + + * 2.0.7-rc1 release. + + -- Electric Coin Company Fri, 09 Aug 2019 17:05:51 -0600 + +zcash (2.0.6) stable; urgency=medium + + * 2.0.6 release. + + -- Electric Coin Company Wed, 19 Jun 2019 00:28:06 +0100 + +zcash (2.0.6~rc1) stable; urgency=medium + + * 2.0.6-rc1 release. + + -- Electric Coin Company Wed, 12 Jun 2019 16:36:57 +0100 + +zcash (2.0.5+2) stable; urgency=medium + + * 2.0.5-2 release. + + -- Electric Coin Company Wed, 15 May 2019 09:56:01 -0600 + +zcash (2.0.5+1) stable; urgency=medium + + * 2.0.5-1 release. + + -- Electric Coin Company Wed, 08 May 2019 06:57:28 -0600 + +zcash (2.0.5) stable; urgency=medium + + * 2.0.5 release. + + -- Electric Coin Company Fri, 03 May 2019 16:35:30 -0600 + +zcash (2.0.5~rc1) stable; urgency=medium + + * 2.0.5-rc1 release. + + -- Electric Coin Company Wed, 01 May 2019 14:16:08 -0600 + +zcash (2.0.4) stable; urgency=medium + + * 2.0.4 release. + + -- Electric Coin Company Tue, 26 Mar 2019 11:29:21 -0700 + +zcash (2.0.4~rc1) stable; urgency=medium + + * 2.0.4-rc1 release. + + -- Zcash Company Wed, 20 Mar 2019 09:39:43 -0700 + +zcash (2.0.3) stable; urgency=medium + + * 2.0.3 release. + + -- Zcash Company Mon, 11 Feb 2019 09:16:09 -0800 + +zcash (2.0.3~rc1) stable; urgency=medium + + * 2.0.3-rc1 release. + + -- Zcash Company Mon, 04 Feb 2019 12:05:43 -0800 + +zcash (2.0.2) stable; urgency=medium + + * 2.0.2 release. + + -- Zcash Company Wed, 28 Nov 2018 11:09:08 -0800 + +zcash (2.0.2~rc1) stable; urgency=medium + + * 2.0.2-rc1 release. + + -- Zcash Company Sun, 18 Nov 2018 10:19:49 -0800 + +zcash (2.0.1) stable; urgency=medium + + * 2.0.1 release. + + -- Zcash Company Sun, 14 Oct 2018 13:40:30 -0700 + +zcash (2.0.1~rc1) stable; urgency=medium + + * 2.0.1-rc1 release. + + -- Zcash Company Mon, 08 Oct 2018 12:40:54 -0700 + +zcash (2.0.0) stable; urgency=medium + + * 2.0.0 release. + + -- Zcash Company Wed, 15 Aug 2018 17:57:50 -0700 + +zcash (2.0.0~rc1) stable; urgency=medium + + * 2.0.0-rc1 release. + + -- Zcash Company Thu, 09 Aug 2018 16:56:56 +0000 + +zcash (1.1.2) stable; urgency=medium + + * 1.1.2 release. + + -- Zcash Company Sun, 01 Jul 2018 20:12:33 -0700 + +zcash (1.1.2~rc1) stable; urgency=medium + + * 1.1.2-rc1 release. + + -- Zcash Company Fri, 22 Jun 2018 17:03:41 -0700 + +zcash (1.1.1) stable; urgency=medium + + * 1.1.1 release. + + -- Zcash Company Fri, 25 May 2018 15:49:34 +1200 + +zcash (1.1.1~rc2) stable; urgency=medium + + * 1.1.1-rc2 release. + + -- Zcash Company Wed, 23 May 2018 09:28:50 -0700 + +zcash (1.1.1~rc1) stable; urgency=medium + + * 1.1.1-rc1 release. + + -- Zcash Company Sat, 19 May 2018 10:16:14 +1200 + +zcash (1.1.0) stable; urgency=medium + + * 1.1.0 release. + + -- Zcash Company Wed, 11 Apr 2018 20:15:29 -0600 + +zcash (1.1.0~rc1) stable; urgency=medium + + * 1.1.0-rc1 release. + + -- Zcash Company Thu, 05 Apr 2018 03:26:17 +0100 + +zcash (1.0.15) stable; urgency=medium + + * 1.0.15 release. + + -- Zcash Company Wed, 28 Feb 2018 16:58:19 +0000 + +zcash (1.0.15~rc1) stable; urgency=medium + + * 1.0.15-rc1 release. + + -- Zcash Company Sat, 24 Feb 2018 04:20:05 +0000 + +zcash (1.0.14) stable; urgency=medium + + * 1.0.14 release. + + -- Zcash Company Wed, 03 Jan 2018 23:54:16 +0100 + +zcash (1.0.14~rc1) stable; urgency=medium + + * 1.0.14-rc1 release. + + -- Zcash Company Fri, 22 Dec 2017 10:12:41 +0000 + +zcash (1.0.13) stable; urgency=medium + + * 1.0.13 release. + + -- Zcash Company Mon, 20 Nov 2017 12:31:53 +0000 + +zcash (1.0.13~rc2) stable; urgency=medium + + * 1.0.13-rc2 release. + + -- Zcash Company Fri, 17 Nov 2017 18:01:08 +0000 + +zcash (1.0.13~rc1) stable; urgency=medium + + * 1.0.13-rc1 release. + + -- Zcash Company Wed, 15 Nov 2017 00:02:21 +0000 + +zcash (1.0.12) stable; urgency=medium + + * 1.0.12 release. + + -- Zcash Company Thu, 28 Sep 2017 01:26:44 +0100 + +zcash (1.0.12~rc1) stable; urgency=medium + + * 1.0.12-rc1 release. + + -- Zcash Company Sat, 23 Sep 2017 10:51:36 +0100 + +zcash (1.0.11) stable; urgency=medium + + * 1.0.11 release. + + -- Zcash Company Tue, 15 Aug 2017 10:06:25 +0100 + +zcash (1.0.11~rc1) stable; urgency=medium + + * 1.0.11-rc1 release. + + -- Zcash Company Tue, 01 Aug 2017 17:12:52 +0200 + +zcash (1.0.10+1) stable; urgency=medium + + * 1.0.10-1 release. + + -- Zcash Company Fri, 23 Jun 2017 19:50:41 -0700 + +zcash (1.0.10) stable; urgency=medium + + * 1.0.10 release. + + -- Zcash Company Thu, 22 Jun 2017 15:13:04 +1200 + +zcash (1.0.9) stable; urgency=medium + + * 1.0.9 release. + + -- Zcash Company Wed, 24 May 2017 12:51:06 -0700 + +zcash (1.0.8+1) jessie; urgency=high + + * 1.0.8-1 release. + + -- Zcash Company Thu, 13 Apr 2017 20:20:37 -0700 + +zcash (1.0.8) jessie; urgency=medium + + * 1.0.8 release. + + -- Zcash Company Mon, 27 Mar 2017 21:30:07 +0100 + +zcash (1.0.7+1) jessie; urgency=medium + + * 1.0.7-1 release. + + -- Zcash Company Wed, 08 Mar 2017 13:51:11 -0800 + +zcash (1.0.7) jessie; urgency=medium + + * 1.0.7 release. + + -- Zcash Company Fri, 03 Mar 2017 20:55:04 -0800 + +zcash (1.0.6) jessie; urgency=medium + + * 1.0.6 release. + + -- Zcash Company Fri, 10 Feb 2017 10:23:00 -0800 + +zcash (1.0.5) jessie; urgency=medium + + * 1.0.5 release. + + -- Zcash Company Thu, 19 Jan 2017 19:23:40 -0700 + +zcash (1.0.4) jessie; urgency=medium + + * 1.0.4 release. + + -- Zcash Company Thu, 15 Dec 2016 16:46:14 +1300 + +zcash (1.0.3) jessie; urgency=medium + + * 1.0.3 release. + + -- Zcash Company Wed, 17 Nov 2016 15:56:00 -0700 + +zcash (1.0.2) jessie; urgency=medium + + * 1.0.2 release. + + -- Zcash Company Mon, 07 Nov 2016 19:01:35 -0600 + +zcash (1.0.1) jessie; urgency=medium + + * 1.0.1 release. + + -- Zcash Company Thu, 03 Nov 2016 23:21:09 -0500 + +zcash (1.0.0-sprout) jessie; urgency=medium + + * 1.0.0 release. + + -- Zcash Company Fri, 28 Oct 2016 03:00:50 -0700 + +zcash (1.0.0-rc4) jessie; urgency=medium + + * 1.0.0-rc4 release. + + -- Zcash Company Thu, 27 Oct 2016 13:36:00 +0100 + +zcash (1.0.0-rc3) jessie; urgency=medium + + * 1.0.0-rc3 release. + + -- Zcash Company Wed, 26 Oct 2016 23:17:03 +0100 + +zcash (1.0.0-rc2) jessie; urgency=medium + + * 1.0.0-rc2 release. + + -- Zcash Company Sun, 23 Oct 2016 01:51:27 +0100 + +zcash (1.0.0-rc1) jessie; urgency=medium + + * Initial packaging for Debian. + + -- Zcash Company Mon, 17 Oct 2016 11:47:02 -0700 diff --git a/depend/zcash/contrib/debian/compat b/depend/zcash/contrib/debian/compat new file mode 100644 index 000000000..ec635144f --- /dev/null +++ b/depend/zcash/contrib/debian/compat @@ -0,0 +1 @@ +9 diff --git a/depend/zcash/contrib/debian/control b/depend/zcash/contrib/debian/control new file mode 100644 index 000000000..31f40c2c8 --- /dev/null +++ b/depend/zcash/contrib/debian/control @@ -0,0 +1,22 @@ +Source: zcash +Section: utils +Priority: optional +Maintainer: Electric Coin Company +Homepage: https://z.cash +Build-Depends: autoconf, automake, bsdmainutils, build-essential, + git, g++-multilib, libc6-dev, libtool, + m4, ncurses-dev, pkg-config, python, + unzip, wget, zlib1g-dev +Vcs-Git: https://github.com/zcash/zcash.git +Vcs-Browser: https://github.com/zcash/zcash + +Package: zcash +Architecture: amd64 +Depends: ${shlibs:Depends} +Description: Zcash libraries and tools + Based on Bitcoin's code, it intends to offer a far higher standard + of privacy and anonymity through a sophisticiated zero-knowledge + proving scheme which preserves confidentiality of transaction metadata. + Think of it as HTTPS for money. + This package provides the daemon, zcashd, and the CLI tool, + zcash-cli, to interact with the daemon. diff --git a/depend/zcash/contrib/debian/copyright b/depend/zcash/contrib/debian/copyright new file mode 100644 index 000000000..79105d8af --- /dev/null +++ b/depend/zcash/contrib/debian/copyright @@ -0,0 +1,1891 @@ +Format: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=174 +Upstream-Name: Zcash +Upstream-Contact: Electric Coin Company +Source: https://github.com/zcash/zcash + +Files: * +Copyright: 2016-2022, The Zcash developers + 2009-2022, Bitcoin Core developers + 2009-2022, Bitcoin Developers +License: Expat +Comment: The Bitcoin Core developers encompasses the current developers listed on + bitcoin.org, as well as the numerous contributors to the project. + The Zcash developers are listed at https://z.cash/team.html and in doc/authors.md. + This copyright entry excludes files explicitly listed below. + We do not explicitly list Rust crates that have Expat/MIT as a licensing option + (as determined by "cargo license"). + +Files: build-aux/m4/ax_boost_base.m4 +Copyright: 2008, Thomas Porschberg + 2009, Peter Adolphs +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_chrono.m4 +Copyright: 2012, Xiyue Deng +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_filesystem.m4 +Copyright: 2009, Thomas Porschberg + 2009, Michael Tindal + 2009, Roman Rybalko +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_program_options.m4 +Copyright: 2009, Thomas Porschberg +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_system.m4 +Copyright: 2008, Thomas Porschberg + 2008, Michael Tindal + 2008, Daniel Casimiro +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_thread.m4 +Copyright: 2009, Thomas Porschberg + 2009, Michael Tindal +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_boost_unit_test_framework.m4 +Copyright: 2008, Thomas Porschberg +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_cxx_compile_stdcxx.m4 +Copyright: 2008, Benjamin Kosnik + 2012, Zack Weinberg + 2013, Roy Stogner + 2014-2015, Google Inc.; contributed by Alexey Sokolov + 2015, Paul Norman + 2015, Moritz Klammler + 2016, 2018 Krzesimir Nowak + 2019 Enji Cooper +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_gcc_func_attribute.m4 +Copyright: 2013, Gabriele Svelto +License: GNU-All-permissive-License + +Files: build-aux/m4/l_atomic.m4 +Copyright: 2015, Tim Kosse +License: GNU-All-permissive-License + +Files: build-aux/m4/ax_check_compile_flag.m4 + build-aux/m4/ax_check_link_flag.m4 + build-aux/m4/ax_check_preproc_flag.m4 +Copyright: 2008, Guido U. Draheim + 2011, Maarten Bosmans +License: GPL-3+ with Autoconf exception + +Files: build-aux/m4/ax_pthread.m4 +Copyright: 2008, Steven G. Johnson + 2011, Daniel Richard G. +License: GPL-3+ with Autoconf exception + +Files: build-aux/m4/libtool.m4 +Copyright: 1996-2001, 2003-2015 Free Software Foundation, Inc. + Written by Gordon Matzigkeit, 1996 +License: GNU-All-permissive-License or GPL-2+ with Libtool exception + +Files: build-aux/m4/lt~obsolete.m4 +Copyright: 2004-2005, 2007, 2009, 2011-2015 Free Software Foundation, Inc. + Written by Scott James Remnant, 2004. +License: GNU-All-permissive-License + +Files: build-aux/m4/ltoptions.m4 + build-aux/m4/ltsugar.m4 +Copyright: 2004-2005, 2007-2009, 2011-2015 Free Software Foundation, Inc. + Written by Gary V. Vaughan, 2004 +License: GNU-All-permissive-License + +Files: build-aux/m4/ltversion.m4 +Copyright: 2004, 2011-2015 Free Software Foundation, Inc. + Written by Scott James Remnant, 2004 +License: GNU-All-permissive-License + +Files: qa/zcash/checksec.sh +Copyright: 2014-2015, Brian Davis + 2013, Robin David + 2009-2011, Tobias Klein +License: BSD-3-clause-Tobias-Klein + +Files: depends/sources/libsodium-*.tar.gz +Copyright: 2013-2022 Frank Denis +License: ISC + +Files: depends/sources/boost_*.tar.gz +Copyright: 2008 Beman Dawes +License: Boost-Software-License-1.0 + +Files: depends/sources/clang-llvm-*.tar.xz +Copyright: The libc++ Authors +License: Apache-2 with LLVM exception +Comment: This entry is specifically for the libc++ library. The libc++ Authors + are listed in https://github.com/llvm/llvm-project/blob/main/libcxx/CREDITS.TXT . + +Files: depends/sources/db-*.tar.gz +Copyright: 1990, 2016 Oracle and/or its affiliates; + 1990, 1993, 1994, 1995 The Regents of the University of California; + 1995, 1996 The President and Fellows of Harvard University; + 2000-2005 INRIA, France Telecom +License: BDB + +Files: depends/sources/libevent-*.tar.gz +Copyright: 2000-2007 Niels Provos + 2007-2012 Niels Provos and Nick Mathewson + 2000 Dug Song + 1993 The Regents of the University of California. + 1998 Todd C. Miller + 2003 Michael A. Davis + 2007 Sun Microsystems + 2002 Christopher Clark + 2006 Maxim Yegorushkin +License: BSD-3-clause + +Files: depends/sources/zeromq-*.tar.gz +Copyright: 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2007-2014 iMatix Corporation + 2009-2011 250bpm s.r.o. + 2010-2011 Miru Limited + 2011 VMware, Inc. + 2012 Spotify AB + 2013 Ericsson AB + 2014 AppDynamics Inc. + 2015-2016 Brocade Communications Systems Inc. +License: LGPL-3+ with ZeroMQ exception + +Files: depends/sources/google*.tar.gz +Copyright: 2008 Google Inc. +License: BSD-3-clause-Google + +Files: depends/sources/utfcpp-*.tar.gz +Copyright: 2006 Nemanja Trifunovic +License: Boost-Software-License-1.0 + +Files: depends/*/vendored-sources/halo2/* + depends/*/vendored-sources/orchard/* +Copyright: 2020-2022 The Electric Coin Company +License: BOSL-1+ with Zcash exception + +Files: depends/*/vendored-sources/sketches-ddsketch/* +Copyright: 2019-2020 Mike Heffner +License: Apache-2.0 + +Files: depends/*/vendored-sources/arrayref/* +Copyright: 2015-2022 David Roundy +License: BSD-2-clause + +Files: depends/*/vendored-sources/mach/* +Copyright: 2015-2022 Nick Fitzgerald +License: BSD-2-clause + +Files: depends/*/vendored-sources/curve25519-dalek/* +Copyright: 2016-2021 isis agora lovecruft + 2016-2021 Henry de Valence + 2012-2017 Adam Langley + 2012 The Go Authors +License: BSD-3-clause and BSD-3-clause-Google + +Files: depends/*/vendored-sources/instant/* +Copyright: 2019 Sébastien Crozet +License: BSD-3-clause + +Files: depends/*/vendored-sources/parity-scale-codec/* +Copyright: 2018-2022 Parity Technologies +License: Apache-2.0 + +Files: depends/*/vendored-sources/parity-scale-codec-derive/* +Copyright: 2018-2022 Parity Technologies +License: Apache-2.0 + +Files: depends/*/vendored-sources/subtle/* +Copyright: 2016-2017 isis agora lovecruft, Henry de Valence +License: BSD-3-clause + +Files: depends/*/vendored-sources/constant_time_eq/* +Copyright: 2015-2022 Cesar Eduardo Barros +License: CC0-1.0 + +Files: depends/*/vendored-sources/secp256k1/* +Copyright: 2014-2022 Dawid Ciężarkiewicz , Andrew Poelstra +License: CC0-1.0 + +Files: depends/*/vendored-sources/secp256k1-sys/* +Copyright: 2014-2022 Dawid Ciężarkiewicz , Andrew Poelstra , Steven Roose +License: CC0-1.0 + +Files: depends/*/vendored-sources/untrusted/* +Copyright: 2015-2016 Brian Smith +License: ISC + +Files: depends/*/vendored-sources/ring/* +Copyright: 2015-2016 Brian Smith + 1998-2011 The OpenSSL Project + 1995-1998 Eric Young + 2015 Google Inc. + 2015-2016 the fiat-crypto authors +License: Ring-BoringSSL + +Files: depends/*/vendored-sources/terminfo/* +Copyright: 2016-2020 meh +License: WTFPL + +Files: src/crypto/ctaes/* +Copyright: 2016 Pieter Wuille +License: Expat + +Files: src/rust/include/rust/map.h +Copyright: 2012 William Swanson + 2020 The Zcash developers +License: Expat-with-advertising-clause + +Files: src/rust/include/rust/VA_OPT.hpp +Copyright: 2019 Will Wray + 2020 The Zcash developers +License: Boost-Software-License-1.0 + +Files: src/secp256k1/* +Copyright: 2013 Pieter Wuille +License: Expat +Comment: This copyright entry excludes files explicitly listed below. + +Files: src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 +Copyright: 2008 Don Anderson +License: GNU-All-permissive-License + +Files: src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +Copyright: 2008 Paolo Bonzini +License: GNU-All-permissive-License + +Files: src/leveldb/* +Copyright: 2011 The LevelDB Authors +License: BSD-3-clause-Google +Comment: The LevelDB Authors are listed in src/leveldb/AUTHORS. + +License: Apache-2.0 + On Debian systems, the full text of the Apache License v2.0 can be found in the + file `/usr/share/common-licenses/Apache-2.0`. + +License: Apache-2 with LLVM exception + ============================================================================== + The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: + ============================================================================== + . + On Debian systems, the full text of the Apache License v2.0 can be found in the + file `/usr/share/common-licenses/Apache-2.0`. + . + ---- LLVM Exceptions to the Apache 2.0 License ---- + . + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into an Object form of such source code, you + may redistribute such embedded portions in such Object form without complying + with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + . + In addition, if you combine or link compiled forms of this Software with + software that is licensed under the GPLv2 ("Combined Software") and if a + court of competent jurisdiction determines that the patent provision (Section + 3), the indemnity provision (Section 9) or other Section of the License + conflicts with the conditions of the GPLv2, you may retroactively and + prospectively choose to deem waived or otherwise exclude such Section(s) of + the License, but only in their entirety and only with respect to the Combined + Software. + +License: Boost-Software-License-1.0 + Permission is hereby granted, free of charge, to any person or organization + obtaining a copy of the software and accompanying documentation covered by + this license (the "Software") to use, reproduce, display, distribute, + execute, and transmit the Software, and to prepare derivative works of the + Software, and to permit third-parties to whom the Software is furnished to + do so, all subject to the following: + . + The copyright notices in the Software and this entire statement, including + the above license grant, this restriction and the following disclaimer, + must be included in all copies of the Software, in whole or in part, and + all derivative works of the Software, unless such copies or derivative + works are solely in the form of machine-executable object code generated by + a source language processor. + . + 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT + SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +License: BDB + /* + * The Oracle Berkeley DB product is licensed + * under the GNU AFFERO GENERAL PUBLIC LICENSE: + * + * + * GNU AFFERO GENERAL PUBLIC LICENSE + * Version 3, 19 November 2007 + * + * Copyright (C) 2007 Free Software Foundation, Inc. + * Everyone is permitted to copy and distribute verbatim copies + * of this license document, but changing it is not allowed. + * + * Preamble + * + * The GNU Affero General Public License is a free, copyleft license for + * software and other kinds of works, specifically designed to ensure + * cooperation with the community in the case of network server software. + * + * The licenses for most software and other practical works are designed + * to take away your freedom to share and change the works. By contrast, + * our General Public Licenses are intended to guarantee your freedom to + * share and change all versions of a program--to make sure it remains free + * software for all its users. + * + * When we speak of free software, we are referring to freedom, not + * price. Our General Public Licenses are designed to make sure that you + * have the freedom to distribute copies of free software (and charge for + * them if you wish), that you receive source code or can get it if you + * want it, that you can change the software or use pieces of it in new + * free programs, and that you know you can do these things. + * + * Developers that use our General Public Licenses protect your rights + * with two steps: (1) assert copyright on the software, and (2) offer + * you this License which gives you legal permission to copy, distribute + * and/or modify the software. + * + * A secondary benefit of defending all users' freedom is that + * improvements made in alternate versions of the program, if they + * receive widespread use, become available for other developers to + * incorporate. Many developers of free software are heartened and + * encouraged by the resulting cooperation. However, in the case of + * software used on network servers, this result may fail to come about. + * The GNU General Public License permits making a modified version and + * letting the public access it on a server without ever releasing its + * source code to the public. + * + * The GNU Affero General Public License is designed specifically to + * ensure that, in such cases, the modified source code becomes available + * to the community. It requires the operator of a network server to + * provide the source code of the modified version running there to the + * users of that server. Therefore, public use of a modified version, on + * a publicly accessible server, gives the public access to the source + * code of the modified version. + * + * An older license, called the Affero General Public License and + * published by Affero, was designed to accomplish similar goals. This is + * a different license, not a version of the Affero GPL, but Affero has + * released a new version of the Affero GPL which permits relicensing under + * this license. + * + * The precise terms and conditions for copying, distribution and + * modification follow. + * + * TERMS AND CONDITIONS + * + * 0. Definitions. + * + * "This License" refers to version 3 of the GNU Affero General Public License. + * + * "Copyright" also means copyright-like laws that apply to other kinds of + * works, such as semiconductor masks. + * + * "The Program" refers to any copyrightable work licensed under this + * License. Each licensee is addressed as "you". "Licensees" and + * "recipients" may be individuals or organizations. + * + * To "modify" a work means to copy from or adapt all or part of the work + * in a fashion requiring copyright permission, other than the making of an + * exact copy. The resulting work is called a "modified version" of the + * earlier work or a work "based on" the earlier work. + * + * A "covered work" means either the unmodified Program or a work based + * on the Program. + * + * To "propagate" a work means to do anything with it that, without + * permission, would make you directly or secondarily liable for + * infringement under applicable copyright law, except executing it on a + * computer or modifying a private copy. Propagation includes copying, + * distribution (with or without modification), making available to the + * public, and in some countries other activities as well. + * + * To "convey" a work means any kind of propagation that enables other + * parties to make or receive copies. Mere interaction with a user through + * a computer network, with no transfer of a copy, is not conveying. + * + * An interactive user interface displays "Appropriate Legal Notices" + * to the extent that it includes a convenient and prominently visible + * feature that (1) displays an appropriate copyright notice, and (2) + * tells the user that there is no warranty for the work (except to the + * extent that warranties are provided), that licensees may convey the + * work under this License, and how to view a copy of this License. If + * the interface presents a list of user commands or options, such as a + * menu, a prominent item in the list meets this criterion. + * + * 1. Source Code. + * + * The "source code" for a work means the preferred form of the work + * for making modifications to it. "Object code" means any non-source + * form of a work. + * + * A "Standard Interface" means an interface that either is an official + * standard defined by a recognized standards body, or, in the case of + * interfaces specified for a particular programming language, one that + * is widely used among developers working in that language. + * + * The "System Libraries" of an executable work include anything, other + * than the work as a whole, that (a) is included in the normal form of + * packaging a Major Component, but which is not part of that Major + * Component, and (b) serves only to enable use of the work with that + * Major Component, or to implement a Standard Interface for which an + * implementation is available to the public in source code form. A + * "Major Component", in this context, means a major essential component + * (kernel, window system, and so on) of the specific operating system + * (if any) on which the executable work runs, or a compiler used to + * produce the work, or an object code interpreter used to run it. + * + * The "Corresponding Source" for a work in object code form means all + * the source code needed to generate, install, and (for an executable + * work) run the object code and to modify the work, including scripts to + * control those activities. However, it does not include the work's + * System Libraries, or general-purpose tools or generally available free + * programs which are used unmodified in performing those activities but + * which are not part of the work. For example, Corresponding Source + * includes interface definition files associated with source files for + * the work, and the source code for shared libraries and dynamically + * linked subprograms that the work is specifically designed to require, + * such as by intimate data communication or control flow between those + * subprograms and other parts of the work. + * + * The Corresponding Source need not include anything that users + * can regenerate automatically from other parts of the Corresponding + * Source. + * + * The Corresponding Source for a work in source code form is that + * same work. + * + * 2. Basic Permissions. + * + * All rights granted under this License are granted for the term of + * copyright on the Program, and are irrevocable provided the stated + * conditions are met. This License explicitly affirms your unlimited + * permission to run the unmodified Program. The output from running a + * covered work is covered by this License only if the output, given its + * content, constitutes a covered work. This License acknowledges your + * rights of fair use or other equivalent, as provided by copyright law. + * + * You may make, run and propagate covered works that you do not + * convey, without conditions so long as your license otherwise remains + * in force. You may convey covered works to others for the sole purpose + * of having them make modifications exclusively for you, or provide you + * with facilities for running those works, provided that you comply with + * the terms of this License in conveying all material for which you do + * not control copyright. Those thus making or running the covered works + * for you must do so exclusively on your behalf, under your direction + * and control, on terms that prohibit them from making any copies of + * your copyrighted material outside their relationship with you. + * + * Conveying under any other circumstances is permitted solely under + * the conditions stated below. Sublicensing is not allowed; section 10 + * makes it unnecessary. + * + * 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + * + * No covered work shall be deemed part of an effective technological + * measure under any applicable law fulfilling obligations under article + * 11 of the WIPO copyright treaty adopted on 20 December 1996, or + * similar laws prohibiting or restricting circumvention of such + * measures. + * + * When you convey a covered work, you waive any legal power to forbid + * circumvention of technological measures to the extent such circumvention + * is effected by exercising rights under this License with respect to + * the covered work, and you disclaim any intention to limit operation or + * modification of the work as a means of enforcing, against the work's + * users, your or third parties' legal rights to forbid circumvention of + * technological measures. + * + * 4. Conveying Verbatim Copies. + * + * You may convey verbatim copies of the Program's source code as you + * receive it, in any medium, provided that you conspicuously and + * appropriately publish on each copy an appropriate copyright notice; + * keep intact all notices stating that this License and any + * non-permissive terms added in accord with section 7 apply to the code; + * keep intact all notices of the absence of any warranty; and give all + * recipients a copy of this License along with the Program. + * + * You may charge any price or no price for each copy that you convey, + * and you may offer support or warranty protection for a fee. + * + * 5. Conveying Modified Source Versions. + * + * You may convey a work based on the Program, or the modifications to + * produce it from the Program, in the form of source code under the + * terms of section 4, provided that you also meet all of these conditions: + * + * a) The work must carry prominent notices stating that you modified + * it, and giving a relevant date. + * + * b) The work must carry prominent notices stating that it is + * released under this License and any conditions added under section + * 7. This requirement modifies the requirement in section 4 to + * "keep intact all notices". + * + * c) You must license the entire work, as a whole, under this + * License to anyone who comes into possession of a copy. This + * License will therefore apply, along with any applicable section 7 + * additional terms, to the whole of the work, and all its parts, + * regardless of how they are packaged. This License gives no + * permission to license the work in any other way, but it does not + * invalidate such permission if you have separately received it. + * + * d) If the work has interactive user interfaces, each must display + * Appropriate Legal Notices; however, if the Program has interactive + * interfaces that do not display Appropriate Legal Notices, your + * work need not make them do so. + * + * A compilation of a covered work with other separate and independent + * works, which are not by their nature extensions of the covered work, + * and which are not combined with it such as to form a larger program, + * in or on a volume of a storage or distribution medium, is called an + * "aggregate" if the compilation and its resulting copyright are not + * used to limit the access or legal rights of the compilation's users + * beyond what the individual works permit. Inclusion of a covered work + * in an aggregate does not cause this License to apply to the other + * parts of the aggregate. + * + * 6. Conveying Non-Source Forms. + * + * You may convey a covered work in object code form under the terms + * of sections 4 and 5, provided that you also convey the + * machine-readable Corresponding Source under the terms of this License, + * in one of these ways: + * + * a) Convey the object code in, or embodied in, a physical product + * (including a physical distribution medium), accompanied by the + * Corresponding Source fixed on a durable physical medium + * customarily used for software interchange. + * + * b) Convey the object code in, or embodied in, a physical product + * (including a physical distribution medium), accompanied by a + * written offer, valid for at least three years and valid for as + * long as you offer spare parts or customer support for that product + * model, to give anyone who possesses the object code either (1) a + * copy of the Corresponding Source for all the software in the + * product that is covered by this License, on a durable physical + * medium customarily used for software interchange, for a price no + * more than your reasonable cost of physically performing this + * conveying of source, or (2) access to copy the + * Corresponding Source from a network server at no charge. + * + * c) Convey individual copies of the object code with a copy of the + * written offer to provide the Corresponding Source. This + * alternative is allowed only occasionally and noncommercially, and + * only if you received the object code with such an offer, in accord + * with subsection 6b. + * + * d) Convey the object code by offering access from a designated + * place (gratis or for a charge), and offer equivalent access to the + * Corresponding Source in the same way through the same place at no + * further charge. You need not require recipients to copy the + * Corresponding Source along with the object code. If the place to + * copy the object code is a network server, the Corresponding Source + * may be on a different server (operated by you or a third party) + * that supports equivalent copying facilities, provided you maintain + * clear directions next to the object code saying where to find the + * Corresponding Source. Regardless of what server hosts the + * Corresponding Source, you remain obligated to ensure that it is + * available for as long as needed to satisfy these requirements. + * + * e) Convey the object code using peer-to-peer transmission, provided + * you inform other peers where the object code and Corresponding + * Source of the work are being offered to the general public at no + * charge under subsection 6d. + * + * A separable portion of the object code, whose source code is excluded + * from the Corresponding Source as a System Library, need not be + * included in conveying the object code work. + * + * A "User Product" is either (1) a "consumer product", which means any + * tangible personal property which is normally used for personal, family, + * or household purposes, or (2) anything designed or sold for incorporation + * into a dwelling. In determining whether a product is a consumer product, + * doubtful cases shall be resolved in favor of coverage. For a particular + * product received by a particular user, "normally used" refers to a + * typical or common use of that class of product, regardless of the status + * of the particular user or of the way in which the particular user + * actually uses, or expects or is expected to use, the product. A product + * is a consumer product regardless of whether the product has substantial + * commercial, industrial or non-consumer uses, unless such uses represent + * the only significant mode of use of the product. + * + * "Installation Information" for a User Product means any methods, + * procedures, authorization keys, or other information required to install + * and execute modified versions of a covered work in that User Product from + * a modified version of its Corresponding Source. The information must + * suffice to ensure that the continued functioning of the modified object + * code is in no case prevented or interfered with solely because + * modification has been made. + * + * If you convey an object code work under this section in, or with, or + * specifically for use in, a User Product, and the conveying occurs as + * part of a transaction in which the right of possession and use of the + * User Product is transferred to the recipient in perpetuity or for a + * fixed term (regardless of how the transaction is characterized), the + * Corresponding Source conveyed under this section must be accompanied + * by the Installation Information. But this requirement does not apply + * if neither you nor any third party retains the ability to install + * modified object code on the User Product (for example, the work has + * been installed in ROM). + * + * The requirement to provide Installation Information does not include a + * requirement to continue to provide support service, warranty, or updates + * for a work that has been modified or installed by the recipient, or for + * the User Product in which it has been modified or installed. Access to a + * network may be denied when the modification itself materially and + * adversely affects the operation of the network or violates the rules and + * protocols for communication across the network. + * + * Corresponding Source conveyed, and Installation Information provided, + * in accord with this section must be in a format that is publicly + * documented (and with an implementation available to the public in + * source code form), and must require no special password or key for + * unpacking, reading or copying. + * + * 7. Additional Terms. + * + * "Additional permissions" are terms that supplement the terms of this + * License by making exceptions from one or more of its conditions. + * Additional permissions that are applicable to the entire Program shall + * be treated as though they were included in this License, to the extent + * that they are valid under applicable law. If additional permissions + * apply only to part of the Program, that part may be used separately + * under those permissions, but the entire Program remains governed by + * this License without regard to the additional permissions. + * + * When you convey a copy of a covered work, you may at your option + * remove any additional permissions from that copy, or from any part of + * it. (Additional permissions may be written to require their own + * removal in certain cases when you modify the work.) You may place + * additional permissions on material, added by you to a covered work, + * for which you have or can give appropriate copyright permission. + * + * Notwithstanding any other provision of this License, for material you + * add to a covered work, you may (if authorized by the copyright holders of + * that material) supplement the terms of this License with terms: + * + * a) Disclaiming warranty or limiting liability differently from the + * terms of sections 15 and 16 of this License; or + * + * b) Requiring preservation of specified reasonable legal notices or + * author attributions in that material or in the Appropriate Legal + * Notices displayed by works containing it; or + * + * c) Prohibiting misrepresentation of the origin of that material, or + * requiring that modified versions of such material be marked in + * reasonable ways as different from the original version; or + * + * d) Limiting the use for publicity purposes of names of licensors or + * authors of the material; or + * + * e) Declining to grant rights under trademark law for use of some + * trade names, trademarks, or service marks; or + * + * f) Requiring indemnification of licensors and authors of that + * material by anyone who conveys the material (or modified versions of + * it) with contractual assumptions of liability to the recipient, for + * any liability that these contractual assumptions directly impose on + * those licensors and authors. + * + * All other non-permissive additional terms are considered "further + * restrictions" within the meaning of section 10. If the Program as you + * received it, or any part of it, contains a notice stating that it is + * governed by this License along with a term that is a further + * restriction, you may remove that term. If a license document contains + * a further restriction but permits relicensing or conveying under this + * License, you may add to a covered work material governed by the terms + * of that license document, provided that the further restriction does + * not survive such relicensing or conveying. + * + * If you add terms to a covered work in accord with this section, you + * must place, in the relevant source files, a statement of the + * additional terms that apply to those files, or a notice indicating + * where to find the applicable terms. + * + * Additional terms, permissive or non-permissive, may be stated in the + * form of a separately written license, or stated as exceptions; + * the above requirements apply either way. + * + * 8. Termination. + * + * You may not propagate or modify a covered work except as expressly + * provided under this License. Any attempt otherwise to propagate or + * modify it is void, and will automatically terminate your rights under + * this License (including any patent licenses granted under the third + * paragraph of section 11). + * + * However, if you cease all violation of this License, then your + * license from a particular copyright holder is reinstated (a) + * provisionally, unless and until the copyright holder explicitly and + * finally terminates your license, and (b) permanently, if the copyright + * holder fails to notify you of the violation by some reasonable means + * prior to 60 days after the cessation. + * + * Moreover, your license from a particular copyright holder is + * reinstated permanently if the copyright holder notifies you of the + * violation by some reasonable means, this is the first time you have + * received notice of violation of this License (for any work) from that + * copyright holder, and you cure the violation prior to 30 days after + * your receipt of the notice. + * + * Termination of your rights under this section does not terminate the + * licenses of parties who have received copies or rights from you under + * this License. If your rights have been terminated and not permanently + * reinstated, you do not qualify to receive new licenses for the same + * material under section 10. + * + * 9. Acceptance Not Required for Having Copies. + * + * You are not required to accept this License in order to receive or + * run a copy of the Program. Ancillary propagation of a covered work + * occurring solely as a consequence of using peer-to-peer transmission + * to receive a copy likewise does not require acceptance. However, + * nothing other than this License grants you permission to propagate or + * modify any covered work. These actions infringe copyright if you do + * not accept this License. Therefore, by modifying or propagating a + * covered work, you indicate your acceptance of this License to do so. + * + * 10. Automatic Licensing of Downstream Recipients. + * + * Each time you convey a covered work, the recipient automatically + * receives a license from the original licensors, to run, modify and + * propagate that work, subject to this License. You are not responsible + * for enforcing compliance by third parties with this License. + * + * An "entity transaction" is a transaction transferring control of an + * organization, or substantially all assets of one, or subdividing an + * organization, or merging organizations. If propagation of a covered + * work results from an entity transaction, each party to that + * transaction who receives a copy of the work also receives whatever + * licenses to the work the party's predecessor in interest had or could + * give under the previous paragraph, plus a right to possession of the + * Corresponding Source of the work from the predecessor in interest, if + * the predecessor has it or can get it with reasonable efforts. + * + * You may not impose any further restrictions on the exercise of the + * rights granted or affirmed under this License. For example, you may + * not impose a license fee, royalty, or other charge for exercise of + * rights granted under this License, and you may not initiate litigation + * (including a cross-claim or counterclaim in a lawsuit) alleging that + * any patent claim is infringed by making, using, selling, offering for + * sale, or importing the Program or any portion of it. + * + * 11. Patents. + * + * A "contributor" is a copyright holder who authorizes use under this + * License of the Program or a work on which the Program is based. The + * work thus licensed is called the contributor's "contributor version". + * + * A contributor's "essential patent claims" are all patent claims + * owned or controlled by the contributor, whether already acquired or + * hereafter acquired, that would be infringed by some manner, permitted + * by this License, of making, using, or selling its contributor version, + * but do not include claims that would be infringed only as a + * consequence of further modification of the contributor version. For + * purposes of this definition, "control" includes the right to grant + * patent sublicenses in a manner consistent with the requirements of + * this License. + * + * Each contributor grants you a non-exclusive, worldwide, royalty-free + * patent license under the contributor's essential patent claims, to + * make, use, sell, offer for sale, import and otherwise run, modify and + * propagate the contents of its contributor version. + * + * In the following three paragraphs, a "patent license" is any express + * agreement or commitment, however denominated, not to enforce a patent + * (such as an express permission to practice a patent or covenant not to + * sue for patent infringement). To "grant" such a patent license to a + * party means to make such an agreement or commitment not to enforce a + * patent against the party. + * + * If you convey a covered work, knowingly relying on a patent license, + * and the Corresponding Source of the work is not available for anyone + * to copy, free of charge and under the terms of this License, through a + * publicly available network server or other readily accessible means, + * then you must either (1) cause the Corresponding Source to be so + * available, or (2) arrange to deprive yourself of the benefit of the + * patent license for this particular work, or (3) arrange, in a manner + * consistent with the requirements of this License, to extend the patent + * license to downstream recipients. "Knowingly relying" means you have + * actual knowledge that, but for the patent license, your conveying the + * covered work in a country, or your recipient's use of the covered work + * in a country, would infringe one or more identifiable patents in that + * country that you have reason to believe are valid. + * + * If, pursuant to or in connection with a single transaction or + * arrangement, you convey, or propagate by procuring conveyance of, a + * covered work, and grant a patent license to some of the parties + * receiving the covered work authorizing them to use, propagate, modify + * or convey a specific copy of the covered work, then the patent license + * you grant is automatically extended to all recipients of the covered + * work and works based on it. + * + * A patent license is "discriminatory" if it does not include within + * the scope of its coverage, prohibits the exercise of, or is + * conditioned on the non-exercise of one or more of the rights that are + * specifically granted under this License. You may not convey a covered + * work if you are a party to an arrangement with a third party that is + * in the business of distributing software, under which you make payment + * to the third party based on the extent of your activity of conveying + * the work, and under which the third party grants, to any of the + * parties who would receive the covered work from you, a discriminatory + * patent license (a) in connection with copies of the covered work + * conveyed by you (or copies made from those copies), or (b) primarily + * for and in connection with specific products or compilations that + * contain the covered work, unless you entered into that arrangement, + * or that patent license was granted, prior to 28 March 2007. + * + * Nothing in this License shall be construed as excluding or limiting + * any implied license or other defenses to infringement that may + * otherwise be available to you under applicable patent law. + * + * 12. No Surrender of Others' Freedom. + * + * If conditions are imposed on you (whether by court order, agreement or + * otherwise) that contradict the conditions of this License, they do not + * excuse you from the conditions of this License. If you cannot convey a + * covered work so as to satisfy simultaneously your obligations under this + * License and any other pertinent obligations, then as a consequence you may + * not convey it at all. For example, if you agree to terms that obligate you + * to collect a royalty for further conveying from those to whom you convey + * the Program, the only way you could satisfy both those terms and this + * License would be to refrain entirely from conveying the Program. + * + * 13. Remote Network Interaction; Use with the GNU General Public License. + * + * Notwithstanding any other provision of this License, if you modify the + * Program, your modified version must prominently offer all users + * interacting with it remotely through a computer network (if your version + * supports such interaction) an opportunity to receive the Corresponding + * Source of your version by providing access to the Corresponding Source + * from a network server at no charge, through some standard or customary + * means of facilitating copying of software. This Corresponding Source + * shall include the Corresponding Source for any work covered by version 3 + * of the GNU General Public License that is incorporated pursuant to the + * following paragraph. + * + * Notwithstanding any other provision of this License, you have + * permission to link or combine any covered work with a work licensed + * under version 3 of the GNU General Public License into a single + * combined work, and to convey the resulting work. The terms of this + * License will continue to apply to the part which is the covered work, + * but the work with which it is combined will remain governed by version + * 3 of the GNU General Public License. + * + * 14. Revised Versions of this License. + * + * The Free Software Foundation may publish revised and/or new versions of + * the GNU Affero General Public License from time to time. Such new versions + * will be similar in spirit to the present version, but may differ in detail to + * address new problems or concerns. + * + * Each version is given a distinguishing version number. If the + * Program specifies that a certain numbered version of the GNU Affero General + * Public License "or any later version" applies to it, you have the + * option of following the terms and conditions either of that numbered + * version or of any later version published by the Free Software + * Foundation. If the Program does not specify a version number of the + * GNU Affero General Public License, you may choose any version ever published + * by the Free Software Foundation. + * + * If the Program specifies that a proxy can decide which future + * versions of the GNU Affero General Public License can be used, that proxy's + * public statement of acceptance of a version permanently authorizes you + * to choose that version for the Program. + * + * Later license versions may give you additional or different + * permissions. However, no additional obligations are imposed on any + * author or copyright holder as a result of your choosing to follow a + * later version. + * + * 15. Disclaimer of Warranty. + * + * THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY + * APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + * HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY + * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM + * IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF + * ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + * + * 16. Limitation of Liability. + * + * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + * WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS + * THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY + * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE + * USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD + * PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), + * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + * + * 17. Interpretation of Sections 15 and 16. + * + * If the disclaimer of warranty and limitation of liability provided + * above cannot be given local legal effect according to their terms, + * reviewing courts shall apply local law that most closely approximates + * an absolute waiver of all civil liability in connection with the + * Program, unless a warranty or assumption of liability accompanies a + * copy of the Program in return for a fee. + * + * END OF TERMS AND CONDITIONS + * + * How to Apply These Terms to Your New Programs + * + * If you develop a new program, and you want it to be of the greatest + * possible use to the public, the best way to achieve this is to make it + * free software which everyone can redistribute and change under these terms. + * + * To do so, attach the following notices to the program. It is safest + * to attach them to the start of each source file to most effectively + * state the exclusion of warranty; and each file should have at least + * the "copyright" line and a pointer to where the full notice is found. + * + * + * Copyright (C) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * Also add information on how to contact you by electronic and paper mail. + * + * If your software can interact with users remotely through a computer + * network, you should also make sure that it provides a way for users to + * get its source. For example, if your program is a web application, its + * interface could display a "Source" link that leads users to an archive + * of the code. There are many ways you could offer source, and different + * solutions will be better for different programs; see section 13 for the + * specific requirements. + * + * You should also get your employer (if you work as a programmer) or school, + * if any, to sign a "copyright disclaimer" for the program, if necessary. + * For more information on this, and how to apply and follow the GNU AGPL, see + * . + */ + . + ADDITIONAL THIRD PARTY NOTICES: + . + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + /* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + /* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + /*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2005 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + . + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +License: Expat + 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. + +License: BSD-3-clause-Google + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + . + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-3-clause-Tobias-Klein + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Tobias Klein nor the name of trapkit.de may be used + to endorse or promote products derived from this software without specific + prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +License: ISC + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR + BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. + +License: LGPL + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + . + On Debian systems the GNU Lesser General Public License (LGPL) is + located in '/usr/share/common-licenses/LGPL'. + . + 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. +Comment: + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +License: LGPL-3+ with ZeroMQ exception + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + . + On Debian systems the GNU Lesser General Public License (LGPL) is + located in '/usr/share/common-licenses/LGPL'. + . + 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. + -------------------------------------------------------------------------------- + SPECIAL EXCEPTION GRANTED BY COPYRIGHT HOLDERS + . + As a special exception, copyright holders give you permission to link this + library with independent modules to produce an executable, regardless of + the license terms of these independent modules, and to copy and distribute + the resulting executable under terms of your choice, provided that you also + meet, for each linked independent module, the terms and conditions of + the license of that module. An independent module is a module which is not + derived from or based on this library. If you modify this library, you must + extend this exception to your version of the library. + + Note: this exception relieves you of any obligations under sections 4 and 5 + of this license, and section 6 of the GNU General Public License. +Comment: + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +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 + and this notice are preserved. This file is offered as-is, without any + warranty. + +License: GPL-3+ with Autoconf exception + 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 . + . + On Debian systems, the full text of the GNU General Public License + version 3 can be found in the file `/usr/share/common-licenses/GPL-3'. + . + 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. +Comment: + The "special exception" is extended to the versions of files covered by + this license that are distributed with this software. + +License: GPL-2+ with Libtool exception + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + . + GNU Libtool 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 2 of of the License, or + (at your option) any later version. + . + As a special exception to the GNU General Public License, if you + distribute this file as part of a program or library that is built + using GNU Libtool, you may include this file under the same + distribution terms that you use for the rest of that program. + . + GNU Libtool 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 . + +License: Expat-with-advertising-clause + 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 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. + + Except as contained in this notice, the names of the authors or + their institutions shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization from the authors. + +License: CC0-1.0 + Creative Commons Legal Code + . + CC0 1.0 Universal + . + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + . + Statement of Purpose + . + The laws of most jurisdictions throughout the world automatically confer + exclusive Copyright and Related Rights (defined below) upon the creator + and subsequent owner(s) (each and all, an "owner") of an original work of + authorship and/or a database (each, a "Work"). + . + Certain owners wish to permanently relinquish those rights to a Work for + the purpose of contributing to a commons of creative, cultural and + scientific works ("Commons") that the public can reliably and without fear + of later claims of infringement build upon, modify, incorporate in other + works, reuse and redistribute as freely as possible in any form whatsoever + and for any purposes, including without limitation commercial purposes. + These owners may contribute to the Commons to promote the ideal of a free + culture and the further production of creative, cultural and scientific + works, or to gain reputation or greater distribution for their Work in + part through the use and efforts of others. + . + For these and/or other purposes and motivations, and without any + expectation of additional consideration or compensation, the person + associating CC0 with a Work (the "Affirmer"), to the extent that he or she + is an owner of Copyright and Related Rights in the Work, voluntarily + elects to apply CC0 to the Work and publicly distribute the Work under its + terms, with knowledge of his or her Copyright and Related Rights in the + Work and the meaning and intended legal effect of CC0 on those rights. + . + 1. Copyright and Related Rights. A Work made available under CC0 may be + protected by copyright and related or neighboring rights ("Copyright and + Related Rights"). Copyright and Related Rights include, but are not + limited to, the following: + . + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); + iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and + vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + . + 2. Waiver. To the greatest extent permitted by, but not in contravention + of, applicable law, Affirmer hereby overtly, fully, permanently, + irrevocably and unconditionally waives, abandons, and surrenders all of + Affirmer's Copyright and Related Rights and associated claims and causes + of action, whether now known or unknown (including existing as well as + future claims and causes of action), in the Work (i) in all territories + worldwide, (ii) for the maximum duration provided by applicable law or + treaty (including future time extensions), (iii) in any current or future + medium and for any number of copies, and (iv) for any purpose whatsoever, + including without limitation commercial, advertising or promotional + purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each + member of the public at large and to the detriment of Affirmer's heirs and + successors, fully intending that such Waiver shall not be subject to + revocation, rescission, cancellation, termination, or any other legal or + equitable action to disrupt the quiet enjoyment of the Work by the public + as contemplated by Affirmer's express Statement of Purpose. + . + 3. Public License Fallback. Should any part of the Waiver for any reason + be judged legally invalid or ineffective under applicable law, then the + Waiver shall be preserved to the maximum extent permitted taking into + account Affirmer's express Statement of Purpose. In addition, to the + extent the Waiver is so judged Affirmer hereby grants to each affected + person a royalty-free, non transferable, non sublicensable, non exclusive, + irrevocable and unconditional license to exercise Affirmer's Copyright and + Related Rights in the Work (i) in all territories worldwide, (ii) for the + maximum duration provided by applicable law or treaty (including future + time extensions), (iii) in any current or future medium and for any number + of copies, and (iv) for any purpose whatsoever, including without + limitation commercial, advertising or promotional purposes (the + "License"). The License shall be deemed effective as of the date CC0 was + applied by Affirmer to the Work. Should any part of the License for any + reason be judged legally invalid or ineffective under applicable law, such + partial invalidity or ineffectiveness shall not invalidate the remainder + of the License, and in such case Affirmer hereby affirms that he or she + will not (i) exercise any of his or her remaining Copyright and Related + Rights in the Work or (ii) assert any associated claims and causes of + action with respect to the Work, in either case contrary to Affirmer's + express Statement of Purpose. + . + 4. Limitations and Disclaimers. + . + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. + +License: WTFPL + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + . + Copyright (C) 2004 Sam Hocevar + . + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + . + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + . + 0. You just DO WHAT THE FUCK YOU WANT TO. + +License: Ring-BoringSSL + Note that it is easy for this file to get out of sync with the licenses in the + source code files. It's recommended to compare the licenses in the source code + with what's mentioned here. + . + *ring* is derived from BoringSSL, so the licensing situation in *ring* is + similar to BoringSSL. + . + *ring* uses an ISC-style license like BoringSSL for code in new files, + including in particular all the Rust code: + . + Copyright 2015-2016 Brian Smith. + . + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + . + BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL + licensing. Files that are completely new have a Google copyright and an ISC + license. This license is reproduced at the bottom of this file. + . + Contributors to BoringSSL are required to follow the CLA rules for Chromium: + https://cla.developers.google.com/clas + . + Files in third_party/ have their own licenses, as described therein. The MIT + license, for third_party/fiat, which, unlike other third_party directories, is + compiled into non-test libraries, is included below. + . + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the + OpenSSL License and the original SSLeay license apply to the toolkit. See below + for the actual license texts. Actually both licenses are BSD-style Open Source + licenses. In case of any license issues related to OpenSSL please contact + openssl-core@openssl.org. + . + The following are Google-internal bug numbers where explicit permission from + some authors is recorded for use of their work: + 27287199 + 27287880 + 27287883 + . + OpenSSL License + --------------- + . + /* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + . + Original SSLeay License + ----------------------- + . + /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + . + ISC license used for completely new code in BoringSSL: + . + /* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + . + The code in third_party/fiat carries the MIT license: + . + Copyright (c) 2015-2016 the fiat-crypto authors (see + https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS). + . + 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. + +License: BOSL-1+ with Zcash exception + This package ("Original Work") is licensed under the terms of the Bootstrap Open + Source License, version 1.0, or at your option, any later version ("BOSL"). See + the file ./LICENSE-BOSL for the terms of the Bootstrap Open Source Licence, + version 1.0. + . + Only if this Original Work is included as part of the distribution of one of the + following projects ("the Project"): + . + - The Zcash projects published by the Electric Coin Company, + - The Zebra project published by the Zcash Foundation, + . + then License is granted to use this package under the BOSL as modified by the + following clarification and special exception. This exception applies only to + the Original Work when linked or combined with the Project and not to the + Original Work when linked, combined, or included in or with any other software + or project or on a standalone basis. + . + Under the terms of the BOSL, linking or combining this Original Work with + the Project creates a Derivative Work based upon the Original Work and the + terms of the BOSL thus apply to both the Original Work and that Derivative + Work. As a special exception to the BOSL, and to allow this Original Work to + be linked and combined with the Project without having to apply the BOSL to + the other portions of the Project, you are granted permission to link or + combine this Original Work with the Project and to copy and distribute the + resulting work ("Resulting Work") under the open source license applicable + to the Project ("Project License"), provided that any portions of this + Original Work included in the Resulting Work remain subject to the BOSL. For + clarity, you may continue to treat all other portions of the Project under + the Project License, provided that you comply with the BOSL with respect to + the Original Work. If you modify this Original Work, your version of the + Original Work must remain under the BOSL. You may also extend this exception + to your version, but you are not obligated to do so. If you do not wish to + do so, delete this exception statement from your version. + +License: BOSL-1 + ======================================================= + Bootstrap Open Source Licence ("BOSL") v. 1.0 + ======================================================= + This Bootstrap Open Source Licence (the "License") applies to any original work + of authorship (the "Original Work") whose owner (the "Licensor") has placed the + following licensing notice adjacent to the copyright notice for the Original + Work: + . + *Licensed under the Bootstrap Open Source Licence version 1.0* + . + 1. **Grant of Copyright License.** Licensor grants You a worldwide, + royalty-free, non-exclusive, sublicensable license, for the duration of the + copyright in the Original Work, to do the following: + . + a. to reproduce the Original Work in copies, either alone or as part of + a collective work; + . + b. to translate, adapt, alter, transform, modify, or arrange the + Original Work, thereby creating derivative works ("Derivative Works") + based upon the Original Work; + . + c. to distribute or communicate copies of the Original Work and + Derivative Works to the public, provided that prior to any such + distribution or communication You first place a machine-readable copy + of the Source Code of the Original Work and such Derivative Works that + You intend to distribute or communicate in an information repository + reasonably calculated to permit inexpensive and convenient access + thereto by the public (“Information Repositoryâ€) for as long as You + continue to distribute or communicate said copies, accompanied by an + irrevocable offer to license said copies to the public free of charge + under this License, said offer valid starting no later than 12 months + after You first distribute or communicate said copies; + . + d. to perform the Original Work publicly; and + . + e. to display the Original Work publicly. + . + 2. **Grant of Patent License.** Licensor grants You a worldwide, royalty-free, + non-exclusive, sublicensable license, under patent claims owned or controlled + by the Licensor that are embodied in the Original Work as furnished by the + Licensor, for the duration of the patents, to make, use, sell, offer for sale, + have made, and import the Original Work and Derivative Works. + . + 3. **Grant of Source Code License.** The "Source Code" for a work means the + preferred form of the work for making modifications to it and all available + documentation describing how to modify the work. Licensor agrees to provide a + machine-readable copy of the Source Code of the Original Work along with each + copy of the Original Work that Licensor distributes. Licensor reserves the + right to satisfy this obligation by placing a machine-readable copy of said + Source Code in an Information Repository for as long as Licensor continues to + distribute the Original Work. + . + 4. **Exclusions From License Grant.** Neither the names of Licensor, nor the + names of any contributors to the Original Work, nor any of their trademarks or + service marks, may be used to endorse or promote products derived from this + Original Work without express prior permission of the Licensor. Except as + expressly stated herein, nothing in this License grants any license to + Licensor's trademarks, copyrights, patents, trade secrets or any other + intellectual property. No patent license is granted to make, use, sell, offer + for sale, have made, or import embodiments of any patent claims other than the + licensed claims defined in Section 2. No license is granted to the trademarks + of Licensor even if such marks are included in the Original Work. Nothing in + this License shall be interpreted to prohibit Licensor from licensing under + terms different from this License any Original Work that Licensor otherwise + would have a right to license. + . + 5. **External Deployment.** The term "External Deployment" means the use, + distribution, or communication of the Original Work or Derivative Works in any + way such that the Original Work or Derivative Works may be used by anyone other + than You, whether those works are distributed or communicated to those persons + or made available as an application intended for use over a network. As an + express condition for the grants of license hereunder, You must treat any + External Deployment by You of the Original Work or a Derivative Work as a + distribution under section 1(c). + . + 6. **Attribution Rights.** You must retain, in the Source Code of any + Derivative Works that You create, all copyright, patent, or trademark notices + from the Source Code of the Original Work, as well as any notices of licensing + and any descriptive text identified therein as an "Attribution Notice." You + must cause the Source Code for any Derivative Works that You create to carry a + prominent Attribution Notice reasonably calculated to inform recipients that + You have modified the Original Work. + . + 7. **Warranty of Provenance and Disclaimer of Warranty.** Licensor warrants + that the copyright in and to the Original Work and the patent rights granted + herein by Licensor are owned by the Licensor or are sublicensed to You under + the terms of this License with the permission of the contributor(s) of those + copyrights and patent rights. Except as expressly stated in the immediately + preceding sentence, the Original Work is provided under this License on an "AS + IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without + limitation, the warranties of non-infringement, merchantability or fitness for + a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS + WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this + License. No license to the Original Work is granted by this License except + under this disclaimer. + . + 8. **Limitation of Liability.** Under no circumstances and under no legal + theory, whether in tort (including negligence), contract, or otherwise, shall + the Licensor be liable to anyone for any indirect, special, incidental, or + consequential damages of any character arising as a result of this License or + the use of the Original Work including, without limitation, damages for loss of + goodwill, work stoppage, computer failure or malfunction, or any and all other + commercial damages or losses. This limitation of liability shall not apply to + the extent applicable law prohibits such limitation. + . + 9. **Acceptance and Termination.** If, at any time, You expressly assented to + this License, that assent indicates your clear and irrevocable acceptance of + this License and all of its terms and conditions. If You distribute or + communicate copies of the Original Work or a Derivative Work, You must make a + reasonable effort under the circumstances to obtain the express assent of + recipients to the terms of this License. This License conditions your rights to + undertake the activities listed in Section 1, including your right to create + Derivative Works based upon the Original Work, and doing so without honoring + these terms and conditions is prohibited by copyright law and international + treaty. Nothing in this License is intended to affect copyright exceptions and + limitations (including 'fair use' or 'fair dealing'). This License shall + terminate immediately and You may no longer exercise any of the rights granted + to You by this License upon your failure to honor the conditions in Section + 1(c). + . + 10. **Termination for Patent Action.** This License shall terminate + automatically and You may no longer exercise any of the rights granted to You + by this License as of the date You commence an action, including a cross-claim + or counterclaim, against Licensor or any licensee alleging that the Original + Work infringes a patent. This termination provision shall not apply for an + action alleging patent infringement by combinations of the Original Work with + other software or hardware. + . + 11. **Jurisdiction, Venue and Governing Law.** Any action or suit relating to + this License may be brought only in the courts of a jurisdiction wherein the + Licensor resides or in which Licensor conducts its primary business, and under + the laws of that jurisdiction excluding its conflict-of-law provisions. The + application of the United Nations Convention on Contracts for the International + Sale of Goods is expressly excluded. Any use of the Original Work outside the + scope of this License or after its termination shall be subject to the + requirements and penalties of copyright or patent law in the appropriate + jurisdiction. This section shall survive the termination of this License. + . + 12. **Attorneys' Fees.** In any action to enforce the terms of this License or + seeking damages relating thereto, the prevailing party shall be entitled to + recover its costs and expenses, including, without limitation, reasonable + attorneys' fees and costs incurred in connection with such action, including + any appeal of such action. This section shall survive the termination of this + License. + . + 13. **Miscellaneous.** If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent necessary to + make it enforceable. + . + 14. **Definition of "You" in This License.** "You" throughout this License, + whether in upper or lower case, means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this License. + For legal entities, "You" includes any entity that controls, is controlled by, + or is under common control with you. For 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. + . + 15. **Right to Use.** You may use the Original Work in all ways not otherwise + restricted or conditioned by this License or by law, and Licensor promises not + to interfere with or be responsible for such uses by You. + . + 16. **Modification of This License.** This License is Copyright © 2007 Zooko + Wilcox-O'Hearn. Permission is granted to copy, distribute, or communicate this + License without modification. Nothing in this License permits You to modify + this License as applied to the Original Work or to Derivative Works. However, + You may modify the text of this License and copy, distribute or communicate + your modified version (the "Modified License") and apply it to other original + works of authorship subject to the following conditions: (i) You may not + indicate in any way that your Modified License is the "Bootstrap Open Source + Licence" or "BOSL" and you may not use those names in the name of your Modified + License; and (ii) You must replace the notice specified in the first paragraph + above with the notice "Licensed under " or with + a notice of your own that is not confusingly similar to the notice in this + License. diff --git a/depend/zcash/contrib/debian/examples/zcash.conf b/depend/zcash/contrib/debian/examples/zcash.conf new file mode 100644 index 000000000..0293500d0 --- /dev/null +++ b/depend/zcash/contrib/debian/examples/zcash.conf @@ -0,0 +1,129 @@ +## +## zcash.conf configuration file. Lines beginning with # are comments. +## + +# Network-related settings: + +# Run on the test network instead of the real zcash network. +#testnet=0 + +# Run a regression test network +#regtest=0 + +# Connect via a SOCKS5 proxy +#proxy=127.0.0.1:9050 + +# Bind to given address and always listen on it. Use [host]:port notation for IPv6 +#bind= + +# Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 +#whitebind= + +############################################################## +## Quick Primer on addnode vs connect ## +## Let's say for instance you use addnode=4.2.2.4 ## +## addnode will connect you to and tell you about the ## +## nodes connected to 4.2.2.4. In addition it will tell ## +## the other nodes connected to it that you exist so ## +## they can connect to you. ## +## connect will not do the above when you 'connect' to it. ## +## It will *only* connect you to 4.2.2.4 and no one else.## +## ## +## So if you're behind a firewall, or have other problems ## +## finding nodes, add some using 'addnode'. ## +## ## +## If you want to stay private, use 'connect' to only ## +## connect to "trusted" nodes. ## +## ## +## If you run multiple nodes on a LAN, there's no need for ## +## all of them to open lots of connections. Instead ## +## 'connect' them all to one node that is port forwarded ## +## and has lots of connections. ## +## Thanks goes to [Noodle] on Freenode. ## +############################################################## + +# Use as many addnode= settings as you like to connect to specific peers +#addnode=69.164.218.197 +#addnode=10.0.0.2:8233 + +# Alternatively use as many connect= settings as you like to connect ONLY to specific peers +#connect=69.164.218.197 +#connect=10.0.0.1:8233 + +# Listening mode, enabled by default except when 'connect' is being used +#listen=1 + +# Maximum number of inbound+outbound connections. +#maxconnections= + +# +# JSON-RPC options (for controlling a running Zcash/zcashd process) +# + +# server=1 tells zcashd to accept JSON-RPC commands (set as default if not specified) +#server=1 + +# Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. +# This option can be specified multiple times (default: bind to all interfaces) +#rpcbind= + +# You must set rpcuser and rpcpassword to secure the JSON-RPC api +#rpcuser=Ulysses +#rpcpassword=YourSuperGreatPasswordNumber_DO_NOT_USE_THIS_OR_YOU_WILL_GET_ROBBED_385593 + +# How many seconds zcash will wait for a complete RPC HTTP request. +# after the HTTP connection is established. +#rpcclienttimeout=30 + +# By default, only RPC connections from localhost are allowed. +# Specify as many rpcallowip= settings as you like to allow connections from other hosts, +# either as a single IPv4/IPv6 or with a subnet specification. + +# NOTE: opening up the RPC port to hosts outside your local trusted network is NOT RECOMMENDED, +# because the rpcpassword is transmitted over the network unencrypted and also because anyone +# that can authenticate on the RPC port can steal your keys + take over the account running zcashd +# For more information see https://github.com/zcash/zcash/issues/1497 + +#rpcallowip=10.1.1.34/255.255.255.0 +#rpcallowip=1.2.3.4/24 +#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96 + +# Listen for RPC connections on this TCP port: +#rpcport=8232 + +# You can use Zcash or zcashd to send commands to Zcash/zcashd +# running on another host using this option: +#rpcconnect=127.0.0.1 + +# Transaction Fee + +# Send transactions as zero-fee transactions if possible (default: 0) +#sendfreetransactions=0 + +# Create transactions that have enough fees (or priority) so they are likely to # begin confirmation within n blocks (default: 1). +# This setting is overridden by the -paytxfee option. +#txconfirmtarget=n + +# Miscellaneous options + +# Enable attempt to mine zcash. +#gen=0 + +# Set the number of threads to be used for mining zcash (-1 = all cores). +#genproclimit=1 + +# Specify a different Equihash solver (e.g. "tromp") to try to mine zcash +# faster when gen=1. +#equihashsolver=default + +# Pre-generate this many public/private key pairs, so wallet backups will be valid for +# both prior transactions and several dozen future transactions. +#keypool=100 + +# Pay an optional transaction fee every time you send zcash. Transactions with fees +# are more likely than free transactions to be included in generated blocks, so may +# be validated sooner. This setting does not affect private transactions created with +# 'z_sendmany'. +#paytxfee=0.00 + + diff --git a/depend/zcash/contrib/debian/postinst b/depend/zcash/contrib/debian/postinst new file mode 100755 index 000000000..2e6ff8a8d --- /dev/null +++ b/depend/zcash/contrib/debian/postinst @@ -0,0 +1,39 @@ +#!/bin/sh +# postinst script for zcash +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/depend/zcash/contrib/debian/postrm b/depend/zcash/contrib/debian/postrm new file mode 100755 index 000000000..bb442a682 --- /dev/null +++ b/depend/zcash/contrib/debian/postrm @@ -0,0 +1,37 @@ +#!/bin/sh +# postrm script for zcash +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/depend/zcash/contrib/debian/preinst b/depend/zcash/contrib/debian/preinst new file mode 100755 index 000000000..7587b4a88 --- /dev/null +++ b/depend/zcash/contrib/debian/preinst @@ -0,0 +1,35 @@ +#!/bin/sh +# preinst script for zcash +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `install' +# * `install' +# * `upgrade' +# * `abort-upgrade' +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + install|upgrade) + ;; + + abort-upgrade) + ;; + + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/depend/zcash/contrib/debian/prerm b/depend/zcash/contrib/debian/prerm new file mode 100755 index 000000000..6a4f8c033 --- /dev/null +++ b/depend/zcash/contrib/debian/prerm @@ -0,0 +1,38 @@ +#!/bin/sh +# prerm script for zcash +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove|upgrade|deconfigure) + ;; + + failed-upgrade) + ;; + + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/depend/zcash/contrib/debian/rules b/depend/zcash/contrib/debian/rules new file mode 100755 index 000000000..b79cce595 --- /dev/null +++ b/depend/zcash/contrib/debian/rules @@ -0,0 +1,25 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ --with autotools_dev + + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + diff --git a/depend/zcash/contrib/debian/zcash.examples b/depend/zcash/contrib/debian/zcash.examples new file mode 100644 index 000000000..924659c02 --- /dev/null +++ b/depend/zcash/contrib/debian/zcash.examples @@ -0,0 +1 @@ +DEBIAN/examples/zcash.conf diff --git a/depend/zcash/contrib/debian/zcash.install b/depend/zcash/contrib/debian/zcash.install new file mode 100644 index 000000000..b39eaeeb3 --- /dev/null +++ b/depend/zcash/contrib/debian/zcash.install @@ -0,0 +1,3 @@ +usr/bin/zcashd +usr/bin/zcash-cli +usr/bin/zcash-fetch-params diff --git a/depend/zcash/contrib/debian/zcash.manpages b/depend/zcash/contrib/debian/zcash.manpages new file mode 100644 index 000000000..a1115f679 --- /dev/null +++ b/depend/zcash/contrib/debian/zcash.manpages @@ -0,0 +1,2 @@ +DEBIAN/manpages/zcash-cli.1 +DEBIAN/manpages/zcashd.1 diff --git a/depend/zcash/contrib/devtools/README.md b/depend/zcash/contrib/devtools/README.md new file mode 100644 index 000000000..e16e6b5b0 --- /dev/null +++ b/depend/zcash/contrib/devtools/README.md @@ -0,0 +1,102 @@ +Contents +=========== +This directory contains tools for developers working on this repository. + +github-merge.sh +================== + +A small script to automate merging pull-requests securely and sign them with GPG. + +For example: + + ./github-merge.sh bitcoin/bitcoin 3077 + +(in any git repository) will help you merge pull request #3077 for the +bitcoin/bitcoin repository. + +What it does: +* Fetch master and the pull request. +* Locally construct a merge commit. +* Show the diff that merge results in. +* Ask you to verify the resulting source tree (so you can do a make +check or whatever). +* Ask you whether to GPG sign the merge commit. +* Ask you whether to push the result upstream. + +This means that there are no potential race conditions (where a +pullreq gets updated while you're reviewing it, but before you click +merge), and when using GPG signatures, that even a compromised github +couldn't mess with the sources. + +Setup +--------- +Configuring the github-merge tool for the bitcoin repository is done in the following way: + + git config githubmerge.repository bitcoin/bitcoin + git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing) + git config --global user.signingkey mykeyid (if you want to GPG sign) + +fix-copyright-headers.py +=========================== + +Every year newly updated files need to have its copyright headers updated to reflect the current year. +If you run this script from src/ it will automatically update the year on the copyright header for all +.cpp and .h files if these have a git commit from the current year. + +For example a file changed in 2014 (with 2014 being the current year): +```// Copyright (c) 2009-2013 The Bitcoin Core developers``` + +would be changed to: +```// Copyright (c) 2009-2014 The Bitcoin Core developers``` + +symbol-check.py +================== + +A script to check that the (Linux) executables produced by gitian only contain +allowed gcc, glibc and libstdc++ version symbols. This makes sure they are +still compatible with the minimum supported Linux distribution versions. + +Example usage after a gitian build: + + find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py + +If only supported symbols are used the return value will be 0 and the output will be empty. + +If there are 'unsupported' symbols, the return value will be 1 a list like this will be printed: + + .../64/test_bitcoin: symbol memcpy from unsupported version GLIBC_2.14 + .../64/test_bitcoin: symbol __fdelt_chk from unsupported version GLIBC_2.15 + .../64/test_bitcoin: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15 + .../64/test_bitcoin: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15 + +update-translations.py +======================= + +Run this script from the root of the repository to update all translations from transifex. +It will do the following automatically: + +- fetch all translations +- post-process them into valid and committable format +- add missing translations to the build system (TODO) + +See doc/translation-process.md for more information. + +gen-manpages.sh +=============== + +A small script to automatically create manpages in ../../doc/man by running the release binaries with the -help option. +This requires help2man which can be found at: https://www.gnu.org/software/help2man/ + +git-subtree-check.sh +==================== + +Run this script from the root of the repository to verify that a subtree matches the contents of +the commit it claims to have been updated to. + +To use, make sure that you have fetched the upstream repository branch in which the subtree is +maintained: +* for src/secp256k1: https://github.com/bitcoin/secp256k1.git (branch master) +* for sec/leveldb: https://github.com/bitcoin/leveldb.git (branch bitcoin-fork) + +Usage: git-subtree-check.sh DIR COMMIT +COMMIT may be omitted, in which case HEAD is used. diff --git a/depend/zcash/contrib/devtools/fix-copyright-headers.py b/depend/zcash/contrib/devtools/fix-copyright-headers.py new file mode 100755 index 000000000..14b6de706 --- /dev/null +++ b/depend/zcash/contrib/devtools/fix-copyright-headers.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +''' +Run this script inside of src/ and it will look for all the files +that were changed this year that still have the last year in the +copyright headers, and it will fix the headers on that file using +a perl regex one liner. + +For example: if it finds something like this and we're in 2014 + +// Copyright (c) 2009-2013 The Bitcoin Core developers + +it will change it to + +// Copyright (c) 2009-2014 The Bitcoin Core developers + +It will do this for all the files in the folder and its children. + +Author: @gubatron +''' +import os +import time + +year = time.gmtime()[0] +last_year = year - 1 +command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s" +listFilesCommand = "find . | grep %s" + +extensions = [".cpp",".h"] + +def getLastGitModifiedDate(filePath): + gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1" + p = os.popen(gitGetLastCommitDateCommand) + result = "" + for l in p: + result = l + break + result = result.replace("\n","") + return result + +n=1 +for extension in extensions: + foundFiles = os.popen(listFilesCommand % extension) + for filePath in foundFiles: + filePath = filePath[1:-1] + if filePath.endswith(extension): + filePath = os.getcwd() + filePath + modifiedTime = getLastGitModifiedDate(filePath) + if len(modifiedTime) > 0 and str(year) in modifiedTime: + print(n,"Last Git Modified: ", modifiedTime, " - ", filePath) + os.popen(command % (last_year,year,filePath)) + n = n + 1 + + diff --git a/depend/zcash/contrib/devtools/gen-manpages.sh b/depend/zcash/contrib/devtools/gen-manpages.sh new file mode 100755 index 000000000..fb9496b54 --- /dev/null +++ b/depend/zcash/contrib/devtools/gen-manpages.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +export LC_ALL=C +TOPDIR=${TOPDIR:-$(git rev-parse --show-toplevel)} +SRCDIR=${SRCDIR:-$TOPDIR/src} +MANDIR=${MANDIR:-$TOPDIR/doc/man} + +ZCASHD=${ZCASHD:-$SRCDIR/zcashd} +ZCASHD_WALLET_TOOL=${ZCASHD_WALLET_TOOL:-$SRCDIR/zcashd-wallet-tool} +ZCASHCLI=${ZCASHCLI:-$SRCDIR/zcash-cli} +ZCASHTX=${ZCASHTX:-$SRCDIR/zcash-tx} + +[ ! -x $ZCASHD ] && echo "$ZCASHD not found or not executable." && exit 1 + +# The autodetected version git tag can screw up manpage output a little bit +read -r -a ZECVERSTR <<< "$($ZCASHCLI --version | head -n1 | awk '{ print $NF }')" +read -r -a ZECVER <<< "$(echo $ZECVERSTR | awk -F- '{ OFS="-"; NF--; print $0; }')" +read -r -a ZECCOMMIT <<< "$(echo $ZECVERSTR | awk -F- '{ print $NF }')" + +# Create a footer file with copyright content. +# This gets autodetected fine for zcashd if --version-string is not set, +# but has different outcomes for zcash-cli. +echo "[COPYRIGHT]" > footer.h2m +$ZCASHD --version | sed -n '1!p' >> footer.h2m +grep -v "Bitcoin Core Developers" footer.h2m >footer-no-bitcoin-copyright.h2m + +for cmd in $ZCASHD $ZCASHCLI $ZCASHTX; do + cmdname="${cmd##*/}" + help2man -N --version-string=$ZECVER --include=footer.h2m -o ${MANDIR}/${cmdname}.1 ${cmd} + sed -i "s/\\\-$ZECCOMMIT//g" ${MANDIR}/${cmdname}.1 +done + +for cmd in $ZCASHD_WALLET_TOOL; do + cmdname="${cmd##*/}" + help2man -N --version-string=$ZECVER --include=footer-no-bitcoin-copyright.h2m -o ${MANDIR}/${cmdname}.1 ${cmd} + sed -i "s/\\\-$ZECCOMMIT//g" ${MANDIR}/${cmdname}.1 +done + +rm -f footer.h2m +rm -f footer-no-bitcoin-copyright.h2m diff --git a/depend/zcash/contrib/devtools/github-merge.sh b/depend/zcash/contrib/devtools/github-merge.sh new file mode 100755 index 000000000..ec7a1f4c4 --- /dev/null +++ b/depend/zcash/contrib/devtools/github-merge.sh @@ -0,0 +1,181 @@ +#!/bin/bash + +# This script will locally construct a merge commit for a pull request on a +# github repository, inspect it, sign it and optionally push it. + +# The following temporary branches are created/overwritten and deleted: +# * pull/$PULL/base (the current master we're merging onto) +# * pull/$PULL/head (the current state of the remote pull request) +# * pull/$PULL/merge (github's merge) +# * pull/$PULL/local-merge (our merge) + +# In case of a clean merge that is accepted by the user, the local branch with +# name $BRANCH is overwritten with the merged result, and optionally pushed. + +REPO="$(git config --get githubmerge.repository)" +if [[ "d$REPO" == "d" ]]; then + echo "ERROR: No repository configured. Use this command to set:" >&2 + echo "git config githubmerge.repository /" >&2 + echo "In addition, you can set the following variables:" >&2 + echo "- githubmerge.host (default git@github.com)" >&2 + echo "- githubmerge.branch (default master)" >&2 + echo "- githubmerge.testcmd (default none)" >&2 + exit 1 +fi + +HOST="$(git config --get githubmerge.host)" +if [[ "d$HOST" == "d" ]]; then + HOST="git@github.com" +fi + +BRANCH="$(git config --get githubmerge.branch)" +if [[ "d$BRANCH" == "d" ]]; then + BRANCH="master" +fi + +TESTCMD="$(git config --get githubmerge.testcmd)" + +PULL="$1" + +if [[ "d$PULL" == "d" ]]; then + echo "Usage: $0 pullnumber [branch]" >&2 + exit 2 +fi + +if [[ "d$2" != "d" ]]; then + BRANCH="$2" +fi + +# Initialize source branches. +git checkout -q "$BRANCH" +if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then + if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then + echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2 + exit 3 + fi + if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then + echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2 + exit 3 + fi +else + echo "ERROR: Cannot find pull request #$PULL on $HOST:$REPO." >&2 + exit 3 +fi +if git fetch -q "$HOST":"$REPO" +refs/heads/"$BRANCH":refs/heads/pull/"$PULL"/base; then + true +else + echo "ERROR: Cannot find branch $BRANCH on $HOST:$REPO." >&2 + exit 3 +fi +git checkout -q pull/"$PULL"/base +git branch -q -D pull/"$PULL"/local-merge 2>/dev/null +git checkout -q -b pull/"$PULL"/local-merge +TMPDIR="$(mktemp -d -t ghmXXXXX)" + +function cleanup() { + git checkout -q "$BRANCH" + git branch -q -D pull/"$PULL"/head 2>/dev/null + git branch -q -D pull/"$PULL"/base 2>/dev/null + git branch -q -D pull/"$PULL"/merge 2>/dev/null + git branch -q -D pull/"$PULL"/local-merge 2>/dev/null + rm -rf "$TMPDIR" +} + +# Create unsigned merge commit. +( + echo "Merge pull request #$PULL" + echo "" + git log --no-merges --topo-order --pretty='format:%h %s (%an)' pull/"$PULL"/base..pull/"$PULL"/head +)>"$TMPDIR/message" +if git merge -q --commit --no-edit --no-ff -m "$(<"$TMPDIR/message")" pull/"$PULL"/head; then + if [ "d$(git log --pretty='format:%s' -n 1)" != "dMerge pull request #$PULL" ]; then + echo "ERROR: Creating merge failed (already merged?)." >&2 + cleanup + exit 4 + fi +else + echo "ERROR: Cannot be merged cleanly." >&2 + git merge --abort + cleanup + exit 4 +fi + +# Run test command if configured. +if [[ "d$TESTCMD" != "d" ]]; then + # Go up to the repository's root. + while [ ! -d .git ]; do cd ..; done + if ! $TESTCMD; then + echo "ERROR: Running $TESTCMD failed." >&2 + cleanup + exit 5 + fi + # Show the created merge. + git diff pull/"$PULL"/merge..pull/"$PULL"/local-merge >"$TMPDIR"/diff + git diff pull/"$PULL"/base..pull/"$PULL"/local-merge + if [[ "$(<"$TMPDIR"/diff)" != "" ]]; then + echo "WARNING: merge differs from github!" >&2 + read -p "Type 'ignore' to continue. " -r >&2 + if [[ "d$REPLY" =~ ^d[iI][gG][nN][oO][rR][eE]$ ]]; then + echo "Difference with github ignored." >&2 + else + cleanup + exit 6 + fi + fi + read -p "Press 'd' to accept the diff. " -n 1 -r >&2 + echo + if [[ "d$REPLY" =~ ^d[dD]$ ]]; then + echo "Diff accepted." >&2 + else + echo "ERROR: Diff rejected." >&2 + cleanup + exit 6 + fi +else + # Verify the result. + echo "Dropping you on a shell so you can try building/testing the merged source." >&2 + echo "Run 'git diff HEAD~' to show the changes being merged." >&2 + echo "Type 'exit' when done." >&2 + if [[ -f /etc/debian_version ]]; then # Show pull number in prompt on Debian default prompt + export debian_chroot="$PULL" + fi + bash -i + read -p "Press 'm' to accept the merge. " -n 1 -r >&2 + echo + if [[ "d$REPLY" =~ ^d[Mm]$ ]]; then + echo "Merge accepted." >&2 + else + echo "ERROR: Merge rejected." >&2 + cleanup + exit 7 + fi +fi + +# Sign the merge commit. +read -p "Press 's' to sign off on the merge. " -n 1 -r >&2 +echo +if [[ "d$REPLY" =~ ^d[Ss]$ ]]; then + if [[ "$(git config --get user.signingkey)" == "" ]]; then + echo "ERROR: No GPG signing key set, not signing. Set one using:" >&2 + echo "git config --global user.signingkey " >&2 + cleanup + exit 1 + else + git commit -q --gpg-sign --amend --no-edit + fi +else + echo "Not signing off on merge, exiting." + cleanup + exit 1 +fi + +# Clean up temporary branches, and put the result in $BRANCH. +git checkout -q "$BRANCH" +git reset -q --hard pull/"$PULL"/local-merge +cleanup + +# Push the result. +read -p "Type 'push' to push the result to $HOST:$REPO, branch $BRANCH. " -r >&2 +if [[ "d$REPLY" =~ ^d[Pp][Uu][Ss][Hh]$ ]]; then + git push "$HOST":"$REPO" refs/heads/"$BRANCH" +fi diff --git a/depend/zcash/contrib/devtools/optimize-pngs.py b/depend/zcash/contrib/devtools/optimize-pngs.py new file mode 100755 index 000000000..3cfd10d24 --- /dev/null +++ b/depend/zcash/contrib/devtools/optimize-pngs.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 + +import os +import sys +import subprocess +import hashlib +from PIL import Image + +def file_hash(filename): + '''Return hash of raw file contents''' + with open(filename, 'rb') as f: + return hashlib.sha256(f.read()).hexdigest() + +def content_hash(filename): + '''Return hash of RGBA contents of image''' + i = Image.open(filename) + i = i.convert('RGBA') + data = i.tostring() + return hashlib.sha256(data).hexdigest() + +#optimize png, remove various color profiles, remove ancillary chunks (alla) and text chunks (text) +#pngcrush -brute -ow -rem gAMA -rem cHRM -rem iCCP -rem sRGB -rem alla -rem text + +pngcrush = 'pngcrush' +git = 'git' +folders = ["src/qt/res/movies", "src/qt/res/icons", "src/qt/res/images"] +basePath = subprocess.check_output([git, 'rev-parse', '--show-toplevel']).rstrip('\n') +totalSaveBytes = 0 + +outputArray = [] +for folder in folders: + absFolder=os.path.join(basePath, folder) + for file in os.listdir(absFolder): + extension = os.path.splitext(file)[1] + if extension.lower() == '.png': + print("optimizing "+file+"..."), + file_path = os.path.join(absFolder, file) + fileMetaMap = {'file' : file, 'osize': os.path.getsize(file_path), 'sha256Old' : file_hash(file_path)}; + fileMetaMap['contentHashPre'] = content_hash(file_path) + + pngCrushOutput = "" + try: + pngCrushOutput = subprocess.check_output( + [pngcrush, "-brute", "-ow", "-rem", "gAMA", "-rem", "cHRM", "-rem", "iCCP", "-rem", "sRGB", "-rem", "alla", "-rem", "text", file_path], + stderr=subprocess.STDOUT).rstrip('\n') + except: + print("pngcrush is not installed, aborting...") + sys.exit(0) + + #verify + if "Not a PNG file" in subprocess.check_output([pngcrush, "-n", "-v", file_path], stderr=subprocess.STDOUT): + print("PNG file "+file+" is corrupted after crushing, check out pngcursh version") + sys.exit(1) + + fileMetaMap['sha256New'] = file_hash(file_path) + fileMetaMap['contentHashPost'] = content_hash(file_path) + + if fileMetaMap['contentHashPre'] != fileMetaMap['contentHashPost']: + print("Image contents of PNG file "+file+" before and after crushing don't match") + sys.exit(1) + + fileMetaMap['psize'] = os.path.getsize(file_path) + outputArray.append(fileMetaMap) + print("done\n"), + +print("summary:\n+++++++++++++++++") +for fileDict in outputArray: + oldHash = fileDict['sha256Old'] + newHash = fileDict['sha256New'] + totalSaveBytes += fileDict['osize'] - fileDict['psize'] + print(fileDict['file']+"\n size diff from: "+str(fileDict['osize'])+" to: "+str(fileDict['psize'])+"\n old sha256: "+oldHash+"\n new sha256: "+newHash+"\n") + +print("completed. Total reduction: "+str(totalSaveBytes)+" bytes") diff --git a/depend/zcash/contrib/devtools/rust-deps-graph.sh b/depend/zcash/contrib/devtools/rust-deps-graph.sh new file mode 100755 index 000000000..7e7804f1c --- /dev/null +++ b/depend/zcash/contrib/devtools/rust-deps-graph.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +export LC_ALL=C + +# default arguments are --no-transitive-deps +ARGS="${*:---no-transitive-deps}" +echo "Using args: $ARGS" + +cargo deps $ARGS | dot \ + -Earrowhead=vee \ + -Gratio=0.45 \ + -Gsize=50 \ + -Nheight=0.8 \ + -Nfillcolor=LavenderBlush \ + -Nstyle=filled \ + -Nfontsize=18 \ + -Nmargin=0.05,0.05 \ + -Tpng > rust-dependency-graph.png diff --git a/depend/zcash/contrib/devtools/security-check.py b/depend/zcash/contrib/devtools/security-check.py new file mode 100755 index 000000000..ca1a6e0ea --- /dev/null +++ b/depend/zcash/contrib/devtools/security-check.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python +''' +Perform basic ELF security checks on a series of executables. +Exit status will be 0 if successful, and the program will be silent. +Otherwise the exit status will be 1 and it will log which executables failed which checks. +Needs `readelf` (for ELF) and `objdump` (for PE). +''' +from __future__ import division,print_function,unicode_literals +import struct +import subprocess +import sys +import os + +READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') +OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') +NONFATAL = {'HIGH_ENTROPY_VA'} # checks which are non-fatal for now but only generate a warning + +def check_ELF_PIE(executable): + ''' + Check for position independent executable (PIE), allowing for address space randomization. + ''' + p = subprocess.Popen([READELF_CMD, '-h', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + + ok = False + for line in stdout.split(b'\n'): + line = line.split() + if len(line)>=2 and line[0] == b'Type:' and line[1] == b'DYN': + ok = True + return ok + +def get_ELF_program_headers(executable): + '''Return type and flags for ELF program headers''' + p = subprocess.Popen([READELF_CMD, '-l', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + in_headers = False + count = 0 + headers = [] + for line in stdout.split(b'\n'): + if line.startswith(b'Program Headers:'): + in_headers = True + if line == b'': + in_headers = False + if in_headers: + if count == 1: # header line + ofs_typ = line.find(b'Type') + ofs_offset = line.find(b'Offset') + ofs_flags = line.find(b'Flg') + ofs_align = line.find(b'Align') + if ofs_typ == -1 or ofs_offset == -1 or ofs_flags == -1 or ofs_align == -1: + raise ValueError('Cannot parse elfread -lW output') + elif count > 1: + typ = line[ofs_typ:ofs_offset].rstrip() + flags = line[ofs_flags:ofs_align].rstrip() + headers.append((typ, flags)) + count += 1 + return headers + +def check_ELF_NX(executable): + ''' + Check that no sections are writable and executable (including the stack) + ''' + have_wx = False + have_gnu_stack = False + for (typ, flags) in get_ELF_program_headers(executable): + if typ == b'GNU_STACK': + have_gnu_stack = True + if b'W' in flags and b'E' in flags: # section is both writable and executable + have_wx = True + return have_gnu_stack and not have_wx + +def check_ELF_RELRO(executable): + ''' + Check for read-only relocations. + GNU_RELRO program header must exist + Dynamic section must have BIND_NOW flag + ''' + have_gnu_relro = False + for (typ, flags) in get_ELF_program_headers(executable): + # Note: not checking flags == 'R': here as linkers set the permission differently + # This does not affect security: the permission flags of the GNU_RELRO program header are ignored, the PT_LOAD header determines the effective permissions. + # However, the dynamic linker need to write to this area so these are RW. + # Glibc itself takes care of mprotecting this area R after relocations are finished. + # See also http://permalink.gmane.org/gmane.comp.gnu.binutils/71347 + if typ == b'GNU_RELRO': + have_gnu_relro = True + + have_bindnow = False + p = subprocess.Popen([READELF_CMD, '-d', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + for line in stdout.split(b'\n'): + tokens = line.split() + if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2:]): + have_bindnow = True + return have_gnu_relro and have_bindnow + +def check_ELF_Canary(executable): + ''' + Check for use of stack canary + ''' + p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + ok = False + for line in stdout.split(b'\n'): + if b'__stack_chk_fail' in line: + ok = True + return ok + +def get_PE_dll_characteristics(executable): + ''' + Get PE DllCharacteristics bits. + Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386' + and bits is the DllCharacteristics value. + ''' + p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + arch = '' + bits = 0 + for line in stdout.split('\n'): + tokens = line.split() + if len(tokens)>=2 and tokens[0] == 'architecture:': + arch = tokens[1].rstrip(',') + if len(tokens)>=2 and tokens[0] == 'DllCharacteristics': + bits = int(tokens[1],16) + return (arch,bits) + +IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 +IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040 +IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100 + +def check_PE_DYNAMIC_BASE(executable): + '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' + (arch,bits) = get_PE_dll_characteristics(executable) + reqbits = IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE + return (bits & reqbits) == reqbits + +# On 64 bit, must support high-entropy 64-bit address space layout randomization in addition to DYNAMIC_BASE +# to have secure ASLR. +def check_PE_HIGH_ENTROPY_VA(executable): + '''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR''' + (arch,bits) = get_PE_dll_characteristics(executable) + if arch == 'i386:x86-64': + reqbits = IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA + else: # Unnecessary on 32-bit + assert(arch == 'i386') + reqbits = 0 + return (bits & reqbits) == reqbits + +def check_PE_NX(executable): + '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)''' + (arch,bits) = get_PE_dll_characteristics(executable) + return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT + +CHECKS = { +'ELF': [ + ('PIE', check_ELF_PIE), + ('NX', check_ELF_NX), + ('RELRO', check_ELF_RELRO), + ('Canary', check_ELF_Canary) +], +'PE': [ + ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), + ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), + ('NX', check_PE_NX) +], +'MachO64': [ +] +} + +def identify_executable(executable): + with open(filename, 'rb') as f: + magic = f.read(4) + if magic.startswith(b'MZ'): + return 'PE' + elif magic.startswith(b'\x7fELF'): + return 'ELF' + elif struct.unpack('I', magic)[0] == 0xFEEDFACF: + return 'MachO64' + return None + +if __name__ == '__main__': + args = sys.argv[1:] + allow_no_canary = "--allow-no-canary" in args + files = [arg for arg in args if not arg.startswith("--")] + + retval = 0 + for filename in files: + try: + etype = identify_executable(filename) + if etype is None: + print('%s: unknown format' % filename) + retval = 1 + continue + + failed = [] + warning = [] + for (name, func) in CHECKS[etype]: + if name == "Canary" and allow_no_canary: + continue + if not func(filename): + if name in NONFATAL: + warning.append(name) + else: + failed.append(name) + if failed: + print('%s: failed %s' % (filename, ' '.join(failed))) + retval = 1 + if warning: + print('%s: warning %s' % (filename, ' '.join(warning))) + except IOError: + print('%s: cannot open' % filename) + retval = 1 + exit(retval) + diff --git a/depend/zcash/contrib/devtools/split-debug.sh b/depend/zcash/contrib/devtools/split-debug.sh new file mode 100755 index 000000000..16fda3005 --- /dev/null +++ b/depend/zcash/contrib/devtools/split-debug.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ $# -ne 3 ]; + then echo "usage: $0 " +fi + +/usr/bin/objcopy --enable-deterministic-archives -p --only-keep-debug $1 $3 +/usr/bin/objcopy --enable-deterministic-archives -p --strip-debug $1 $2 +/usr/bin/strip --enable-deterministic-archives -p -s $2 +/usr/bin/objcopy --enable-deterministic-archives -p --add-gnu-debuglink=$3 $2 diff --git a/depend/zcash/contrib/devtools/symbol-check.py b/depend/zcash/contrib/devtools/symbol-check.py new file mode 100755 index 000000000..92cf59f8f --- /dev/null +++ b/depend/zcash/contrib/devtools/symbol-check.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +# Copyright (c) 2014 Wladimir J. van der Laan +# Copyright (c) 2016-2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +''' +A script to check that the (Linux) executables produced by gitian only contain +allowed gcc and glibc version symbols. This makes sure they are still compatible +with the minimum supported Linux distribution versions. + +Example usage: + + find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py +''' +from __future__ import division, print_function +import subprocess +import re +import sys +import os + +# Ubuntu 16.04 LTS (Xenial Xerus; End of Standard Support April 2021, EOL April 2022) has: +# +# - g++ version 4.5.3 (https://packages.ubuntu.com/search?suite=all&searchon=names&keywords=g%2B%2B) +# - libc6 version 2.23 (https://packages.ubuntu.com/search?suite=all&searchon=names&keywords=libc6) +# +# Debian 9 (Stretch; EOL 2020-07-06, LTS EOL in 2022) has: +# +# - g++ version 6.3.0 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=g%2B%2B) +# - libc6 version 2.24 (https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=libc6) +# +# RedHat Enterprise Linux 8 (EOL: long and complicated) is based on Fedora 28 (EOL 2019-05-28) and uses the same base packages: +# +# - g++ version 8.0.1 (https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/28/Everything/x86_64/os/Packages/g/ search for gcc-) +# - libc6 version 2.27 (https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/28/Everything/x86_64/os/Packages/g/ search for glibc) +# +# CentOS 8 (Full update EOL May 2024, Maintenance EOL 2029-05-31) has: +# +# - g++ version 8.3.1 (https://centos.pkgs.org/8/centos-baseos-x86_64/ search for libgcc) +# - libc6 version 2.28 (https://centos.pkgs.org/8/centos-baseos-x86_64/ search for glibc) +# +# Fedora 31 (EOL ~November 2020) has: +# +# - g++ version 9.2.1 (https://dl.fedoraproject.org/pub/fedora/linux/releases/31/Everything/x86_64/os/Packages/g/ search for gcc-) +# - libc6 version 2.30 (https://dl.fedoraproject.org/pub/fedora/linux/releases/31/Everything/x86_64/os/Packages/g/ search for glibc) +# +# Arch is a rolling release, and as of October 2020 has packages for: +# +# - g++ version 8.4.0 / 9.3.0 / 10.2.0 (https://www.archlinux.org/packages/?q=gcc) +# - libc6 version 2.32 (https://www.archlinux.org/packages/?q=glibc) +# +# We take the minimum of these as our target. In practice, if we build on Xenial without +# upgrading GCC or libc, then we should get a binary that works for all these systems, and +# later ones. +# +# According to the GNU ABI document (https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) this corresponds to: +# GCC 4.5.3: GCC_4.5.0, GLIBCXX_3.4.14, CXXABI_1.3.4 +# libc6: GLIBC_2_23 + +# We statically link libc++ and libc++abi in our builds. Set this to allow dynamic linking to libstdc++. +ALLOW_DYNAMIC_LIBSTDCXX = False + +MAX_VERSIONS = { + 'GCC': (4,5,0), + 'GLIBC': (2,23), +} +if ALLOW_DYNAMIC_LIBSTDCXX: + MAX_VERSIONS.update({ + 'GLIBCXX': (3,4,14), + 'CXXABI': (1,3,4), + }) + +# See here for a description of _IO_stdin_used: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 + +# Ignore symbols that are exported as part of every executable +IGNORE_EXPORTS = { + '_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used' +} +READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') +CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt') + +# Allowed NEEDED libraries +ALLOWED_LIBRARIES = { + # zcashd + 'libgcc_s.so.1', # GCC support library (also used by clang) + 'libc.so.6', # C library + 'libpthread.so.0', # threading + 'libanl.so.1', # DNS resolver + 'libm.so.6', # math library + 'librt.so.1', # real-time (POSIX compatibility) + 'ld-linux-x86-64.so.2', # 64-bit dynamic linker + 'ld-linux.so.2', # 32-bit dynamic linker + 'libdl.so.2' # programming interface to dynamic linker +} +if ALLOW_DYNAMIC_LIBSTDCXX: + ALLOWED_LIBRARIES.add('libstdc++.so.6') # C++ standard library + + +class CPPFilt(object): + ''' + Demangle C++ symbol names. + + Use a pipe to the 'c++filt' command. + ''' + def __init__(self): + self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + + def __call__(self, mangled): + self.proc.stdin.write(mangled + '\n') + return self.proc.stdout.readline().rstrip() + + def close(self): + self.proc.stdin.close() + self.proc.stdout.close() + self.proc.wait() + +def read_symbols(executable, imports=True): + ''' + Parse an ELF executable and return a list of (symbol,version) tuples + for dynamic, imported symbols. + ''' + p = subprocess.Popen([READELF_CMD, '--dyn-syms', '-W', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Could not read symbols for %s: %s' % (executable, stderr.strip())) + syms = [] + for line in stdout.split('\n'): + line = line.split() + if len(line)>7 and re.match('[0-9]+:$', line[0]): + (sym, _, version) = line[7].partition('@') + is_import = line[6] == 'UND' + if version.startswith('@'): + version = version[1:] + if is_import == imports: + syms.append((sym, version)) + return syms + +def check_version(max_versions, version): + if '_' in version: + (lib, _, ver) = version.rpartition('_') + else: + lib = version + ver = '0' + ver = tuple([int(x) for x in ver.split('.')]) + if not lib in max_versions: + return False + return ver <= max_versions[lib] + +def read_libraries(filename): + p = subprocess.Popen([READELF_CMD, '-d', '-W', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + (stdout, stderr) = p.communicate() + if p.returncode: + raise IOError('Error opening file') + libraries = [] + for line in stdout.split('\n'): + tokens = line.split() + if len(tokens)>2 and tokens[1] == '(NEEDED)': + match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) + if match: + libraries.append(match.group(1)) + else: + raise ValueError('Unparseable (NEEDED) specification') + return libraries + +if __name__ == '__main__': + cppfilt = CPPFilt() + retval = 0 + for filename in sys.argv[1:]: + print("Checking %s..." % (filename,)) + # Check imported symbols + for sym,version in read_symbols(filename, True): + if version and not check_version(MAX_VERSIONS, version): + print('%s: symbol %s from unsupported version %s' % (filename, cppfilt(sym), version)) + retval = 1 + # Check exported symbols + for sym,version in read_symbols(filename, False): + if sym in IGNORE_EXPORTS: + continue + print('%s: export of symbol %s not allowed' % (filename, cppfilt(sym))) + retval = 1 + # Check dependency libraries + for library_name in read_libraries(filename): + if library_name not in ALLOWED_LIBRARIES: + print('%s: NEEDED library %s is not allowed' % (filename, library_name)) + retval = 1 + print() + + if retval == 0: + print("Everything OK") + else: + print("Note: this script is intended to ensure that Gitian builds meet our compatibility policy.") + print("The above warnings do not necessarily mean the program(s) will not work on your system.") + + exit(retval) diff --git a/depend/zcash/contrib/devtools/test-security-check.py b/depend/zcash/contrib/devtools/test-security-check.py new file mode 100755 index 000000000..b16d9aee3 --- /dev/null +++ b/depend/zcash/contrib/devtools/test-security-check.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +''' +Test script for security-check.py +''' +import subprocess +import sys +import unittest + +def write_testcode(filename): + with open(filename, 'w', encoding="utf8") as f: + f.write(''' + #include + int main() + { + printf("the quick brown fox jumps over the lazy god\\n"); + return 0; + } + ''') + +def call_security_check(cc, source, executable, options): + subprocess.check_call([cc,source,'-o',executable] + options) + p = subprocess.Popen(['./security-check.py',executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) + (stdout, stderr) = p.communicate() + return (p.returncode, stdout.rstrip()) + +class TestSecurityChecks(unittest.TestCase): + def test_ELF(self): + source = 'test1.c' + executable = 'test1' + cc = 'gcc' + write_testcode(source) + + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro']), + (1, executable+': failed PIE NX RELRO Canary')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fno-stack-protector','-Wl,-znorelro']), + (1, executable+': failed PIE RELRO Canary')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro']), + (1, executable+': failed PIE RELRO')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-znorelro','-pie','-fPIE']), + (1, executable+': failed RELRO')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack','-fstack-protector-all','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE']), + (0, '')) + + def test_PE(self): + source = 'test1.c' + executable = 'test1.exe' + cc = 'i686-w64-mingw32-gcc' + write_testcode(source) + + self.assertEqual(call_security_check(cc, source, executable, []), + (1, executable+': failed PIE NX')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat']), + (1, executable+': failed PIE')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase']), + (0, '')) + +if __name__ == '__main__': + unittest.main() + diff --git a/depend/zcash/contrib/devtools/update-rust-hashes.sh b/depend/zcash/contrib/devtools/update-rust-hashes.sh new file mode 100755 index 000000000..ad036bebf --- /dev/null +++ b/depend/zcash/contrib/devtools/update-rust-hashes.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +export LC_ALL=C + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +RUST_PACKAGE="$SCRIPT_DIR/../../depends/packages/native_rust.mk" + +RUST_VERSION=$( cat $RUST_PACKAGE | grep -oP "_version=\K.*" ) + +update_hash() { + url="https://static.rust-lang.org/dist/$1-$RUST_VERSION-$2.tar.gz" + echo "Fetching $url" + hash=$( curl $url | sha256sum | awk '{print $1}' ) + sed -i "/\$(package)_$3_$4=/c\\\$(package)_$3_$4=$hash" $RUST_PACKAGE +} + +update_rust_hash() { + update_hash rust $1 sha256_hash $2 +} + +update_stdlib_hash() { + update_hash rust-std $1 rust_std_sha256_hash $1 +} + +# For native targets +# update_rust_hash RUST_TARGET MAKEFILE_PACKAGE_IDENTIFIER +update_rust_hash aarch64-unknown-linux-gnu aarch64_linux +update_rust_hash x86_64-apple-darwin darwin +update_rust_hash x86_64-unknown-linux-gnu linux +update_rust_hash x86_64-unknown-freebsd freebsd + +# For cross-compilation targets +# update_stdlib_hash RUST_TARGET +update_stdlib_hash aarch64-unknown-linux-gnu +update_stdlib_hash x86_64-apple-darwin +update_stdlib_hash x86_64-pc-windows-gnu +update_stdlib_hash x86_64-unknown-freebsd diff --git a/depend/zcash/contrib/docker/.dockerignore b/depend/zcash/contrib/docker/.dockerignore new file mode 100644 index 000000000..4e5cdf953 --- /dev/null +++ b/depend/zcash/contrib/docker/.dockerignore @@ -0,0 +1,2 @@ +./zcash-data-dir/ +./zcash-params-dir/ diff --git a/depend/zcash/contrib/docker/.env.example b/depend/zcash/contrib/docker/.env.example new file mode 100644 index 000000000..52321b17e --- /dev/null +++ b/depend/zcash/contrib/docker/.env.example @@ -0,0 +1,12 @@ +ZCASHD_NETWORK=testnet +ZCASHD_LOGIPS=1 +ZCASHD_EXPERIMENTALFEATURES=1 +ZCASHD_GEN=0 +ZCASHD_RPCUSER=zcashrpc +ZCASHD_RPCPASSWORD=notsecure +ZCASHD_RPCBIND=0.0.0.0 +ZCASHD_ALLOWIP=0.0.0.0/0 +ZCASHD_TXINDEX=1 +ZCASHD_INSIGHTEXPLORER=1 +ZCASHD_ZMQPORT=9994 +ZCASHD_ZMQBIND=0.0.0.0 diff --git a/depend/zcash/contrib/docker/.gitignore b/depend/zcash/contrib/docker/.gitignore new file mode 100644 index 000000000..6c33f2d41 --- /dev/null +++ b/depend/zcash/contrib/docker/.gitignore @@ -0,0 +1,3 @@ +./zcash-data-dir/ +./zcash-params-dir/ +.env diff --git a/depend/zcash/contrib/docker/Dockerfile b/depend/zcash/contrib/docker/Dockerfile new file mode 100644 index 000000000..1062a87a0 --- /dev/null +++ b/depend/zcash/contrib/docker/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:11 + +RUN apt-get update \ + && apt-get install -y gnupg2 apt-transport-https curl + +ARG ZCASH_SIGNING_KEY_ID=6DEF3BAF272766C0 + +ARG ZCASH_VERSION= +# The empty string for ZCASH_VERSION will install the apt default version, +# which should be the latest stable release. To install a specific +# version, pass `--build-arg 'ZCASH_VERSION='` to `docker build`. + +ARG ZCASHD_USER=zcashd +ARG ZCASHD_UID=2001 + +RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys $ZCASH_SIGNING_KEY_ID \ + && echo "deb [arch=amd64] https://apt.z.cash/ bullseye main" > /etc/apt/sources.list.d/zcash.list \ + && apt-get update + +RUN if [ -z "$ZCASH_VERSION" ]; \ + then apt-get install -y zcash; \ + else apt-get install -y zcash=$ZCASH_VERSION; \ + fi; \ + zcashd --version + +RUN useradd --home-dir /srv/$ZCASHD_USER \ + --shell /bin/bash \ + --create-home \ + --uid $ZCASHD_UID\ + $ZCASHD_USER +USER $ZCASHD_USER +WORKDIR /srv/$ZCASHD_USER +RUN mkdir -p /srv/$ZCASHD_USER/.zcash/ \ + && touch /srv/$ZCASHD_USER/.zcash/zcash.conf + +ADD entrypoint.sh /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/depend/zcash/contrib/docker/README.md b/depend/zcash/contrib/docker/README.md new file mode 100644 index 000000000..69f5b7e9d --- /dev/null +++ b/depend/zcash/contrib/docker/README.md @@ -0,0 +1,87 @@ +# zcash Dockerfile + +This is an example Dockerfile to run the zcashd daemon in a containerized Debian base OS. The image pulls the apt package built by Electric Coin Company. + +The output of building this image should be accessible at https://hub.docker.com/r/electriccoinco/zcashd + +## Defaults + +The image will run as a non-root user, `zcashd` with uid `2001`. When mapping volumes from the host into the container, these permissions must be used, or rebuild the image with your custom values. + +## Run time configuration + +The goal is to follow the default zcashd startup behavior as closely as possible. + +At startup, the image will execute the [./entrypoint.sh](./entrypoint.sh) script. This script uses environmental variables to configure the command line parameters, do a little house cleaning, and start zcashd. + +### Available environment variables + +If defined, the value is assigned to the value of the corresponding flag. + +``` +ZCASHD_NETWORK +ZCASHD_LOGIPS +ZCASHD_EXPERIMENTALFEATURES +ZCASHD_GEN +ZCASHD_ZSHIELDCOINBASE +ZCASHD_RPCUSER +ZCASHD_RPCPASSWORD +ZCASHD_RPCBIND +ZCASHD_ALLOWIP +ZCASHD_TXINDEX +ZCASHD_INSIGHTEXPLORER +ZCASHD_ZMQPORT +ZCASHD_ZMQBIND +``` + +### Additional configuration + +Any provided command line parameters are passed from the entrypoint.sh script to zcashd. + +You can skip using environmental variables at all, and instead provide a fully configured `zcash.conf` file and map to `/srv/zcashd/.zcash/zcash.conf` at startup. + +## Examples + +### See the installed version + +This command will create a container, print the version information of the zcashd software installed and then exit and remove the container. + +Run +``` +docker run --rm electriccoinco/zcashd --version +``` + +Output +``` +Zcash Daemon version v2.1.0-1 + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + +Copyright (C) 2009-2019 The Bitcoin Core Developers +Copyright (C) 2015-2019 The Zcash Developers + +This is experimental software. + +Distributed under the MIT software license, see the accompanying file COPYING +or . +``` + +### Persist data to the host + +For this example, we'll create a place for zcashd to store the blockchain data, create a new container that uses that location, and run it in the background. + +``` +mkdir {./zcash-params-dir,./zcash-data-dir} +sudo chown -R 2001.2001 {./zcash-params-dir,./zcash-data-dir} +docker run -d --name my_zcashd \ + -v $(pwd)/zcash-data-dir:/srv/zcashd/.zcash \ + -v $(pwd)/zcash-params-dir:/srv/zcashd/.zcash-params \ + electriccoinco/zcashd +``` + +Follow the logs to see its activity. + +``` +docker logs -f my_zcashd +``` diff --git a/depend/zcash/contrib/docker/docker-compose.yml b/depend/zcash/contrib/docker/docker-compose.yml new file mode 100644 index 000000000..7d0bf5fee --- /dev/null +++ b/depend/zcash/contrib/docker/docker-compose.yml @@ -0,0 +1,11 @@ +--- +version: '3' + +services: + zcashd: + build: . + env_file: + - .env + volumes: + - ./zcash-params-dir:/srv/zcashd/.zcash-params + - ./zcash-data-dir:/srv/zcashd/.zcash diff --git a/depend/zcash/contrib/docker/entrypoint.sh b/depend/zcash/contrib/docker/entrypoint.sh new file mode 100755 index 000000000..adcbbf8fc --- /dev/null +++ b/depend/zcash/contrib/docker/entrypoint.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -eo pipefail + +if [[ ${1} == "--version" ]];then + zcashd --version + exit 0 +fi + +env | sort | grep ZCASHD || true +export ZCASHD_CMD='zcashd -printtoconsole' + +if [[ ! -n ${ZCASHD_NETWORK} ]];then + export ZCASHD_NETWORK=mainnet +fi + +case ${ZCASHD_NETWORK} in + testnet) + ZCASHD_CMD+=" -testnet -addnode=testnet.z.cash " + ;; + mainnet) + ZCASHD_CMD+=" -addnode=mainnet.z.cash " + ;; + *) + echo "Error, unknown network: ${ZCASHD_NETWORK}" + exit 1 + ;; +esac + +if [[ -n "${ZCASHD_SHOWMETRICS}" ]];then ZCASHD_CMD+=" -showmetrics=${ZCASHD_SHOWMETRICS}";fi +if [[ -n "${ZCASHD_LOGIPS}" ]];then ZCASHD_CMD+=" -logips=${ZCASHD_LOGIPS}";fi +if [[ -n "${ZCASHD_EXPERIMENTALFEATURES}" ]];then ZCASHD_CMD+=" -experimentalfeatures=${ZCASHD_EXPERIMENTALFEATURES}";fi +if [[ -n "${ZCASHD_GEN}" ]];then ZCASHD_CMD+=" -gen=${ZCASHD_GEN}";fi +if [[ -n "${ZCASHD_ZSHIELDCOINBASE}" ]];then ZCASHD_CMD+=" -zshieldcoinbase=${ZCASHD_ZSHIELDCOINBASE}";fi +if [[ -n "${ZCASHD_RPCUSER}" ]];then ZCASHD_CMD+=" -rpcuser=${ZCASHD_RPCUSER}";fi +if [[ -n "${ZCASHD_RPCPASSWORD}" ]];then ZCASHD_CMD+=" -rpcpassword=${ZCASHD_RPCPASSWORD}";fi +if [[ -n "${ZCASHD_RPCBIND}" ]];then ZCASHD_CMD+=" -rpcbind=${ZCASHD_RPCBIND}";fi +if [[ -n "${ZCASHD_RPCPORT}" ]];then ZCASHD_CMD+=" -rpcport=${ZCASHD_RPCPORT}";fi +if [[ -n "${ZCASHD_ALLOWIP}" ]];then ZCASHD_CMD+=" -rpcallowip=${ZCASHD_ALLOWIP}";fi +if [[ -n "${ZCASHD_TXINDEX}" ]];then ZCASHD_CMD+=" -txindex";fi +if [[ -n "${ZCASHD_INSIGHTEXPLORER}" ]];then ZCASHD_CMD+=" -insightexplorer";fi +if [[ -n "${ZCASHD_PROMETHEUSPORT}" ]];then ZCASHD_CMD+=" -prometheusport=${ZCASHD_PROMETHEUSPORT}";fi +if [[ -n "${ZCASHD_METRICSIP}" ]];then ZCASHD_CMD+=" -metricsallowip=${ZCASHD_METRICSIP}";fi +if [[ -n "${ZCASHD_ZMQPORT}" && -n "${ZCASHD_ZMQBIND}" ]];then + ZCASHD_CMD+=" -zmqpubhashblock=tcp://${ZCASHD_ZMQBIND}:${ZCASHD_ZMQPORT}" + ZCASHD_CMD+=" -zmqpubhashtx=tcp://${ZCASHD_ZMQBIND}:${ZCASHD_ZMQPORT}" + ZCASHD_CMD+=" -zmqpubrawblock=tcp://${ZCASHD_ZMQBIND}:${ZCASHD_ZMQPORT}" + ZCASHD_CMD+=" -zmqpubrawtx=tcp://${ZCASHD_ZMQBIND}:${ZCASHD_ZMQPORT}" + ZCASHD_CMD+=" -zmqpubhashblock=tcp://${ZCASHD_ZMQBIND}:${ZCASHD_ZMQPORT}" +fi + +zcash-fetch-params +touch .zcash/zcash.conf +echo "Starting: ${ZCASHD_CMD}" +eval exec "${ZCASHD_CMD}" "${@}" diff --git a/depend/zcash/contrib/gitian-descriptors/README.md b/depend/zcash/contrib/gitian-descriptors/README.md new file mode 100644 index 000000000..8ca2347e0 --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/README.md @@ -0,0 +1,65 @@ +### Gavin's notes on getting gitian builds up and running using KVM + +These instructions distilled from +[https://help.ubuntu.com/community/KVM/Installation](https://help.ubuntu.com/community/KVM/Installation). + +You need the right hardware: you need a 64-bit-capable CPU with hardware virtualization support (Intel VT-x or AMD-V). Not all modern CPUs support hardware virtualization. + +You probably need to enable hardware virtualization in your machine's BIOS. + +You need to be running a recent version of 64-bit-Ubuntu, and you need to install several prerequisites: + + sudo apt-get install ruby apache2 git apt-cacher-ng python-vm-builder qemu-kvm + +Sanity checks: + + sudo service apt-cacher-ng status # Should return apt-cacher-ng is running + ls -l /dev/kvm # Should show a /dev/kvm device + + +Once you've got the right hardware and software: + + git clone git://github.com/bitcoin/bitcoin.git + git clone git://github.com/devrandom/gitian-builder.git + mkdir gitian-builder/inputs + cd gitian-builder/inputs + + # Create base images + cd gitian-builder + bin/make-base-vm --suite trusty --arch amd64 + cd .. + + # Get inputs (see doc/release-process.md for exact inputs needed and where to get them) + ... + + # For further build instructions see doc/release-process.md + ... + +--------------------- + +`gitian-builder` now also supports building using LXC. See +[help.ubuntu.com](https://ubuntu.com/server/docs/containers-lxc) +for how to get LXC up and running under Ubuntu. + +If your main machine is a 64-bit Mac or PC with a few gigabytes of memory +and at least 10 gigabytes of free disk space, you can `gitian-build` using +LXC running inside a virtual machine. + +Here's a description of Gavin's setup on OSX 10.6: + +1. Download and install VirtualBox from [https://www.virtualbox.org/](https://www.virtualbox.org/) + +2. Download the 64-bit Ubuntu Desktop 12.04 LTS .iso CD image from + [https://ubuntu.com/](https://ubuntu.com) + +3. Run VirtualBox and create a new virtual machine, using the Ubuntu .iso (see the [VirtualBox documentation](https://www.virtualbox.org/wiki/Documentation) for details). Create it with at least 2 gigabytes of memory and a disk that is at least 20 gigabytes big. + +4. Inside the running Ubuntu desktop, install: + + sudo apt-get install debootstrap lxc ruby apache2 git apt-cacher-ng python-vm-builder + +5. Still inside Ubuntu, tell gitian-builder to use LXC, then follow the "Once you've got the right hardware and software" instructions above: + + export USE_LXC=1 + git clone git://github.com/bitcoin/bitcoin.git + ... etc diff --git a/depend/zcash/contrib/gitian-descriptors/gitian-linux.yml b/depend/zcash/contrib/gitian-descriptors/gitian-linux.yml new file mode 100644 index 000000000..9e03c1767 --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/gitian-linux.yml @@ -0,0 +1,141 @@ +--- +name: "zcash-5.0.0" +enable_cache: true +distro: "debian" +suites: +- "buster" +- "bullseye" +architectures: +- "amd64" +packages: +- "curl" +- "autoconf" +- "automake" +- "bsdmainutils" +- "binutils-gold" +- "ca-certificates" +- "faketime" +- "g++-multilib" +- "git-core" +- "libc6-dev" +- "libtinfo5" +- "libtool" +- "libxml2" +- "m4" +- "ncurses-dev" +- "pkg-config" +- "python" +- "unzip" +- "wget" +- "zlib1g-dev" +remotes: +- "url": "https://github.com/zcash/zcash.git" + "dir": "zcash" +files: [] +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-linux-gnu" + CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --enable-hardening --enable-werror" + MAKEOPTS="V=1" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="date ar ranlib nm strip objcopy" + HOST_CFLAGS="" + HOST_CXXFLAGS="" + HOST_LDFLAGS=-static-libstdc++ + + export QT_RCC_TEST=0 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + export PATH=${WRAP_DIR}:${PATH} + + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + + cd zcash + BASEPREFIX=`pwd`/depends + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + make dist + SOURCEDIST=`echo zcash-*.tar.gz` + DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$SOURCEDIST + find zcash* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + INSTALLPATH=`pwd`/installed/${DISTNAME} + mkdir -p ${INSTALLPATH} + tar --strip-components=1 -xf ../$SOURCEDIST + + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" + make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make install DESTDIR=${INSTALLPATH} + cd installed + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + rm -rf ${DISTNAME}/lib/pkgconfig + find ${DISTNAME}/bin -type f -executable -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; + # Commented out while we don't build any libraries + #find ${DISTNAME}/lib -type f -exec objcopy --only-keep-debug {} {}.dbg \; -exec strip -s {} \; -exec objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz + cd ../../ + rm -rf distsrc-${i} + done + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src + mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.tar.gz ${OUTDIR}/${DISTNAME}-linux64-debug.tar.gz + mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-linux64.tar.gz diff --git a/depend/zcash/contrib/gitian-descriptors/gitian-osx-signer.yml b/depend/zcash/contrib/gitian-descriptors/gitian-osx-signer.yml new file mode 100644 index 000000000..73a2f12f3 --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -0,0 +1,37 @@ +--- +name: "bitcoin-dmg-signer" +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "libc6:i386" +- "faketime" +remotes: +- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" + "dir": "signature" +files: +- "bitcoin-osx-unsigned.tar.gz" +script: | + WRAP_DIR=$HOME/wrapped + mkdir -p ${WRAP_DIR} + export PATH=`pwd`:$PATH + FAKETIME_PROGS="dmg genisoimage" + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + UNSIGNED=bitcoin-osx-unsigned.tar.gz + SIGNED=bitcoin-osx-signed.dmg + + tar -xf ${UNSIGNED} + ./detached-sig-apply.sh ${UNSIGNED} signature/osx + ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/depend/zcash/contrib/gitian-descriptors/gitian-osx.yml b/depend/zcash/contrib/gitian-descriptors/gitian-osx.yml new file mode 100644 index 000000000..65533d060 --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/gitian-osx.yml @@ -0,0 +1,146 @@ +--- +name: "bitcoin-osx-0.11" +enable_cache: true +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "g++" +- "git-core" +- "pkg-config" +- "autoconf" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "cmake" +- "libcap-dev" +- "libz-dev" +- "libbz2-dev" +- "ca-certificates" +- "python" +remotes: +- "url": "https://github.com/bitcoin/bitcoin.git" + "dir": "bitcoin" +files: +- "Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz" +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-apple-darwin18" + CONFIGFLAGS="--enable-reduce-exports --disable-bench GENISOIMAGE=$WRAP_DIR/genisoimage" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="ar ranlib date dmg genisoimage" + + export QT_RCC_TEST=1 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + export ZERO_AR_DATE=1 + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + export PATH=${WRAP_DIR}:${PATH} + + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + + cd bitcoin + BASEPREFIX=`pwd`/depends + + mkdir -p ${BASEPREFIX}/SDKs + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz + + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + make dist + SOURCEDIST=`echo bitcoin-*.tar.gz` + DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + INSTALLPATH=`pwd`/installed/${DISTNAME} + mkdir -p ${INSTALLPATH} + tar --strip-components=1 -xf ../$SOURCEDIST + + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + make ${MAKEOPTS} + make install-strip DESTDIR=${INSTALLPATH} + + make deploydir + mkdir -p unsigned-app-${i} + cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} + cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate + cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff + mv dist unsigned-app-${i} + pushd unsigned-app-${i} + find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz + popd + + make deploy + ${WRAP_DIR}/dmg dmg Bitcoin-Core.dmg ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg + + cd installed + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + rm -rf ${DISTNAME}/lib/pkgconfig + find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz + cd ../../ + done + mkdir -p $OUTDIR/src + mv $SOURCEDIST $OUTDIR/src + mv ${OUTDIR}/${DISTNAME}-x86_64-*.tar.gz ${OUTDIR}/${DISTNAME}-osx64.tar.gz diff --git a/depend/zcash/contrib/gitian-descriptors/gitian-win-signer.yml b/depend/zcash/contrib/gitian-descriptors/gitian-win-signer.yml new file mode 100644 index 000000000..6b53b89b6 --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/gitian-win-signer.yml @@ -0,0 +1,38 @@ +--- +name: "bitcoin-win-signer" +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "libssl-dev" +- "autoconf" +remotes: +- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git" + "dir": "signature" +files: +- "osslsigncode-1.7.1.tar.gz" +- "osslsigncode-Backports-to-1.7.1.patch" +- "bitcoin-win-unsigned.tar.gz" +script: | + BUILD_DIR=`pwd` + SIGDIR=${BUILD_DIR}/signature/win + UNSIGNED_DIR=${BUILD_DIR}/unsigned + + echo "f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 osslsigncode-1.7.1.tar.gz" | sha256sum -c + echo "a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 osslsigncode-Backports-to-1.7.1.patch" | sha256sum -c + + mkdir -p ${UNSIGNED_DIR} + tar -C ${UNSIGNED_DIR} -xf bitcoin-win-unsigned.tar.gz + + tar xf osslsigncode-1.7.1.tar.gz + cd osslsigncode-1.7.1 + patch -p1 < ${BUILD_DIR}/osslsigncode-Backports-to-1.7.1.patch + + ./configure --without-gsf --without-curl --disable-dependency-tracking + make + find ${UNSIGNED_DIR} -name "*-unsigned.exe" | while read i; do + INFILE="`basename "${i}"`" + OUTFILE="`echo "${INFILE}" | sed s/-unsigned//`" + ./osslsigncode attach-signature -in "${i}" -out "${OUTDIR}/${OUTFILE}" -sigin "${SIGDIR}/${INFILE}.pem" + done diff --git a/depend/zcash/contrib/gitian-descriptors/gitian-win.yml b/depend/zcash/contrib/gitian-descriptors/gitian-win.yml new file mode 100644 index 000000000..cab6187fa --- /dev/null +++ b/depend/zcash/contrib/gitian-descriptors/gitian-win.yml @@ -0,0 +1,166 @@ +--- +name: "bitcoin-win-0.11" +enable_cache: true +suites: +- "trusty" +architectures: +- "amd64" +packages: +- "g++" +- "git-core" +- "pkg-config" +- "autoconf" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "mingw-w64" +- "g++-mingw-w64" +- "nsis" +- "zip" +- "ca-certificates" +- "python" +remotes: +- "url": "https://github.com/bitcoin/bitcoin.git" + "dir": "bitcoin" +files: [] +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" + CONFIGFLAGS="--enable-reduce-exports --disable-bench" + FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip objcopy" + FAKETIME_PROGS="date makensis zip" + HOST_CFLAGS="-O2 -g" + HOST_CXXFLAGS="-O2 -g" + + export QT_RCC_TEST=1 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + function create_global_faketime_wrappers { + for prog in ${FAKETIME_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + } + + function create_per-host_faketime_wrappers { + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + function create_per-host_linker_wrapper { + # This is only needed for trusty, as the mingw linker leaks a few bytes of + # heap, causing non-determinism. See discussion in https://github.com/bitcoin/bitcoin/pull/6900 + for i in $HOSTS; do + mkdir -p ${WRAP_DIR}/${i} + for prog in collect2; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}/${prog} + REAL=$(${i}-gcc -print-prog-name=${prog}) + echo "export MALLOC_PERTURB_=255" >> ${WRAP_DIR}/${i}/${prog} + echo "${REAL} \$@" >> $WRAP_DIR/${i}/${prog} + chmod +x ${WRAP_DIR}/${i}/${prog} + done + for prog in gcc g++; do + echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"$1\"" >> ${WRAP_DIR}/${i}-${prog} + echo "export COMPILER_PATH=${WRAP_DIR}/${i}" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + } + + export PATH=${WRAP_DIR}:${PATH} + + # Faketime for depends so intermediate results are comparable + create_global_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_faketime_wrappers "2000-01-01 12:00:00" + create_per-host_linker_wrapper "2000-01-01 12:00:00" + + cd bitcoin + BASEPREFIX=`pwd`/depends + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Faketime for binaries + create_global_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_faketime_wrappers "${REFERENCE_DATETIME}" + create_per-host_linker_wrapper "${REFERENCE_DATETIME}" + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + CONFIG_SITE=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`/share/config.site ./configure --prefix=/ + make dist + SOURCEDIST=`echo bitcoin-*.tar.gz` + DISTNAME=`echo ${SOURCEDIST} | sed 's/.tar.*//'` + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$SOURCEDIST + find bitcoin-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ../$SOURCEDIST + mkdir -p $OUTDIR/src + cp ../$SOURCEDIST $OUTDIR/src + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + INSTALLPATH=`pwd`/installed/${DISTNAME} + mkdir -p ${INSTALLPATH} + tar --strip-components=1 -xf ../$SOURCEDIST + + CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" + make ${MAKEOPTS} + make ${MAKEOPTS} -C src check-security + make deploy + make install DESTDIR=${INSTALLPATH} + cp -f bitcoin-*setup*.exe $OUTDIR/ + cd installed + mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + rm -rf ${DISTNAME}/lib/pkgconfig + find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; + # Commented out while we don't build any libraries + #find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; + find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip + find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip + cd ../../ + rm -rf distsrc-${i} + done + cd $OUTDIR + rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe + find . -name "*-setup-unsigned.exe" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz + mv ${OUTDIR}/${DISTNAME}-x86_64-*-debug.zip ${OUTDIR}/${DISTNAME}-win64-debug.zip + mv ${OUTDIR}/${DISTNAME}-i686-*-debug.zip ${OUTDIR}/${DISTNAME}-win32-debug.zip + mv ${OUTDIR}/${DISTNAME}-x86_64-*.zip ${OUTDIR}/${DISTNAME}-win64.zip + mv ${OUTDIR}/${DISTNAME}-i686-*.zip ${OUTDIR}/${DISTNAME}-win32.zip diff --git a/depend/zcash/contrib/gitian-downloader/daira.asc b/depend/zcash/contrib/gitian-downloader/daira.asc new file mode 100644 index 000000000..e60a2bbcb --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/daira.asc @@ -0,0 +1,70 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.5 +Comment: Hostname: pgp.mit.edu + +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 +eCJPlVdlz6Oj1tV2kw== +=E8LJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/gitian-downloader/jack.asc b/depend/zcash/contrib/gitian-downloader/jack.asc new file mode 100644 index 000000000..db9967233 --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/jack.asc @@ -0,0 +1,449 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +HifqTn/z+qdV2A== +=phy7 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/gitian-downloader/kevin.asc b/depend/zcash/contrib/gitian-downloader/kevin.asc new file mode 100644 index 000000000..13a39ee7f --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/kevin.asc @@ -0,0 +1,171 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=qSqw +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/gitian-downloader/nathan.asc b/depend/zcash/contrib/gitian-downloader/nathan.asc new file mode 100644 index 000000000..2a2be1ee9 --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/nathan.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +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 +JfmuGLm2Czs= +=kUB4 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/gitian-downloader/sean.asc b/depend/zcash/contrib/gitian-downloader/sean.asc new file mode 100644 index 000000000..9b710ff5f --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/sean.asc @@ -0,0 +1,51 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQINBFN/6CcBEADJ7y3ejKFq5FDvK+IlSgXpZQicX4DBKjWAVKI57iIVJ2iRpUSn +q/RnF+pW5WuKYV0uu+JueyaPo2tjYTqx8Eah3LOMlC9Kui4bmHsQHmLecSWZqrUX +jrilfSHHMLOzdp3ufZ6BfgbrMIQEycQygjDXY4FNfkHKkm5iyW0NznhYZr2Iv6wC +h4I4lA4hSYTcU+BLoI3ENNX4OdeBN5sXOJsyYGXOzGskYDa1Pk1iZbeba2Eg7U3b +6ItGymJjgLRbDiZQzBhAH7yfR2VkI5MycNtnuLk4M5j53Aangb8bkzv1/z0KwQYE +N9xXcr2GceJ1ShbdqRiVwtOeRupBPOtL2J0o/bJuigAG0UcugcYgj4XbZ0JU7yPT +fuXqdSBdodTM2mwhBI1gTBp7HnmIUlX3hHNjRahRxYVJi7oT2hALiZOyHZdf1ylg +Cz+TKTl4kTg+P8dHW/PrPlPbbcQlHuEfbINzvpyS9nndxyQM7P8cuUwqvLzU6xhB +6DR/XLbrY3Ho/sYyKyzcAufh6x+7/xfggJ1oyO3qJtJwa68sccj/TcShF6TlgEPk +9LOKdWIHv1xI0CpbNJpC8LmTp4D3P4WSkXDit4/K5MkYT+c+C7RkbHnVC2EMaDfI +ZphwMZ5QadDxA6lRMREAfBgRIMUKOAPEVtSEgZalxwFfoThS+8vCV3zUqwARAQAB +tCFTZWFuIEJvd2UgPGV3aWxsYmVmdWxsQGdtYWlsLmNvbT6JAjgEEwECACIFAlN/ +6CcCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEJVoQlfY+LAxit0P+wRK +s9Btsu6/rfS34CoOj2xwfNqGhzjPAFEWvXFZ5Q45ydtofOQ6fUm1Rw63Qb7RfEhl +Te0AiyPTxjCFh6VVE+DLPArk9LwgeinihUb9hgt8LCjIacH0Y9wAqHpmveeyd4aS +ZiQXToNS5KOZ40mp2BObuGmFr+X7kqW/YTIpptbUiUB9MmeDE+pxZ6fM+zK0RNmf +x6T5gs/dh/o3l8Xh772YT6DRzg87nemt66jSs8yi+wJyYDP/YMlOczTyV0pciYPL +mavvuoB+ZzySVdig/7vbddqvJCSgGVb1WDZZWp+EBpZu50+zjpHnfz75//pEkhwo +nRIF6iNqZg5Ot+UKsneLir+tVPUkf9jy7gSXZr+78m0WQII+RZtU9kXDIrK7dGMy +QCs5lCtYDpbZVy2IwRUwi4C7JuC20wZ2NByKUbH6OogzOng4os/4HIFdPMixNnFd +J6fGhoB7t8zWz3w+/iuPy2bJdRblUC2JKKmkqga6ZNLmHs5RJvdv5HmO9JFpJuPM +he4Fn3txK3a88XV+SSZmv46rsoWHlYB65GhMc45soLpWTsDlJFE6V++CtoxTVFLk +eF1TrrVsn/edX4zht5l9VIa2V4udSf6QrhnRUK+oWPdSNkmEV5OjfYbFaVIDvk3X +P1c8aj+SNnrEQcpLP3TlPOjQQ2KIAPZbxjP8pkiVuQINBFN/6CcBEAC4K57I/Pi6 +DzW6UMw1OHkui8oPjxdQOxjLP8ymM0e4T52iXyPklArLyFfoafYV28of0Y2xy5Z0 +sE+BGjHiDN7xGDz9RhtpOQ90NzYGnfdZx+3mIhDm/cvbynZ8JTzD7jNVCzAI/tqA +kVxTyq40/QP+BetHvfA7MjcuyuzSRDSqKiISy5cCPTmmp4mH56MrSRoL6QNupEHl +M6bZ2CypOyVUv/rYSxFmveZGWwBoInFjTJaYaWgQoDqeueVvQFToUq/HHMvCvv9V +UXytHq2xgXEyLsJhnbKBosTHsM6Fbo6fTnUIvaBxFnNnK9UUYVdtNJbve8vvhL/b +zOjjA3uthTWFNYswAG3ugtOwlMcljYgGSW7Ile/AWgyLk8I0uJfJEerROZfphU93 +PaikOFwC31v+AgOCV3kVFTnxiamwVrwyD63Ol7JF16vpIZI15HBbIp9WbE9Zhnai +GdmtDjkQa7FyJmzCdFnCm83vlV8WLCdxFTWKc/eci9oyrhymx7sTAOdBbldXmMLj +4lfEXIfLemYeD17oBYuUvWXXnMdGLXxLzPLxKbTJhndA5wl4iGfPF1sCPU5cDw2N +b7DMJVLHzYTK4mLBPQLF84TeN4kWdd7bK18jE9XK2efcXR3f+J7X/KnX4R/4gLLs +CVOtDYWi6b8xFGW/fpqcC7I25VqWGFe97wARAQABiQIfBBgBAgAJBQJTf+gnAhsM +AAoJEJVoQlfY+LAx/0oP/RTjO7YvE1rDePbrNynQhc5ImyME4yJrhvOMj1vqvn0f +Z+z21YNOUs4rC1zTRQO5Fypg7ILWtU1leZ0oV+z2cA5IJa0WMu45mXfgIS7sXkU+ +/BC3tP1kj6We+IVcmKbNKNqtSszb/Ls5mw6/ADNRxcJ12btMKiGFC7ahEHjGMBX/ +OQe5uFoPPNYtL3fEuroPk3/rGSRG9nECa37UA5PLmvq9xuRLf6cbEQ7gnu1aZ1Kx +9li5FU16O3xRUBGcJlovtzZfnm/fyc1jt8Su7v3Vuot9Bty3O8uLzfKqqV4DrkrH +dLKFh0NLCnApdRmGzWyFFTMFW1otMCOqLsfyjzkKVuouNl9HqOEmvG9PvW1b04DP +FgdWdpclvhFc/32q+gWi6s6M8oz3dTerydET/1QU/ADkpidDvq7BqHWdsuFTHBF0 +Pie3AfkQv7/1Tb44f0GjFAOLk5GjufHCwLy1ihACFQ/fXfIqDA8fgdu34vhq3Wkr +VEKANOT8lFuhr8TbKEiwsNrOTorQj0nuybIXNNBZehb+XiMgd8265utw4g50hXoy +HbqIb2eL44k7TDK0w6g/1SATegplFcqi+USXNTKDGV7aTj1PUePKVMdUG3aDoP9t +e6RMNnbUmII/VPfFfw+LqX7qB7+OYLEPnZ5zG3bxQRdsYTqQKBpYQqDGpDLhH3/J +=0DUx +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/gitian-downloader/simon.asc b/depend/zcash/contrib/gitian-downloader/simon.asc new file mode 100644 index 000000000..3cbf0f57c --- /dev/null +++ b/depend/zcash/contrib/gitian-downloader/simon.asc @@ -0,0 +1,47 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.5 +Comment: Hostname: pgp.mit.edu + +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 +=nZf9 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/depend/zcash/contrib/linearize/README.md b/depend/zcash/contrib/linearize/README.md new file mode 100644 index 000000000..06f278f3b --- /dev/null +++ b/depend/zcash/contrib/linearize/README.md @@ -0,0 +1,33 @@ +# Linearize +Construct a linear, no-fork, best version of the blockchain. + +## Step 1: Download hash list + + $ ./linearize-hashes.py linearize.cfg > hashlist.txt + +Required configuration file settings for linearize-hashes: +* RPC: rpcuser, rpcpassword + +Optional config file setting for linearize-hashes: +* RPC: host, port +* Block chain: min_height, max_height + +## Step 2: Copy local block data + + $ ./linearize-data.py linearize.cfg + +Required configuration file settings: +* "input": bitcoind blocks/ directory containing blkNNNNN.dat +* "hashlist": text file containing list of block hashes, linearized-hashes.py +output. +* "output_file": bootstrap.dat + or +* "output": output directory for linearized blocks/blkNNNNN.dat output + +Optional config file setting for linearize-data: +* "netmagic": network magic number +* "max_out_sz": maximum output file size (default `1000*1000*1000`) +* "split_timestamp": Split files when a new month is first seen, in addition to +reaching a maximum file size. +* "file_timestamp": Set each file's last-modified time to that of the +most recent block in that file. diff --git a/depend/zcash/contrib/linearize/example-linearize.cfg b/depend/zcash/contrib/linearize/example-linearize.cfg new file mode 100644 index 000000000..4c5596deb --- /dev/null +++ b/depend/zcash/contrib/linearize/example-linearize.cfg @@ -0,0 +1,29 @@ + +# bitcoind RPC settings (linearize-hashes) +rpcuser=someuser +rpcpassword=somepassword +host=127.0.0.1 +port=8232 +#port=18232 + +# bootstrap.dat hashlist settings (linearize-hashes) +max_height=313000 + +# bootstrap.dat input/output settings (linearize-data) + +# mainnet +netmagic=f9beb4d9 +genesis=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f +input=/home/example/.bitcoin/blocks + +# testnet +#netmagic=0b110907 +#genesis=000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 +#input=/home/example/.bitcoin/testnet3/blocks + +output_file=/home/example/Downloads/bootstrap.dat +hashlist=hashlist.txt +split_year=1 + +# Maxmimum size in bytes of out-of-order blocks cache in memory +out_of_order_cache_sz = 100000000 diff --git a/depend/zcash/contrib/linearize/linearize-data.py b/depend/zcash/contrib/linearize/linearize-data.py new file mode 100755 index 000000000..bd2fd3b5d --- /dev/null +++ b/depend/zcash/contrib/linearize/linearize-data.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python +# +# linearize-data.py: Construct a linear, no-fork version of the chain. +# +# Copyright (c) 2013-2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# + +from __future__ import print_function, division +import json +import struct +import re +import os +import os.path +import base64 +import httplib +import sys +import hashlib +import datetime +import time +from collections import namedtuple + +settings = {} + +def uint32(x): + return x & 0xffffffffL + +def bytereverse(x): + return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | + (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) + +def bufreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + word = struct.unpack('@I', in_buf[i:i+4])[0] + out_words.append(struct.pack('@I', bytereverse(word))) + return ''.join(out_words) + +def wordreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + out_words.append(in_buf[i:i+4]) + out_words.reverse() + return ''.join(out_words) + +def calc_hdr_hash(blk_hdr): + hash1 = hashlib.sha256() + hash1.update(blk_hdr) + hash1_o = hash1.digest() + + hash2 = hashlib.sha256() + hash2.update(hash1_o) + hash2_o = hash2.digest() + + return hash2_o + +def calc_hash_str(blk_hdr): + hash = calc_hdr_hash(blk_hdr) + hash = bufreverse(hash) + hash = wordreverse(hash) + hash_str = hash.encode('hex') + return hash_str + +def get_blk_dt(blk_hdr): + members = struct.unpack(" self.maxOutSz): + self.outF.close() + if self.setFileTime: + os.utime(outFname, (int(time.time()), highTS)) + self.outF = None + self.outFname = None + self.outFn = self.outFn + 1 + self.outsz = 0 + + (blkDate, blkTS) = get_blk_dt(blk_hdr) + if self.timestampSplit and (blkDate > self.lastDate): + print("New month " + blkDate.strftime("%Y-%m") + " @ " + hash_str) + lastDate = blkDate + if outF: + outF.close() + if setFileTime: + os.utime(outFname, (int(time.time()), highTS)) + self.outF = None + self.outFname = None + self.outFn = self.outFn + 1 + self.outsz = 0 + + if not self.outF: + if self.fileOutput: + outFname = self.settings['output_file'] + else: + outFname = os.path.join(self.settings['output'], "blk%05d.dat" % self.outFn) + print("Output file " + outFname) + self.outF = open(outFname, "wb") + + self.outF.write(inhdr) + self.outF.write(blk_hdr) + self.outF.write(rawblock) + self.outsz = self.outsz + len(inhdr) + len(blk_hdr) + len(rawblock) + + self.blkCountOut = self.blkCountOut + 1 + if blkTS > self.highTS: + self.highTS = blkTS + + if (self.blkCountOut % 1000) == 0: + print('%i blocks scanned, %i blocks written (of %i, %.1f%% complete)' % + (self.blkCountIn, self.blkCountOut, len(self.blkindex), 100.0 * self.blkCountOut / len(self.blkindex))) + + def inFileName(self, fn): + return os.path.join(self.settings['input'], "blk%05d.dat" % fn) + + def fetchBlock(self, extent): + '''Fetch block contents from disk given extents''' + with open(self.inFileName(extent.fn), "rb") as f: + f.seek(extent.offset) + return f.read(extent.size) + + def copyOneBlock(self): + '''Find the next block to be written in the input, and copy it to the output.''' + extent = self.blockExtents.pop(self.blkCountOut) + if self.blkCountOut in self.outOfOrderData: + # If the data is cached, use it from memory and remove from the cache + rawblock = self.outOfOrderData.pop(self.blkCountOut) + self.outOfOrderSize -= len(rawblock) + else: # Otherwise look up data on disk + rawblock = self.fetchBlock(extent) + + self.writeBlock(extent.inhdr, extent.blkhdr, rawblock) + + def run(self): + while self.blkCountOut < len(self.blkindex): + if not self.inF: + fname = self.inFileName(self.inFn) + print("Input file " + fname) + try: + self.inF = open(fname, "rb") + except IOError: + print("Premature end of block data") + return + + inhdr = self.inF.read(8) + if (not inhdr or (inhdr[0] == "\0")): + self.inF.close() + self.inF = None + self.inFn = self.inFn + 1 + continue + + inMagic = inhdr[:4] + if (inMagic != self.settings['netmagic']): + print("Invalid magic: " + inMagic.encode('hex')) + return + inLenLE = inhdr[4:] + su = struct.unpack(" corresponding to /root/bazdir + foo/bar/qux -> corresponding to /root/bazdir/qux + + """ + def change_tarinfo_base(tarinfo): + if tarinfo.name and tarinfo.name.startswith("./"): + tarinfo.name = str(pathlib.Path(alt_base_dir, tarinfo.name)) + if tarinfo.linkname and tarinfo.linkname.startswith("./"): + tarinfo.linkname = str(pathlib.Path(alt_base_dir, tarinfo.linkname)) + return tarinfo + with cd(dir_to_add): + tarfp.add(".", recursive=True, filter=change_tarinfo_base) + + print("Creating output .tar.gz file...") + with out_sdktgz_path.open("wb") as fp: + with gzip.GzipFile(fileobj=fp, compresslevel=9, mtime=0) as gzf: + with tarfile.open(mode="w", fileobj=gzf) as tarfp: + print("Adding MacOSX SDK {} files...".format(sdk_version)) + tarfp_add_with_base_change(tarfp, sdk_dir, out_name) + print("Adding libc++ headers...") + tarfp_add_with_base_change(tarfp, xcode_libcxx_dir, "{}/usr/include/c++/v1".format(out_name)) + print("Done! Find the resulting gzipped tarball at:") + print(out_sdktgz_path.resolve()) + +if __name__ == '__main__': + run() diff --git a/depend/zcash/contrib/metrics/prometheus.yaml b/depend/zcash/contrib/metrics/prometheus.yaml new file mode 100644 index 000000000..77d08e5b4 --- /dev/null +++ b/depend/zcash/contrib/metrics/prometheus.yaml @@ -0,0 +1,6 @@ +scrape_configs: + - job_name: 'zcashd' + scrape_interval: 500ms + metrics_path: '/' + static_configs: + - targets: ['127.0.0.1:9969'] diff --git a/depend/zcash/contrib/qos/README.md b/depend/zcash/contrib/qos/README.md new file mode 100644 index 000000000..c8cbc0264 --- /dev/null +++ b/depend/zcash/contrib/qos/README.md @@ -0,0 +1,5 @@ +### Qos ### + +This is a Linux bash script that will set up tc to limit the outgoing bandwidth for connections to the Bitcoin network. It limits outbound TCP traffic with a source or destination port of 8233, but not if the destination IP is within a LAN (defined as 192.168.x.x). + +This means one can have an always-on bitcoind instance running, and another local bitcoind/bitcoin-qt instance which connects to this node and receives blocks from it. diff --git a/depend/zcash/contrib/qos/tc.sh b/depend/zcash/contrib/qos/tc.sh new file mode 100644 index 000000000..2376013b5 --- /dev/null +++ b/depend/zcash/contrib/qos/tc.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +export LC_ALL=C +#network interface on which to limit traffic +IF="eth0" +#limit of the network interface in question +LINKCEIL="1gbit" +#limit outbound Bitcoin protocol traffic to this rate +LIMIT="160kbit" +#defines the address space for which you wish to disable rate limiting +LOCALNET="192.168.0.0/16" + +#delete existing rules +tc qdisc del dev ${IF} root + +#add root class +tc qdisc add dev ${IF} root handle 1: htb default 10 + +#add parent class +tc class add dev ${IF} parent 1: classid 1:1 htb rate ${LINKCEIL} ceil ${LINKCEIL} + +#add our two classes. one unlimited, another limited +tc class add dev ${IF} parent 1:1 classid 1:10 htb rate ${LINKCEIL} ceil ${LINKCEIL} prio 0 +tc class add dev ${IF} parent 1:1 classid 1:11 htb rate ${LIMIT} ceil ${LIMIT} prio 1 + +#add handles to our classes so packets marked with go into the class with "... handle fw ..." +tc filter add dev ${IF} parent 1: protocol ip prio 1 handle 1 fw classid 1:10 +tc filter add dev ${IF} parent 1: protocol ip prio 2 handle 2 fw classid 1:11 + +#delete any existing rules +#disable for now +#ret=0 +#while [ $ret -eq 0 ]; do +# iptables -t mangle -D OUTPUT 1 +# ret=$? +#done + +#limit outgoing traffic to and from port 8233. but not when dealing with a host on the local network +# (defined by $LOCALNET) +# --set-mark marks packages matching these criteria with the number "2" +# these packages are filtered by the tc filter with "handle 2" +# this filter sends the packages into the 1:11 class, and this class is limited to ${LIMIT} +iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 8233 ! -d ${LOCALNET} -j MARK --set-mark 0x2 +iptables -t mangle -A OUTPUT -p tcp -m tcp --sport 8233 ! -d ${LOCALNET} -j MARK --set-mark 0x2 diff --git a/depend/zcash/contrib/seeds/README.md b/depend/zcash/contrib/seeds/README.md new file mode 100644 index 000000000..0a9d59d88 --- /dev/null +++ b/depend/zcash/contrib/seeds/README.md @@ -0,0 +1,4 @@ +### Seeds ### + +Utility to generate the seeds.txt list that is compiled into the client +(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)). \ No newline at end of file diff --git a/depend/zcash/contrib/seeds/generate-seeds.py b/depend/zcash/contrib/seeds/generate-seeds.py new file mode 100755 index 000000000..5c9bd5475 --- /dev/null +++ b/depend/zcash/contrib/seeds/generate-seeds.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# Copyright (c) 2014 Wladimir J. van der Laan +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +''' +Script to generate list of seed nodes for chainparams.cpp. + +This script expects two text files in the directory that is passed as an +argument: + + nodes_main.txt + nodes_test.txt + +These files must consist of lines in the format + + + : + [] + []: + .onion + 0xDDBBCCAA (IPv4 little-endian old pnSeeds format) + +The output will be two data structures with the peers in binary format: + + static SeedSpec6 pnSeed6_main[]={ + ... + } + static SeedSpec6 pnSeed6_test[]={ + ... + } + +These should be pasted into `src/chainparamsseeds.h`. +''' +from __future__ import print_function, division +from base64 import b32decode +from binascii import a2b_hex +import sys, os +import re + +# ipv4 in ipv6 prefix +pchIPv4 = bytearray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff]) +# tor-specific ipv6 prefix +pchOnionCat = bytearray([0xFD,0x87,0xD8,0x7E,0xEB,0x43]) + +def name_to_ipv6(addr): + if len(addr)>6 and addr.endswith('.onion'): + vchAddr = b32decode(addr[0:-6], True) + if len(vchAddr) != 16-len(pchOnionCat): + raise ValueError('Invalid onion %s' % s) + return pchOnionCat + vchAddr + elif '.' in addr: # IPv4 + return pchIPv4 + bytearray((int(x) for x in addr.split('.'))) + elif ':' in addr: # IPv6 + sub = [[], []] # prefix, suffix + x = 0 + addr = addr.split(':') + for i,comp in enumerate(addr): + if comp == '': + if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end + continue + x += 1 # :: skips to suffix + assert(x < 2) + else: # two bytes per component + val = int(comp, 16) + sub[x].append(val >> 8) + sub[x].append(val & 0xff) + nullbytes = 16 - len(sub[0]) - len(sub[1]) + assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0)) + return bytearray(sub[0] + ([0] * nullbytes) + sub[1]) + elif addr.startswith('0x'): # IPv4-in-little-endian + return pchIPv4 + bytearray(reversed(a2b_hex(addr[2:]))) + else: + raise ValueError('Could not parse address %s' % addr) + +def parse_spec(s, defaultport): + match = re.match('\[([0-9a-fA-F:]+)\](?::([0-9]+))?$', s) + if match: # ipv6 + host = match.group(1) + port = match.group(2) + elif s.count(':') > 1: # ipv6, no port + host = s + port = '' + else: + (host,_,port) = s.partition(':') + + if not port: + port = defaultport + else: + port = int(port) + + host = name_to_ipv6(host) + + return (host,port) + +def process_nodes(g, f, structname, defaultport): + g.write('static SeedSpec6 %s[] = {\n' % structname) + first = True + for line in f: + comment = line.find('#') + if comment != -1: + line = line[0:comment] + line = line.strip() + if not line: + continue + if not first: + g.write(',\n') + first = False + + (host,port) = parse_spec(line, defaultport) + hoststr = ','.join(('0x%02x' % b) for b in host) + g.write(' {{%s}, %i}' % (hoststr, port)) + g.write('\n};\n') + +def main(): + if len(sys.argv)<2: + print(('Usage: %s ' % sys.argv[0]), file=sys.stderr) + exit(1) + g = sys.stdout + indir = sys.argv[1] + g.write('#ifndef BITCOIN_CHAINPARAMSSEEDS_H\n') + g.write('#define BITCOIN_CHAINPARAMSSEEDS_H\n') + g.write('/**\n') + g.write(' * List of fixed seed nodes for the bitcoin network\n') + g.write(' * AUTOGENERATED by contrib/seeds/generate-seeds.py\n') + g.write(' *\n') + g.write(' * Each line contains a 16-byte IPv6 address and a port.\n') + g.write(' * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly.\n') + g.write(' */\n') + with open(os.path.join(indir,'nodes_main.txt'),'r', encoding="utf8") as f: + process_nodes(g, f, 'pnSeed6_main', 8233) + g.write('\n') + with open(os.path.join(indir,'nodes_test.txt'),'r', encoding="utf8") as f: + process_nodes(g, f, 'pnSeed6_test', 18233) + g.write('#endif // BITCOIN_CHAINPARAMSSEEDS_H\n') + +if __name__ == '__main__': + main() + diff --git a/depend/zcash/contrib/seeds/makeseeds.py b/depend/zcash/contrib/seeds/makeseeds.py new file mode 100755 index 000000000..041f83e2b --- /dev/null +++ b/depend/zcash/contrib/seeds/makeseeds.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Generate seeds.txt from Pieter's DNS seeder +# + +NSEEDS=512 + +MAX_SEEDS_PER_ASN=2 + +MIN_BLOCKS = 337600 + +# These are hosts that have been observed to be behaving strangely (e.g. +# aggressively connecting to every node). +SUSPICIOUS_HOSTS = set([ + "130.211.129.106", "178.63.107.226", + "83.81.130.26", "88.198.17.7", "148.251.238.178", "176.9.46.6", + "54.173.72.127", "54.174.10.182", "54.183.64.54", "54.194.231.211", + "54.66.214.167", "54.66.220.137", "54.67.33.14", "54.77.251.214", + "54.94.195.96", "54.94.200.247" +]) + +import re +import sys +import dns.resolver +import collections + +PATTERN_IPV4 = re.compile(r"^((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})):(\d+)$") +PATTERN_IPV6 = re.compile(r"^\[([0-9a-z:]+)\]:(\d+)$") +PATTERN_ONION = re.compile(r"^([abcdefghijklmnopqrstuvwxyz234567]{16}\.onion):(\d+)$") +PATTERN_AGENT = re.compile(r"^(\/MagicBean:([0-9a-z-.]+)\/)$") + +def parseline(line): + sline = line.split() + if len(sline) < 11: + return None + m = PATTERN_IPV4.match(sline[0]) + sortkey = None + ip = None + if m is None: + m = PATTERN_IPV6.match(sline[0]) + if m is None: + m = PATTERN_ONION.match(sline[0]) + if m is None: + return None + else: + net = 'onion' + ipstr = sortkey = m.group(1) + port = int(m.group(2)) + else: + net = 'ipv6' + if m.group(1) in ['::']: # Not interested in localhost + return None + ipstr = m.group(1) + sortkey = ipstr # XXX parse IPv6 into number, could use name_to_ipv6 from generate-seeds + port = int(m.group(2)) + else: + # Do IPv4 sanity check + ip = 0 + for i in range(0,4): + if int(m.group(i+2)) < 0 or int(m.group(i+2)) > 255: + return None + ip = ip + (int(m.group(i+2)) << (8*(3-i))) + if ip == 0: + return None + net = 'ipv4' + sortkey = ip + ipstr = m.group(1) + port = int(m.group(6)) + # Skip bad results. + if sline[1] == 0: + return None + # Extract uptime %. + uptime30 = float(sline[7][:-1]) + # Extract Unix timestamp of last success. + lastsuccess = int(sline[2]) + # Extract protocol version. + version = int(sline[10]) + # Extract user agent. + agent = sline[11][1:-1] + # Extract service flags. + service = int(sline[9], 16) + # Extract blocks. + blocks = int(sline[8]) + # Construct result. + return { + 'net': net, + 'ip': ipstr, + 'port': port, + 'ipnum': ip, + 'uptime': uptime30, + 'lastsuccess': lastsuccess, + 'version': version, + 'agent': agent, + 'service': service, + 'blocks': blocks, + 'sortkey': sortkey, + } + +def filtermultiport(ips): + '''Filter out hosts with more nodes per IP''' + hist = collections.defaultdict(list) + for ip in ips: + hist[ip['sortkey']].append(ip) + return [value[0] for (key,value) in hist.items() if len(value)==1] + +# Based on Greg Maxwell's seed_filter.py +def filterbyasn(ips, max_per_asn, max_total): + # Sift out ips by type + ips_ipv4 = [ip for ip in ips if ip['net'] == 'ipv4'] + ips_ipv6 = [ip for ip in ips if ip['net'] == 'ipv6'] + ips_onion = [ip for ip in ips if ip['net'] == 'onion'] + + # Filter IPv4 by ASN + result = [] + asn_count = {} + for ip in ips_ipv4: + if len(result) == max_total: + break + try: + asn = int([x.to_text() for x in dns.resolver.query('.'.join(reversed(ip['ip'].split('.'))) + '.origin.asn.cymru.com', 'TXT').response.answer][0].split('\"')[1].split(' ')[0]) + if asn not in asn_count: + asn_count[asn] = 0 + if asn_count[asn] == max_per_asn: + continue + asn_count[asn] += 1 + result.append(ip) + except: + sys.stderr.write('ERR: Could not resolve ASN for "' + ip['ip'] + '"\n') + + # TODO: filter IPv6 by ASN + + # Add back non-IPv4 + result.extend(ips_ipv6) + result.extend(ips_onion) + return result + +def main(): + lines = sys.stdin.readlines() + ips = [parseline(line) for line in lines] + + # Skip entries with valid address. + ips = [ip for ip in ips if ip is not None] + # Skip entries from suspicious hosts. + ips = [ip for ip in ips if ip['ip'] not in SUSPICIOUS_HOSTS] + # Enforce minimal number of blocks. + ips = [ip for ip in ips if ip['blocks'] >= MIN_BLOCKS] + # Require service bit 1. + ips = [ip for ip in ips if (ip['service'] & 1) == 1] + # Require at least 50% 30-day uptime. + ips = [ip for ip in ips if ip['uptime'] > 50] + # Require a known and recent user agent. + ips = [ip for ip in ips if PATTERN_AGENT.match(ip['agent'])] + # Sort by availability (and use last success as tie breaker) + ips.sort(key=lambda x: (x['uptime'], x['lastsuccess'], x['ip']), reverse=True) + # Filter out hosts with multiple bitcoin ports, these are likely abusive + ips = filtermultiport(ips) + # Look up ASNs and limit results, both per ASN and globally. + ips = filterbyasn(ips, MAX_SEEDS_PER_ASN, NSEEDS) + # Sort the results by IP address (for deterministic output). + ips.sort(key=lambda x: (x['net'], x['sortkey'])) + + for ip in ips: + if ip['net'] == 'ipv6': + print '[%s]:%i' % (ip['ip'], ip['port']) + else: + print '%s:%i' % (ip['ip'], ip['port']) + +if __name__ == '__main__': + main() diff --git a/depend/zcash/contrib/simulations/worstcase.py b/depend/zcash/contrib/simulations/worstcase.py new file mode 100755 index 000000000..3018cd053 --- /dev/null +++ b/depend/zcash/contrib/simulations/worstcase.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python3 +import csv +import os +import subprocess + +# +# Constants +# + +MAX_BLOCK_SIZE = 2000000 + +# +# Verification times +# + +def collect_times(): + # Find bench_bitcoin binary + script_dir = os.path.dirname(os.path.realpath(__file__)) + base_dir = os.path.dirname(os.path.dirname(script_dir)) + bench_bitcoin = os.path.join(base_dir, 'src', 'bench', 'bench_bitcoin') + + # Run bench_bitcoin binary + try: + result = subprocess.run([bench_bitcoin], stdout=subprocess.PIPE, universal_newlines=True) + result.check_returncode() + result = result.stdout + except AttributeError: + # Use the older API + result = subprocess.check_output([bench_bitcoin], universal_newlines=True) + + # Collect benchmarks + benchmarks = {} + for row in result.strip().split('\n')[1:]: # Skip the headings + parts = row.split(',') + benchmarks[parts[0]] = int(parts[2]) + + return { + 'proof': benchmarks['SaplingOutput'], + 'ecdsa': benchmarks['ECDSA'], + 'redjubjub': benchmarks['SaplingSpend'] - benchmarks['SaplingOutput'], + 'ed25519': benchmarks['JoinSplitSig'], + } + +# +# Size calculations +# + +def compact_size_size(nSize): + if nSize < 253: + return 1 + elif nSize <= 0xFFFF: + return 3 + elif nSize <= 0xFFFFFFFF: + return 5 + else: + return 9 + +def script_size(script): + return ( + compact_size_size(len(script)) + + len(script) + ) + +def tx_in_size(scriptSig): + return ( + 32 + # prevout.hash + 4 + # prevout.n + script_size(scriptSig) + + 4 # nSequence + ) + +def tx_out_size(scriptPubKey): + return ( + 8 + # nValue + script_size(scriptPubKey) + ) + +def v4_tx_size(vin, vout, nShieldedSpend, nShieldedOutput, nJoinSplit): + return ( + 4 + # header + 4 + # nVersionGroupId + compact_size_size(len(vin)) + + sum([tx_in_size(scriptSig) for scriptSig in vin]) + + compact_size_size(len(vout)) + + sum([tx_out_size(scriptPubKey) for scriptPubKey in vout]) + + 4 + # lock_time + 4 + # nExpiryHeight + 4 + # valueBalance + compact_size_size(nShieldedSpend) + + (384 * nShieldedSpend) + + compact_size_size(nShieldedOutput) + + (948 * nShieldedOutput) + + compact_size_size(nJoinSplit) + + (1698 * nJoinSplit) + + ((32 + 64) if nJoinSplit > 0 else 0) + # joinSplitPubKey + joinSplitSig + (64 if (nShieldedSpend + nShieldedOutput) > 0 else 0) # bindingSig + ) + +def block_size(vtx): + return ( + 4 + # nVersion + 32 + # hashPrevBlock + 32 + # hashMerkleRoot + 32 + # hashFinalSaplingRoot + 4 + # nTime + 4 + # nBits + 32 + # nNonce + compact_size_size(1344) + # solutionSize + 1344 + # solution + compact_size_size(len(vtx)) + + sum([v4_tx_size(**tx) for tx in vtx]) + ) + +# +# Runners +# + +def worst_case_many_identical_txs(tx): + vtx = [] + while True: + vtx.append(tx) + if block_size(vtx) > MAX_BLOCK_SIZE: + # Keep under the size limit + vtx.pop() + break + return vtx + +def worst_case_one_tx_containing(item): + vtx = [{ + 'vin': [], + 'vout': [], + 'nShieldedSpend': 0, + 'nShieldedOutput': 0, + 'nJoinSplit': 0, + }] + while True: + vtx[0][item] += 1 + if block_size(vtx) > MAX_BLOCK_SIZE: + # Keep under the size limit + vtx[0][item] -= 1 + break + return vtx + +def print_makeup(vtx, times): + # One proof per Sapling spend, Sapling output, and JoinSplit + proofs = sum([tx['nShieldedSpend'] + tx['nShieldedOutput'] + tx['nJoinSplit'] for tx in vtx]) + + # One ECDSA signature per transparent input + ecdsa_sigs = sum([len(tx['vin']) for tx in vtx]) + + # One RedJubjub signature per Sapling spend (spendAuthSig) and per transaction (bindingSig) + redjubjub_sigs = sum([tx['nShieldedSpend'] + ( + 1 if tx['nShieldedSpend'] + tx['nShieldedOutput'] > 0 else 0) for tx in vtx]) + + # One Ed25519 signature per transaction that contains JoinSplits + ed25519_sigs = sum([1 if tx['nJoinSplit'] > 0 else 0 for tx in vtx]) + + print('- Block size: ', block_size(vtx), 'bytes') + print('- Transactions: ', len(vtx)) + print('- Proofs: ', proofs) + print('- ECDSA signatures: ', ecdsa_sigs) + print('- RedJubjub signatures:', redjubjub_sigs) + print('- Ed25519 signatures: ', ed25519_sigs) + print('- Verification time: %0.2f seconds' % (float( + (times['proof'] * proofs) + + (times['ecdsa'] * ecdsa_sigs) + + (times['redjubjub'] * redjubjub_sigs) + + (times['ed25519'] * ed25519_sigs) + ) / 10**9)) + +# +# Worst-case scenarios +# + +def worst_case_one_sapling_spend_per_tx(times): + vtx = worst_case_many_identical_txs({ + 'vin': [], + 'vout': [], + 'nShieldedSpend': 1, + 'nShieldedOutput': 0, + 'nJoinSplit': 0, + }) + print('One Sapling spend per transaction:') + print_makeup(vtx, times) + print() + +def worst_case_one_tx_containing_sapling_spends(times): + vtx = worst_case_one_tx_containing('nShieldedSpend') + print('One transaction containing Sapling spends:') + print_makeup(vtx, times) + print() + +def worst_case_one_sapling_output_per_tx(times): + vtx = worst_case_many_identical_txs({ + 'vin': [], + 'vout': [], + 'nShieldedSpend': 0, + 'nShieldedOutput': 1, + 'nJoinSplit': 0, + }) + print('One Sapling output per transaction:') + print_makeup(vtx, times) + print() + +def worst_case_one_tx_containing_sapling_outputs(times): + vtx = worst_case_one_tx_containing('nShieldedOutput') + print('One transaction containing Sapling outputs:') + print_makeup(vtx, times) + print() + +def worst_case_one_joinsplit_per_tx(times): + vtx = worst_case_many_identical_txs({ + 'vin': [], + 'vout': [], + 'nShieldedSpend': 0, + 'nShieldedOutput': 0, + 'nJoinSplit': 1, + }) + print('One JoinSplit per transaction:') + print_makeup(vtx, times) + print() + +def worst_case_one_tx_containing_joinsplits(times): + vtx = worst_case_one_tx_containing('nJoinSplit') + print('One transaction containing JoinSplits:') + print_makeup(vtx, times) + print() + + +def run(): + print('Collecting benchmarks...') + times = collect_times() + # times = hard_coded_times() + print('Times (ns):', times) + print() + + print('Running worst-case simulations...') + worst_case_one_sapling_spend_per_tx(times) + worst_case_one_tx_containing_sapling_spends(times) + worst_case_one_sapling_output_per_tx(times) + worst_case_one_tx_containing_sapling_outputs(times) + worst_case_one_joinsplit_per_tx(times) + worst_case_one_tx_containing_joinsplits(times) + +if __name__ == '__main__': + run() diff --git a/depend/zcash/contrib/testgen/README.md b/depend/zcash/contrib/testgen/README.md new file mode 100644 index 000000000..83624f443 --- /dev/null +++ b/depend/zcash/contrib/testgen/README.md @@ -0,0 +1,8 @@ +### TestGen ### + +Utilities to generate test vectors for the data-driven Bitcoin tests. + +Usage: + + gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json + gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json \ No newline at end of file diff --git a/depend/zcash/contrib/testgen/base58.py b/depend/zcash/contrib/testgen/base58.py new file mode 100644 index 000000000..b71649514 --- /dev/null +++ b/depend/zcash/contrib/testgen/base58.py @@ -0,0 +1,104 @@ +''' +Bitcoin base58 encoding and decoding. + +Based on https://bitcointalk.org/index.php?topic=1026.0 (public domain) +''' +import hashlib + +# for compatibility with following code... +class SHA256: + new = hashlib.sha256 + +if str != bytes: + # Python 3.x + def ord(c): + return c + def chr(n): + return bytes( (n,) ) + +__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +__b58base = len(__b58chars) +b58chars = __b58chars + +def b58encode(v): + """ encode v, which is a string of bytes, to base58. + """ + long_value = 0 + for (i, c) in enumerate(v[::-1]): + long_value += (256**i) * ord(c) + + result = '' + while long_value >= __b58base: + div, mod = divmod(long_value, __b58base) + result = __b58chars[mod] + result + long_value = div + result = __b58chars[long_value] + result + + # Bitcoin does a little leading-zero-compression: + # leading 0-bytes in the input become leading-1s + nPad = 0 + for c in v: + if c == '\0': nPad += 1 + else: break + + return (__b58chars[0]*nPad) + result + +def b58decode(v, length = None): + """ decode v into a string of len bytes + """ + long_value = 0 + for (i, c) in enumerate(v[::-1]): + long_value += __b58chars.find(c) * (__b58base**i) + + result = bytes() + while long_value >= 256: + div, mod = divmod(long_value, 256) + result = chr(mod) + result + long_value = div + result = chr(long_value) + result + + nPad = 0 + for c in v: + if c == __b58chars[0]: nPad += 1 + else: break + + result = chr(0)*nPad + result + if length is not None and len(result) != length: + return None + + return result + +def checksum(v): + """Return 32-bit checksum based on SHA256""" + return SHA256.new(SHA256.new(v).digest()).digest()[0:4] + +def b58encode_chk(v): + """b58encode a string, with 32-bit checksum""" + return b58encode(v + checksum(v)) + +def b58decode_chk(v): + """decode a base58 string, check and remove checksum""" + result = b58decode(v) + if result is None: + return None + h3 = checksum(result[:-4]) + if result[-4:] == checksum(result[:-4]): + return result[:-4] + else: + return None + +def get_bcaddress_version(strAddress): + """ Returns None if strAddress is invalid. Otherwise returns integer version of address. """ + addr = b58decode_chk(strAddress) + if addr is None or len(addr)!=21: return None + version = addr[0] + return ord(version) + +if __name__ == '__main__': + # Test case (from http://gitorious.org/bitcoin/python-base58.git) + assert get_bcaddress_version('15VjRaDX9zpbA8LVnbrCAFzrVzN7ixHNsC') is 0 + _ohai = 'o hai'.encode('ascii') + _tmp = b58encode(_ohai) + assert _tmp == 'DYB3oMS' + assert b58decode(_tmp, 5) == _ohai + print("Tests passed") diff --git a/depend/zcash/contrib/testgen/gen_base58_test_vectors.py b/depend/zcash/contrib/testgen/gen_base58_test_vectors.py new file mode 100755 index 000000000..17b85667a --- /dev/null +++ b/depend/zcash/contrib/testgen/gen_base58_test_vectors.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python +''' +Generate valid and invalid base58 address and private key test vectors. + +Usage: + gen_base58_test_vectors.py valid 50 > ../../src/test/data/base58_keys_valid.json + gen_base58_test_vectors.py invalid 50 > ../../src/test/data/base58_keys_invalid.json +''' +# 2012 Wladimir J. van der Laan +# Released under MIT License +import os +from itertools import islice +from base58 import b58encode, b58decode, b58encode_chk, b58decode_chk, b58chars +import random +from binascii import b2a_hex + +# key types +PUBKEY_ADDRESS = (0x1C, 0xB8) +SCRIPT_ADDRESS = (0x1C, 0xBD) +PUBKEY_ADDRESS_TEST = (0x1D, 0x25) +SCRIPT_ADDRESS_TEST = (0x1C, 0xBA) +PRIVKEY = 128 +PRIVKEY_TEST = 239 + +metadata_keys = ['isPrivkey', 'isTestnet', 'addrType', 'isCompressed'] +# templates for valid sequences +templates = [ + # prefix, payload_size, suffix, metadata + # None = N/A + (PUBKEY_ADDRESS, 20, (), (False, False, 'pubkey', None)), + (SCRIPT_ADDRESS, 20, (), (False, False, 'script', None)), + (PUBKEY_ADDRESS_TEST, 20, (), (False, True, 'pubkey', None)), + (SCRIPT_ADDRESS_TEST, 20, (), (False, True, 'script', None)), + ((PRIVKEY,), 32, (), (True, False, None, False)), + ((PRIVKEY,), 32, (1,), (True, False, None, True)), + ((PRIVKEY_TEST,), 32, (), (True, True, None, False)), + ((PRIVKEY_TEST,), 32, (1,), (True, True, None, True)) +] + +def is_valid(v): + '''Check vector v for validity''' + result = b58decode_chk(v) + if result is None: + return False + valid = False + for template in templates: + prefix = str(bytearray(template[0])) + suffix = str(bytearray(template[2])) + if result.startswith(prefix) and result.endswith(suffix): + if (len(result) - len(prefix) - len(suffix)) == template[1]: + return True + return False + +def gen_valid_vectors(): + '''Generate valid test vectors''' + while True: + for template in templates: + prefix = str(bytearray(template[0])) + payload = os.urandom(template[1]) + suffix = str(bytearray(template[2])) + rv = b58encode_chk(prefix + payload + suffix) + assert is_valid(rv) + metadata = dict([(x,y) for (x,y) in zip(metadata_keys,template[3]) if y is not None]) + yield (rv, b2a_hex(payload), metadata) + +def gen_invalid_vector(template, corrupt_prefix, randomize_payload_size, corrupt_suffix): + '''Generate possibly invalid vector''' + if corrupt_prefix: + prefix = os.urandom(1) + else: + prefix = str(bytearray(template[0])) + + if randomize_payload_size: + payload = os.urandom(max(int(random.expovariate(0.5)), 50)) + else: + payload = os.urandom(template[1]) + + if corrupt_suffix: + suffix = os.urandom(len(template[2])) + else: + suffix = str(bytearray(template[2])) + + return b58encode_chk(prefix + payload + suffix) + +def randbool(p = 0.5): + '''Return True with P(p)''' + return random.random() < p + +def gen_invalid_vectors(): + '''Generate invalid test vectors''' + # start with some manual edge-cases + yield "", + yield "x", + while True: + # kinds of invalid vectors: + # invalid prefix + # invalid payload length + # invalid (randomized) suffix (add random data) + # corrupt checksum + for template in templates: + val = gen_invalid_vector(template, randbool(0.2), randbool(0.2), randbool(0.2)) + if random.randint(0,10)<1: # line corruption + if randbool(): # add random character to end + val += random.choice(b58chars) + else: # replace random character in the middle + n = random.randint(0, len(val)) + val = val[0:n] + random.choice(b58chars) + val[n+1:] + if not is_valid(val): + yield val, + +if __name__ == '__main__': + import sys, json + iters = {'valid':gen_valid_vectors, 'invalid':gen_invalid_vectors} + try: + uiter = iters[sys.argv[1]] + except IndexError: + uiter = gen_valid_vectors + try: + count = int(sys.argv[2]) + except IndexError: + count = 0 + + data = list(islice(uiter(), count)) + json.dump(data, sys.stdout, sort_keys=True, indent=4) + sys.stdout.write('\n') + diff --git a/depend/zcash/contrib/tidy_datadir.sh b/depend/zcash/contrib/tidy_datadir.sh new file mode 100755 index 000000000..7861e6e6e --- /dev/null +++ b/depend/zcash/contrib/tidy_datadir.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Copyright (c) 2013 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +if [ -d "$1" ]; then + cd "$1" || exit 1 +else + echo "Usage: $0 " >&2 + echo "Removes obsolete Bitcoin database files" >&2 + exit 1 +fi + +LEVEL=0 +if [ -f wallet.dat -a -f addr.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=1; fi +if [ -f wallet.dat -a -f peers.dat -a -f blkindex.dat -a -f blk0001.dat ]; then LEVEL=2; fi +if [ -f wallet.dat -a -f peers.dat -a -f coins/CURRENT -a -f blktree/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=3; fi +if [ -f wallet.dat -a -f peers.dat -a -f chainstate/CURRENT -a -f blocks/index/CURRENT -a -f blocks/blk00000.dat ]; then LEVEL=4; fi + +case $LEVEL in + 0) + echo "Error: no Bitcoin datadir detected." + exit 1 + ;; + 1) + echo "Detected old Bitcoin datadir (before 0.7)." + echo "Nothing to do." + exit 0 + ;; + 2) + echo "Detected Bitcoin 0.7 datadir." + ;; + 3) + echo "Detected Bitcoin pre-0.8 datadir." + ;; + 4) + echo "Detected Bitcoin 0.8 datadir." + ;; +esac + +FILES="" +DIRS="" + +if [ $LEVEL -ge 3 ]; then FILES=$(echo $FILES blk????.dat blkindex.dat); fi +if [ $LEVEL -ge 2 ]; then FILES=$(echo $FILES addr.dat); fi +if [ $LEVEL -ge 4 ]; then DIRS=$(echo $DIRS coins blktree); fi + +for FILE in $FILES; do + if [ -f $FILE ]; then + echo "Deleting: $FILE" + rm -f $FILE + fi +done + +for DIR in $DIRS; do + if [ -d $DIR ]; then + echo "Deleting: $DIR/" + rm -rf $DIR + fi +done + +echo "Done." diff --git a/depend/zcash/contrib/zcash-cli.bash-completion b/depend/zcash/contrib/zcash-cli.bash-completion new file mode 100644 index 000000000..264ba86f4 --- /dev/null +++ b/depend/zcash/contrib/zcash-cli.bash-completion @@ -0,0 +1,161 @@ +# bash programmable completion for zcash-cli(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Copyright (c) 2016-2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# call $zcash-cli for RPC +_zcash_rpc() { + # determine already specified args necessary for RPC + local rpcargs=() + for i in ${COMP_LINE}; do + case "$i" in + -conf=*|-datadir=*|-regtest|-rpc*|-testnet) + rpcargs=( "${rpcargs[@]}" "$i" ) + ;; + esac + done + $zcash_cli "${rpcargs[@]}" "$@" +} + +# Add wallet accounts to COMPREPLY +_zcash_accounts() { + local accounts + # Accounts are deprecated in Zcash + #accounts=$(_zcash_rpc listaccounts | awk -F '"' '{ print $2 }') + accounts="\\\"\\\"" + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) +} + +_zcash_cli() { + local cur prev words=() cword + local zcash_cli + + # save and use original argument to invoke zcash-cli for -help, help and RPC + # as zcash-cli might not be in $PATH + zcash_cli="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + if ((cword > 5)); then + case ${words[cword-5]} in + sendtoaddress) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 4)); then + case ${words[cword-4]} in + importaddress|listtransactions|setban) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + signrawtransaction) + COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 3)); then + case ${words[cword-3]} in + addmultisigaddress) + _zcash_accounts + return 0 + ;; + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 2)); then + case ${words[cword-2]} in + addnode) + COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) + return 0 + ;; + setban) + COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) + return 0 + ;; + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + z_importkey|z_importviewingkey) + COMPREPLY=( $( compgen -W "yes no whenkeyisnew" -- "$cur" ) ) + return 0 + ;; + move|setaccount) + _zcash_accounts + return 0 + ;; + esac + fi + + case "$prev" in + backupwallet|dumpwallet|importwallet|z_exportwallet|z_importwallet) + _filedir + return 0 + ;; + getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) + _zcash_accounts + return 0 + ;; + esac + + case "$cur" in + -conf=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + local helpopts commands + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + helpopts=$($zcash_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + fi + + # only parse help if senseful + if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then + commands=$(_zcash_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + fi + + COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _zcash_cli zcash-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/depend/zcash/contrib/zcash-tx.bash-completion b/depend/zcash/contrib/zcash-tx.bash-completion new file mode 100644 index 000000000..b6a0cf434 --- /dev/null +++ b/depend/zcash/contrib/zcash-tx.bash-completion @@ -0,0 +1,58 @@ +# bash programmable completion for zcash-tx(1) +# Copyright (c) 2016 The Bitcoin Core developers +# Copyright (c) 2016-2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +_zcash_tx() { + local cur prev words=() cword + local zcash_tx + + # save and use original argument to invoke zcash-tx for -help + # it might not be in $PATH + zcash_tx="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n =: cur prev words cword + + case "$cur" in + load=*:*) + cur="${cur#load=*:}" + _filedir + return 0 + ;; + *=*) # prevent attempts to complete other arguments + return 0 + ;; + esac + + if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then + # only options (or an uncompletable hex-string) allowed + # parse zcash-tx -help for options + local helpopts + helpopts=$($zcash_tx -help | sed -e '/^ -/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + else + # only commands are allowed + # parse -help for commands + local helpcmds + helpcmds=$($zcash_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + + return 0 +} && +complete -F _zcash_tx zcash-tx + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/depend/zcash/contrib/zcashd.bash-completion b/depend/zcash/contrib/zcashd.bash-completion new file mode 100644 index 000000000..d5135350a --- /dev/null +++ b/depend/zcash/contrib/zcashd.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for zcashd(1) +# Copyright (c) 2012-2017 The Bitcoin Core developers +# Copyright (c) 2016-2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +_zcashd() { + local cur prev words=() cword + local zcashd + + # save and use original argument to invoke zcashd for -help + # it might not be in $PATH + zcashd="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + case "$cur" in + -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*|-exportdir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + local helpopts + helpopts=$($zcashd -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _zcashd zcashd + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/depend/zcash/contrib/zmq/zmq_sub.py b/depend/zcash/contrib/zmq/zmq_sub.py new file mode 100755 index 000000000..6df3e0838 --- /dev/null +++ b/depend/zcash/contrib/zmq/zmq_sub.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import array +import binascii +import zmq +import struct + +port = 28332 + +zmqContext = zmq.Context() +zmqSubSocket = zmqContext.socket(zmq.SUB) +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "hashtx") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawblock") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "rawtx") +zmqSubSocket.setsockopt(zmq.SUBSCRIBE, "checkedblock") +zmqSubSocket.connect("tcp://127.0.0.1:%i" % port) + +try: + while True: + msg = zmqSubSocket.recv_multipart() + topic = str(msg[0]) + body = msg[1] + sequence = "Unknown"; + if len(msg[-1]) == 4: + msgSequence = struct.unpack(' $@ + $(AT)touch $@ + + +define check_or_remove_cached + mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \ + $(build_SHA256SUM) -c $($(package)_cached_checksum) >/dev/null 2>/dev/null || \ + ( rm -f $($(package)_cached_checksum); \ + if test -f "$($(package)_cached)"; then echo "Checksum mismatch for $(package). Forcing rebuild.."; rm -f $($(package)_cached_checksum) $($(package)_cached); fi ) +endef + +define check_or_remove_sources + mkdir -p $($(package)_source_dir); cd $($(package)_source_dir); \ + $(build_SHA256SUM) -c $($(package)_fetched) >/dev/null 2>/dev/null || \ + ( test -z "$($(package)_all_sources)" || ( echo $($(package)_all_sources) | xargs -n 1 test ! -f ) || echo "Checksum missing or mismatched for $(package) source. Forcing re-download."; \ + rm -f $($(package)_all_sources) $($(1)_fetched)) +endef + +check-packages: + @$(foreach package,$(packages),$(call check_or_remove_cached,$(package));) + @$(foreach package,$(rust_crates),$(call check_or_remove_cached,$(package));) + @$(foreach package,$(native_packages),$(call check_or_remove_cached,$(package));) +check-sources: + @$(foreach package,$(packages),$(call check_or_remove_sources,$(package));) + @$(foreach package,$(rust_crates),$(call check_or_remove_sources,$(package));) + @$(foreach package,$(native_packages),$(call check_or_remove_sources,$(package));) + +$(host_prefix)/share/config.site: check-packages + +check-packages: check-sources + +install: check-packages $(host_prefix)/share/config.site + + +crates_download_dir=$(base_download_dir)/crates +download-crates: native_rust + $(AT)echo Vendoring crates... + $(AT)mkdir -p $(SOURCES_PATH) + $(AT)rm -rf $(crates_download_dir) + $(AT)mkdir -p $(crates_download_dir) + $(AT)tar xf $(native_rust_cached) -C $(crates_download_dir) + $(AT)$(crates_download_dir)/native/bin/cargo vendor --locked --manifest-path $(BASEDIR)/../Cargo.toml $(crates_download_dir)/$(CRATE_REGISTRY) + $(AT)cd $(crates_download_dir); find $(CRATE_REGISTRY) | sort | tar --no-recursion -czf $(CRATE_ARCHIVE) -T - + $(AT)rm -rf $(crates_download_dir) + +download-one: check-sources $(all_sources) + +download-osx: + @$(MAKE) -s HOST=x86_64-apple-darwin14 download-one +download-linux: + @$(MAKE) -s HOST=x86_64-pc-linux-gnu download-one +download-win: + @$(MAKE) -s HOST=x86_64-w64-mingw32 download-one +download: download-crates download-osx download-linux download-win + +.PHONY: install cached download-crates download-one download-osx download-linux download-win download check-packages check-sources diff --git a/depend/zcash/depends/README.md b/depend/zcash/depends/README.md new file mode 100644 index 000000000..cf88a425f --- /dev/null +++ b/depend/zcash/depends/README.md @@ -0,0 +1,57 @@ +### Usage + +To build dependencies for the current arch+OS: + + make + +To build for another arch/OS: + + make HOST=host-platform-triplet + +For example: + + make HOST=x86_64-w64-mingw32 -j4 + +A prefix will be generated that's suitable for plugging into Bitcoin's +configure. In the above example, a dir named x86_64-w64-mingw32 will be +created. To use it for Bitcoin: + + ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + +Common `host-platform-triplets` for cross compilation are: + +- `i686-w64-mingw32` for Win32 +- `x86_64-w64-mingw32` for Win64 +- `x86_64-apple-darwin18` for macOS +- `arm-linux-gnueabihf` for Linux ARM 32 bit +- `aarch64-linux-gnu` for Linux ARM 64 bit +- `riscv32-linux-gnu` for Linux RISC-V 32 bit +- `riscv64-linux-gnu` for Linux RISC-V 64 bit + +No other options are needed, the paths are automatically configured. + +Dependency Options: +The following can be set when running make: make FOO=bar + + SOURCES_PATH: downloaded sources will be placed here + BASE_CACHE: built packages will be placed here + SDK_PATH: Path where sdk's can be found (used by OSX) + FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up + NO_WALLET: Don't download/build/cache libs needed to enable the wallet + DEBUG: disable some optimizations and enable more runtime checking + +If some packages are not built, for example `make NO_WALLET=1`, the appropriate +options will be passed to bitcoin's configure. In this case, `--disable-wallet`. + +Additional targets: + + download: run 'make download' to fetch all sources without building them + download-osx: run 'make download-osx' to fetch all sources needed for osx builds + download-win: run 'make download-win' to fetch all sources needed for win builds + download-linux: run 'make download-linux' to fetch all sources needed for linux builds + +### Other documentation + +- [description.md](description.md): General description of the depends system +- [packages.md](packages.md): Steps for adding packages + diff --git a/depend/zcash/depends/builders/darwin.mk b/depend/zcash/depends/builders/darwin.mk new file mode 100644 index 000000000..bcb02b782 --- /dev/null +++ b/depend/zcash/depends/builders/darwin.mk @@ -0,0 +1,23 @@ +build_darwin_CC: = $(shell xcrun -f clang) +build_darwin_CXX: = $(shell xcrun -f clang++) +build_darwin_AR: = $(shell xcrun -f ar) +build_darwin_RANLIB: = $(shell xcrun -f ranlib) +build_darwin_STRIP: = $(shell xcrun -f strip) +build_darwin_OTOOL: = $(shell xcrun -f otool) +build_darwin_NM: = $(shell xcrun -f nm) +build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +build_darwin_SHA256SUM = shasum -a 256 +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +#darwin host on darwin builder. overrides darwin host preferences. +darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) -fvisibility=hidden -fvisibility-inlines-hidden --sysroot $(shell xcrun --show-sdk-path) +darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -fvisibility=hidden -fvisibility-inlines-hidden -stdlib=libc++ --sysroot $(shell xcrun --show-sdk-path) +darwin_AR:=$(shell xcrun -f ar) +darwin_RANLIB:=$(shell xcrun -f ranlib) +darwin_STRIP:=$(shell xcrun -f strip) +darwin_LIBTOOL:=$(shell xcrun -f libtool) +darwin_OTOOL:=$(shell xcrun -f otool) +darwin_NM:=$(shell xcrun -f nm) +darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +darwin_native_binutils= +darwin_native_toolchain= diff --git a/depend/zcash/depends/builders/default.mk b/depend/zcash/depends/builders/default.mk new file mode 100644 index 000000000..f097db65d --- /dev/null +++ b/depend/zcash/depends/builders/default.mk @@ -0,0 +1,20 @@ +default_build_CC = gcc +default_build_CXX = g++ +default_build_AR = ar +default_build_RANLIB = ranlib +default_build_STRIP = strip +default_build_NM = nm +default_build_OTOOL = otool +default_build_INSTALL_NAME_TOOL = install_name_tool + +define add_build_tool_func +build_$(build_os)_$1 ?= $$(default_build_$1) +build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) +build_$1=$$(build_$(build_arch)_$(build_os)_$1) +endef +$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) +define add_build_flags_func +build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) +build_$1=$$(build_$(build_arch)_$(build_os)_$1) +endef +$(foreach flags, CFLAGS CXXFLAGS LDFLAGS, $(eval $(call add_build_flags_func,$(flags)))) diff --git a/depend/zcash/depends/builders/freebsd.mk b/depend/zcash/depends/builders/freebsd.mk new file mode 100644 index 000000000..7a61043e9 --- /dev/null +++ b/depend/zcash/depends/builders/freebsd.mk @@ -0,0 +1,4 @@ +build_freebsd_CC = clang +build_freebsd_CXX = clang++ +build_freebsd_SHA256SUM = shasum -a 256 +build_freebsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depend/zcash/depends/builders/linux.mk b/depend/zcash/depends/builders/linux.mk new file mode 100644 index 000000000..b03f42401 --- /dev/null +++ b/depend/zcash/depends/builders/linux.mk @@ -0,0 +1,2 @@ +build_linux_SHA256SUM = sha256sum +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depend/zcash/depends/config.guess b/depend/zcash/depends/config.guess new file mode 100755 index 000000000..8d70ec2b2 --- /dev/null +++ b/depend/zcash/depends/config.guess @@ -0,0 +1,1685 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2020 Free Software Foundation, Inc. + +timestamp='2020-09-19' + +# This file 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 to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2020 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + #include + #ifdef __DEFINED_va_list + LIBC=musl + #else + LIBC=gnu + #endif + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-pc-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + # shellcheck disable=SC2154 + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; +esac + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/depend/zcash/depends/config.site.in b/depend/zcash/depends/config.site.in new file mode 100644 index 000000000..ba96d9f45 --- /dev/null +++ b/depend/zcash/depends/config.site.in @@ -0,0 +1,78 @@ +depends_prefix="`dirname ${ac_site_file}`/.." + +cross_compiling=maybe +host_alias=@HOST@ +ac_tool_prefix=${host_alias}- + +if test -z $with_boost; then + with_boost=$depends_prefix +fi + + +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 +fi + +PATH=$depends_prefix/native/bin:$PATH +PKG_CONFIG="`which pkg-config` --static" + +# These two need to remain exported because pkg-config does not see them +# otherwise. That means they must be unexported at the end of configure.ac to +# avoid ruining the cache. Sigh. + +export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig +export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig + +CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" + +if test x@host_os@ = xfreebsd; then + LDFLAGS="-L$depends_prefix/lib $LDFLAGS -static-libstdc++ -lcxxrt" +else + LDFLAGS="-L$depends_prefix/lib $LDFLAGS -static-libstdc++ -lc++abi" +fi + +CC="@CC@" +CXX="@CXX@" +OBJC="${CC}" +OBJCXX="${CXX}" +CCACHE=$depends_prefix/native/bin/ccache + +if test -n "@AR@"; then + AR=@AR@ + ac_cv_path_ac_pt_AR=${AR} +fi + +if test -n "@RANLIB@"; then + RANLIB=@RANLIB@ + ac_cv_path_ac_pt_RANLIB=${RANLIB} +fi + +if test -n "@NM@"; then + NM=@NM@ + ac_cv_path_ac_pt_NM=${NM} +fi + +if test -n "@debug@"; then + enable_reduce_exports=no +fi + +if test -n "@CFLAGS@"; then + CFLAGS="@CFLAGS@ $CFLAGS" +fi +if test -n "@CXXFLAGS@"; then + CXXFLAGS="@CXXFLAGS@ $CXXFLAGS" +fi +if test -n "@CPPFLAGS@"; then + CPPFLAGS="@CPPFLAGS@ $CPPFLAGS" +fi +if test -n "@LDFLAGS@"; then + LDFLAGS="@LDFLAGS@ $LDFLAGS" +fi diff --git a/depend/zcash/depends/config.sub b/depend/zcash/depends/config.sub new file mode 100755 index 000000000..780c2bbaa --- /dev/null +++ b/depend/zcash/depends/config.sub @@ -0,0 +1,1845 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2020 Free Software Foundation, Inc. + +timestamp='2020-09-08' + +# This file 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 to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2020 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x$basic_os != x +then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo $basic_os | sed -e 's|gnu/linux|gnu|'` + ;; + nto-qnx*) + kernel=nto + os=`echo $basic_os | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + nto-qnx*) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/depend/zcash/depends/description.md b/depend/zcash/depends/description.md new file mode 100644 index 000000000..74f9ef3f2 --- /dev/null +++ b/depend/zcash/depends/description.md @@ -0,0 +1,53 @@ +This is a system of building and caching dependencies necessary for building Bitcoin. +There are several features that make it different from most similar systems: + +### It is designed to be builder and host agnostic + +In theory, binaries for any target OS/architecture can be created, from a +builder running any OS/architecture. In practice, build-side tools must be +specified when the defaults don't fit, and packages must be amended to work +on new hosts. For now, a build architecture of x86_64 is assumed, either on +Linux or OSX. + +### No reliance on timestamps + +File presence is used to determine what needs to be built. This makes the +results distributable and easily digestable by automated builders. + +### Each build only has its specified dependencies available at build-time. + +For each build, the sysroot is wiped and the (recursive) dependencies are +installed. This makes each build deterministic, since there will never be any +unknown files available to cause side-effects. + +### Each package is cached and only rebuilt as needed. + +Before building, a unique build-id is generated for each package. This id +consists of a hash of all files used to build the package (Makefiles, packages, +etc), and as well as a hash of the same data for each recursive dependency. If +any portion of a package's build recipe changes, it will be rebuilt as well as +any other package that depends on it. If any of the main makefiles (Makefile, +funcs.mk, etc) are changed, all packages will be rebuilt. After building, the +results are cached into a tarball that can be re-used and distributed. + +### Package build results are (relatively) deterministic. + +Each package is configured and patched so that it will yield the same +build-results with each consequent build, within a reasonable set of +constraints. Some things like timestamp insertion are unavoidable, and are +beyond the scope of this system. Additionally, the toolchain itself must be +capable of deterministic results. When revisions are properly bumped, a cached +build should represent an exact single payload. + +### Sources are fetched and verified automatically + +Each package must define its source location and checksum. The build will fail +if the fetched source does not match. Sources may be pre-seeded and/or cached +as desired. + +### Self-cleaning + +Build and staging dirs are wiped after use, and any previous version of a +cached result is removed following a successful build. Automated builders +should be able to build each revision and store the results with no further +intervention. diff --git a/depend/zcash/depends/funcs.mk b/depend/zcash/depends/funcs.mk new file mode 100644 index 000000000..c0c118285 --- /dev/null +++ b/depend/zcash/depends/funcs.mk @@ -0,0 +1,249 @@ +define int_vars +#Set defaults for vars which may be overridden per-package +$(1)_cc=$($($(1)_type)_CC) +$(1)_cxx=$($($(1)_type)_CXX) +$(1)_objc=$($($(1)_type)_OBJC) +$(1)_objcxx=$($($(1)_type)_OBJCXX) +$(1)_ar=$($($(1)_type)_AR) +$(1)_ranlib=$($($(1)_type)_RANLIB) +$(1)_libtool=$($($(1)_type)_LIBTOOL) +$(1)_nm=$($($(1)_type)_NM) +$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS) +$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS) +$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib +$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include +$(1)_recipe_hash:= +endef + +define int_get_all_dependencies +$(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies)))) +endef + +define download_and_check_file +($(build_DOWNLOAD) "$(1)/$(2).temp" $(3) && echo "$(4) $(1)/$(2).temp" > $(1)/.$(2).hash && $(build_SHA256SUM) -c $(1)/.$(2).hash) +endef + +define fetch_file +(test -f $$($(1)_source_dir)/$(4) || \ + ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \ + ( $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(2)/$(3)",$(5)) || \ + $(call download_and_check_file,$$($(1)_download_dir),$(4),"$(FALLBACK_DOWNLOAD_PATH)/$(4)",$(5)) ) && \ + mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \ + rm -rf $$($(1)_download_dir) )) +endef + +define int_get_build_recipe_hash +$(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $(PATCHES_PATH)/$(1)/,$($(1)_patches)) | cut -d" " -f1)) +$(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1)) +endef + +define int_get_build_id +$(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) +$(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) +$(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) +$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps)) +$(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) +final_build_id_long+=$($(package)_build_id_long) + +#override platform specific files and hashes +$(eval $(1)_file_name=$(if $($(1)_exact_file_name),$($(1)_exact_file_name),$(if $($(1)_file_name_$(host_arch)_$(host_os)),$($(1)_file_name_$(host_arch)_$(host_os)),$(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_arch)_$(host_os)),$($(1)_sha256_hash_$(host_arch)_$(host_os)),$(if $($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash))))) +$(eval $(1)_download_file=$(if $($(1)_exact_download_file),$($(1)_exact_download_file),$(if $($(1)_download_file_$(host_arch)_$(host_os)),$($(1)_download_file_$(host_arch)_$(host_os)),$(if $($(1)_download_file_$(host_os)),$($(1)_download_file_$(host_os)),$(if $($(1)_download_file),$($(1)_download_file),$($(1)_file_name)))))) +$(eval $(1)_download_path=$(if $($(1)_exact_download_path),$($(1)_exact_download_path),$(if $($(1)_download_path_$(host_arch)_$(host_os)),$($(1)_download_path_$(host_arch)_$(host_os)),$(if $($(1)_download_path_$(host_os)),$($(1)_download_path_$(host_os)),$($(1)_download_path))))) + +#compute package-specific paths +$(1)_build_subdir?=. +$(1)_source_dir:=$(SOURCES_PATH) +$(1)_source:=$$($(1)_source_dir)/$($(1)_file_name) +$(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id) +$(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix) +$(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id) +$(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version) +$(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir) +$(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.hash +$(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id) +$(1)_prefixbin:=$($($(1)_type)_prefix)/bin/ +$(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz +$(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources) + +#stamps +$(1)_fetched=$(SOURCES_PATH)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name).hash +$(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted +$(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed +$(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned +$(1)_built=$$($(1)_build_dir)/.stamp_built +$(1)_configured=$$($(1)_build_dir)/.stamp_configured +$(1)_staged=$$($(1)_staging_dir)/.stamp_staged +$(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed +$(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 --no-same-owner --strip-components=1 -xf $$($(1)_source) +$(1)_preprocess_cmds ?= +$(1)_build_cmds ?= +$(1)_config_cmds ?= +$(1)_stage_cmds ?= +$(1)_set_vars ?= + + +all_sources+=$$($(1)_fetched) +endef +#$(foreach dep_target,$($(1)_all_dependencies),$(eval $(1)_dependency_targets=$($(dep_target)_cached))) + + +define int_config_attach_build_config +$(eval $(call $(1)_set_vars,$(1))) +$(1)_cflags+=$($(1)_cflags_$(release_type)) +$(1)_cflags+=$($(1)_cflags_$(host_arch)) $($(1)_cflags_$(host_arch)_$(release_type)) +$(1)_cflags+=$($(1)_cflags_$(host_os)) $($(1)_cflags_$(host_os)_$(release_type)) +$(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os)) $($(1)_cflags_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_cxxflags+=$($(1)_cxxflags_$(release_type)) +$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)) $($(1)_cxxflags_$(host_arch)_$(release_type)) +$(1)_cxxflags+=$($(1)_cxxflags_$(host_os)) $($(1)_cxxflags_$(host_os)_$(release_type)) +$(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os)) $($(1)_cxxflags_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_cppflags+=$($(1)_cppflags_$(release_type)) +$(1)_cppflags+=$($(1)_cppflags_$(host_arch)) $($(1)_cppflags_$(host_arch)_$(release_type)) +$(1)_cppflags+=$($(1)_cppflags_$(host_os)) $($(1)_cppflags_$(host_os)_$(release_type)) +$(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os)) $($(1)_cppflags_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_ldflags+=$($(1)_ldflags_$(release_type)) +$(1)_ldflags+=$($(1)_ldflags_$(host_arch)) $($(1)_ldflags_$(host_arch)_$(release_type)) +$(1)_ldflags+=$($(1)_ldflags_$(host_os)) $($(1)_ldflags_$(host_os)_$(release_type)) +$(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os)) $($(1)_ldflags_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_build_opts+=$$($(1)_build_opts_$(release_type)) +$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)) $$($(1)_build_opts_$(host_arch)_$(release_type)) +$(1)_build_opts+=$$($(1)_build_opts_$(host_os)) $$($(1)_build_opts_$(host_os)_$(release_type)) +$(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os)) $$($(1)_build_opts_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_config_opts+=$$($(1)_config_opts_$(release_type)) +$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)) $$($(1)_config_opts_$(host_arch)_$(release_type)) +$(1)_config_opts+=$$($(1)_config_opts_$(host_os)) $$($(1)_config_opts_$(host_os)_$(release_type)) +$(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os)) $$($(1)_config_opts_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_config_env+=$$($(1)_config_env_$(release_type)) +$(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_$(release_type)) +$(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type)) +$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type)) + +$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig +$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig +$(1)_config_env+=PATH="$(build_prefix)/bin:$(PATH)" +$(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)" +$(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)" +$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" + +ifneq ($($(1)_nm),) +$(1)_autoconf += NM="$$($(1)_nm)" +endif +ifneq ($($(1)_ranlib),) +$(1)_autoconf += RANLIB="$$($(1)_ranlib)" +endif +ifneq ($($(1)_ar),) +$(1)_autoconf += AR="$$($(1)_ar)" +endif +ifneq ($($(1)_cflags),) +$(1)_autoconf += CFLAGS="$$($(1)_cflags)" +endif +ifneq ($($(1)_cxxflags),) +$(1)_autoconf += CXXFLAGS="$$($(1)_cxxflags)" +endif +ifneq ($($(1)_cppflags),) +$(1)_autoconf += CPPFLAGS="$$($(1)_cppflags)" +endif +ifneq ($($(1)_ldflags),) +$(1)_autoconf += LDFLAGS="$$($(1)_ldflags)" +endif +endef + +define int_add_cmds +$($(1)_fetched): + $(AT)mkdir -p $$(@D) $(SOURCES_PATH) + $(AT)rm -f $$@ + $(AT)touch $$@ + $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1)) + $(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) + $(AT)touch $$@ +$($(1)_extracted): | $($(1)_fetched) + $(AT)echo Extracting $(1)... + $(AT)mkdir -p $$(@D) + $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) + $(AT)touch $$@ +$($(1)_preprocessed): | $($(1)_dependencies) $($(1)_extracted) + $(AT)echo Preprocessing $(1)... + $(AT)mkdir -p $$(@D) $($(1)_patch_dir) + $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) + $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) + $(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 --no-same-owner -xf $($(package)_cached); ) + $(AT)mkdir -p $$(@D) + $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) + $(AT)touch $$@ +$($(1)_built): | $($(1)_configured) + $(AT)echo Building $(1)... + $(AT)mkdir -p $$(@D) + $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) + $(AT)touch $$@ +$($(1)_staged): | $($(1)_built) + $(AT)echo Staging $(1)... + $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix) + $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) + $(AT)rm -rf $($(1)_extract_dir) + $(AT)touch $$@ +$($(1)_postprocessed): | $($(1)_staged) + $(AT)echo Postprocessing $(1)... + $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) + $(AT)touch $$@ +$($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) + $(AT)echo Caching $(1)... + $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + $(AT)mkdir -p $$(@D) + $(AT)rm -rf $$(@D) && mkdir -p $$(@D) + $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@) + $(AT)rm -rf $($(1)_staging_dir) +$($(1)_cached_checksum): $($(1)_cached) + $(AT)cd $$(@D); $(build_SHA256SUM) $$( $$(@) + +.PHONY: $(1) +$(1): | $($(1)_cached_checksum) +.SECONDARY: $($(1)_cached) $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched) + +endef + +# These functions create the build targets for each package. They must be +# broken down into small steps so that each part is done for all packages +# before moving on to the next step. Otherwise, a package's info +# (build-id for example) would only be available to another package if it +# happened to be computed already. + +#set the type for host/build packages. +$(foreach native_package,$(native_packages),$(eval $(native_package)_type=build)) +$(foreach package,$(packages),$(eval $(package)_type=$(host_arch)_$(host_os))) + +#set overridable defaults +$(foreach package,$(all_packages),$(eval $(call int_vars,$(package)))) + +#include package files +$(foreach package,$(all_packages),$(eval include packages/$(package).mk)) + +#compute a hash of all files that comprise this package's build recipe +$(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package)))) + +#generate a unique id for this package, incorporating its dependencies as well +$(foreach package,$(all_packages),$(eval $(call int_get_build_id,$(package)))) + +#compute final vars after reading package vars +$(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$(package)))) + +#create build targets +$(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package)))) + +#special exception: if a toolchain package exists, all non-native packages depend on it +$(foreach package,$(packages),$(eval $($(package)_unpacked): |$($($(host_arch)_$(host_os)_native_toolchain)_cached) $($($(host_arch)_$(host_os)_native_binutils)_cached) )) diff --git a/depend/zcash/depends/hosts/darwin.mk b/depend/zcash/depends/hosts/darwin.mk new file mode 100644 index 000000000..78d696a7a --- /dev/null +++ b/depend/zcash/depends/hosts/darwin.mk @@ -0,0 +1,43 @@ +OSX_MIN_VERSION=10.14 +XCODE_VERSION=11.3.1 +XCODE_BUILD_ID=11C505 +LD64_VERSION=530 + +OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers + +# Flag explanations: +# +# -mlinker-version +# +# Ensures that modern linker features are enabled. See here for more +# details: https://github.com/bitcoin/bitcoin/pull/19407. +# +# -B$(build_prefix)/bin +# +# Explicitly point to our binaries (e.g. cctools) so that they are +# ensured to be found and preferred over other possibilities. +# +# -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# +# Forces clang to use the libc++ headers from our SDK and completely +# forget about the libc++ headers from the standard directories +# +# TODO: Once we start requiring a clang version that has the +# -stdlib++-isystem flag first introduced here: +# https://reviews.llvm.org/D64089, we should use that instead. Read the +# differential summary there for more details. +# +darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin +darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 + +darwin_CFLAGS=-pipe +darwin_CXXFLAGS=$(darwin_CFLAGS) + +darwin_release_CFLAGS=-O3 +darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) + +darwin_debug_CFLAGS=-O0 +darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) + +darwin_native_binutils=native_cctools +darwin_native_toolchain=native_cctools diff --git a/depend/zcash/depends/hosts/default.mk b/depend/zcash/depends/hosts/default.mk new file mode 100644 index 000000000..ec9ca3e63 --- /dev/null +++ b/depend/zcash/depends/hosts/default.mk @@ -0,0 +1,45 @@ +# Flag explanations: +# +# -B$(build_prefix)/bin +# +# Explicitly point to our binaries (e.g. cctools) so that they are +# ensured to be found and preferred over other possibilities. +# +default_host_CC = clang -target $(host) -B$(build_prefix)/bin +default_host_CXX = clang++ -target $(host) -B$(build_prefix)/bin -stdlib=libc++ +default_host_AR = llvm-ar +default_host_RANLIB = llvm-ranlib +default_host_STRIP = llvm-strip +default_host_LIBTOOL = $(host_toolchain)libtool +default_host_INSTALL_NAME_TOOL = $(host_toolchain)install_name_tool +default_host_OTOOL = $(host_toolchain)otool +default_host_NM = llvm-nm + +$(host_os)_native_binutils?=native_clang +$(host_os)_native_toolchain?=native_clang + +define add_host_tool_func +ifneq ($(filter $(origin $1),undefined default),) +# Do not consider the well-known var $1 if it is undefined or is taking a value +# that is predefined by "make" (e.g. the make variable "CC" has a predefined +# value of "cc") +$(host_os)_$1?=$$(default_host_$1) +$(host_arch)_$(host_os)_$1?=$$($(host_os)_$1) +$(host_arch)_$(host_os)_$(release_type)_$1?=$$($(host_os)_$1) +else +$(host_os)_$1=$(or $($1),$($(host_os)_$1),$(default_host_$1)) +$(host_arch)_$(host_os)_$1=$(or $($1),$($(host_arch)_$(host_os)_$1),$$($(host_os)_$1)) +$(host_arch)_$(host_os)_$(release_type)_$1=$(or $($1),$($(host_arch)_$(host_os)_$(release_type)_$1),$$($(host_os)_$1)) +endif +host_$1=$$($(host_arch)_$(host_os)_$1) +endef + +define add_host_flags_func +$(host_arch)_$(host_os)_$1 += $($(host_os)_$1) +$(host_arch)_$(host_os)_$(release_type)_$1 += $($(host_os)_$(release_type)_$1) +host_$1 = $$($(host_arch)_$(host_os)_$1) +host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1) +endef + +$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool)))) +$(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags)))) diff --git a/depend/zcash/depends/hosts/freebsd.mk b/depend/zcash/depends/hosts/freebsd.mk new file mode 100644 index 000000000..a8d5c0171 --- /dev/null +++ b/depend/zcash/depends/hosts/freebsd.mk @@ -0,0 +1,20 @@ +freebsd_CFLAGS=-pipe +freebsd_CXXFLAGS=$(freebsd_CFLAGS) + +freebsd_release_CFLAGS=-O3 +freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS) + +freebsd_debug_CFLAGS=-O0 +freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS) + +freebsd_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + +# Changes below have not been tested. If you try to build on FreeBSD, +# please let us know how it goes. + +freebsd_LDFLAGS?=-fuse-ld=lld + +i686_freebsd_CC=$(default_host_CC) -m32 +i686_freebsd_CXX=$(default_host_CXX) -m32 +x86_64_freebsd_CC=$(default_host_CC) -m64 +x86_64_freebsd_CXX=$(default_host_CXX) -m64 diff --git a/depend/zcash/depends/hosts/linux.mk b/depend/zcash/depends/hosts/linux.mk new file mode 100644 index 000000000..160bdbb91 --- /dev/null +++ b/depend/zcash/depends/hosts/linux.mk @@ -0,0 +1,25 @@ +linux_CFLAGS=-pipe +linux_CXXFLAGS=$(linux_CFLAGS) + +linux_release_CFLAGS=-O3 +linux_release_CXXFLAGS=$(linux_release_CFLAGS) + +linux_debug_CFLAGS=-O0 +linux_debug_CXXFLAGS=$(linux_debug_CFLAGS) + +linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + +linux_LDFLAGS?=-fuse-ld=lld + +i686_linux_CC=$(default_host_CC) -m32 +i686_linux_CXX=$(default_host_CXX) -m32 +x86_64_linux_CC=$(default_host_CC) -m64 +x86_64_linux_CXX=$(default_host_CXX) -m64 + +# Clang doesn't appear to find these multilib paths by default, +# so help it out if we are cross-compiling. +ifneq ($(canonical_host),$(build)) + # CFLAGS is copied to CXXFLAGS after it is fully-evaluated. + linux_CFLAGS += -idirafter /usr/$(host)/include + linux_LDFLAGS += -L/usr/$(host)/lib +endif diff --git a/depend/zcash/depends/hosts/mingw32.mk b/depend/zcash/depends/hosts/mingw32.mk new file mode 100644 index 000000000..e48546cce --- /dev/null +++ b/depend/zcash/depends/hosts/mingw32.mk @@ -0,0 +1,12 @@ +mingw32_CFLAGS=-pipe +mingw32_CXXFLAGS=$(mingw32_CFLAGS) -isystem $(host_prefix)/include/c++/v1 + +mingw32_LDFLAGS?=-fuse-ld=lld + +mingw32_release_CFLAGS=-O3 +mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS) + +mingw32_debug_CFLAGS=-O0 +mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) + +mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC diff --git a/depend/zcash/depends/packages.md b/depend/zcash/depends/packages.md new file mode 100644 index 000000000..14bb8f3d9 --- /dev/null +++ b/depend/zcash/depends/packages.md @@ -0,0 +1,186 @@ +Each recipe consists of 3 main parts: defining identifiers, setting build +variables, and defining build commands. + +The package "mylib" will be used here as an example + +General tips: +- mylib_foo is written as $(package)_foo in order to make recipes more similar. +- Secondary dependency packages relative to the Zcash binaries/libraries (i.e. + those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) should + be built statically. See [below](#secondary-dependencies) for more details. + +## Identifiers +Each package is required to define at least these variables: + + $(package)_version: + Version of the upstream library or program. If there is no version, a + placeholder such as 1.0 can be used. + + $(package)_download_path: + Location of the upstream source, without the file-name. Usually http, https + or ftp. Secure transmission options like https should be preferred if + available. + + $(package)_file_name: + The upstream source filename available at the download path. + + $(package)_sha256_hash: + The sha256 hash of the upstream file + +These variables are optional: + + $(package)_build_subdir: + cd to this dir before running configure/build/stage commands. + + $(package)_download_file: + The file-name of the upstream source if it differs from how it should be + stored locally. This can be used to avoid storing file-names with strange + characters. + + $(package)_dependencies: + Names of any other packages that this one depends on. + + $(package)_patches: + Filenames of any patches needed to build the package + + $(package)_extra_sources: + Any extra files that will be fetched via $(package)_fetch_cmds. These are + specified so that they can be fetched and verified via 'make download'. + + +## Build Variables: +After defining the main identifiers, build variables may be added or customized +before running the build commands. They should be added to a function called +$(package)_set_vars. For example: + + define $(package)_set_vars + ... + endef + +Most variables can be prefixed with the host, architecture, or both, to make +the modifications specific to that case. For example: + + Universal: $(package)_cc=gcc + Linux only: $(package)_linux_cc=gcc + x86_64 only: $(package)_x86_64_cc = gcc + x86_64 linux only: $(package)_x86_64_linux_cc = gcc + +These variables may be set to override or append their default values. + + $(package)_cc + $(package)_cxx + $(package)_objc + $(package)_objcxx + $(package)_ar + $(package)_ranlib + $(package)_libtool + $(package)_nm + $(package)_cflags + $(package)_cxxflags + $(package)_ldflags + $(package)_cppflags + $(package)_config_env + $(package)_build_env + $(package)_stage_env + $(package)_build_opts + $(package)_config_opts + +The *_env variables are used to add environment variables to the respective +commands. + +Many variables respect a debug/release suffix as well, in order to use them for +only the appropriate build config. For example: + + $(package)_cflags_release = -O3 + $(package)_cflags_i686_debug = -g + $(package)_config_opts_release = --disable-debug + +These will be used in addition to the options that do not specify +debug/release. All builds are considered to be release unless DEBUG=1 is set by +the user. Other variables may be defined as needed. + +## Build commands: + + For each build, a unique build dir and staging dir are created. For example, + `work/build/mylib/1.0-1adac830f6e` and `work/staging/mylib/1.0-1adac830f6e`. + + The following build commands are available for each recipe: + + $(package)_fetch_cmds: + Runs from: build dir + Fetch the source file. If undefined, it will be fetched and verified + against its hash. + + $(package)_extract_cmds: + Runs from: build dir + Verify the source file against its hash and extract it. If undefined, the + source is assumed to be a tarball. + + $(package)_preprocess_cmds: + Runs from: build dir/$(package)_build_subdir + Preprocess the source as necessary. If undefined, does nothing. + + $(package)_config_cmds: + Runs from: build dir/$(package)_build_subdir + Configure the source. If undefined, does nothing. + + $(package)_build_cmds: + Runs from: build dir/$(package)_build_subdir + Build the source. If undefined, does nothing. + + $(package)_stage_cmds: + Runs from: build dir/$(package)_build_subdir + Stage the build results. If undefined, does nothing. + + The following variables are available for each recipe: + + $(1)_staging_dir: package's destination sysroot path + $(1)_staging_prefix_dir: prefix path inside of the package's staging dir + $(1)_extract_dir: path to the package's extracted sources + $(1)_build_dir: path where configure/build/stage commands will be run + $(1)_patch_dir: path where the package's patches (if any) are found + +Notes on build commands: + +For packages built with autotools, $($(package)_autoconf) can be used in the +configure step to (usually) correctly configure automatically. Any +$($(package)_config_opts) will be appended. + +Most autotools projects can be properly staged using: + + $(MAKE) DESTDIR=$($(package)_staging_dir) install + +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + +## Secondary dependencies: + +Secondary dependency packages relative to the Zcash binaries/libraries (i.e. +those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) +should be built statically. The arguments for statically linking secondary +dependencies are similar to those for primary dependencies: it is preferable +for promptness of security updates; consensus compatibility; ease of +debugging and reproduction of user issues; avoiding unintended breakage +due to incompatible changes; and portability across OS distributions. It also +improves general build reliability as illustrated by the following example: + +When linking an executable against a shared library `libprimary` that has its +own shared dependency `libsecondary`, we may need to specify the path to +`libsecondary` on the link command using the `-rpath/-rpath-link` options, it is +not sufficient to just say `libprimary`. + +For us, it's much easier to just link a static `libsecondary` into a shared +`libprimary`. Especially because in our case, we are linking against a dummy +`libprimary` anyway that we'll throw away. We don't care if the end-user has a +static or dynamic `libseconday`, that's not our concern. With a static +`libseconday`, when we need to link `libprimary` into our executable, there's no +dependency chain to worry about as `libprimary` has all the symbols. diff --git a/depend/zcash/depends/packages/bdb.mk b/depend/zcash/depends/packages/bdb.mk new file mode 100644 index 000000000..350816eeb --- /dev/null +++ b/depend/zcash/depends/packages/bdb.mk @@ -0,0 +1,53 @@ +package=bdb +$(package)_version=6.2.23 +$(package)_download_path=https://download.oracle.com/berkeley-db +$(package)_file_name=db-$($(package)_version).tar.gz +$(package)_sha256_hash=47612c8991aa9ac2f6be721267c8d3cdccf5ac83105df8e50809daea24e95dc7 +$(package)_build_subdir=build_unix +$(package)_patches=clang-12-stpcpy-issue.diff winioctl-and-atomic_init_db.patch + +ifneq ($(host_os),darwin) +$(package)_dependencies=libcxx +endif + +define $(package)_set_vars +$(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking +$(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++17 + +ifeq ($(host_os),freebsd) + $(package)_ldflags+=-static-libstdc++ -lcxxrt +else + $(package)_ldflags+=-static-libstdc++ -lc++abi +endif + +endef + +define $(package)_preprocess_cmds + patch -p1 <$($(package)_patch_dir)/clang-12-stpcpy-issue.diff && \ + patch -p1 <$($(package)_patch_dir)/winioctl-and-atomic_init_db.patch +endef + +define $(package)_config_cmds + ../dist/$($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) libdb_cxx-6.2.a libdb-6.2.a +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + cd $(BASEDIR)/../zcutil && \ + mkdir -p bin && \ + mv -f $($(package)_staging_dir)$(host_prefix)/bin/db_* bin +endef diff --git a/depend/zcash/depends/packages/boost.mk b/depend/zcash/depends/packages/boost.mk new file mode 100644 index 000000000..d94be2d67 --- /dev/null +++ b/depend/zcash/depends/packages/boost.mk @@ -0,0 +1,66 @@ +package=boost +$(package)_version=1_79_0 +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ +$(package)_file_name=boost_$($(package)_version).tar.bz2 +$(package)_sha256_hash=475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 +$(package)_dependencies=native_b2 + +ifneq ($(host_os),darwin) +$(package)_dependencies+=libcxx +endif + +define $(package)_set_vars +$(package)_config_opts_release=variant=release +$(package)_config_opts_debug=variant=debug +$(package)_config_opts=--layout=system --user-config=user-config.jam +$(package)_config_opts+=threading=multi link=static -sNO_COMPRESSION=1 +$(package)_config_opts_linux=target-os=linux threadapi=pthread runtime-link=shared +$(package)_config_opts_freebsd=cxxflags=-fPIC +$(package)_config_opts_darwin=target-os=darwin runtime-link=shared +$(package)_config_opts_mingw32=target-os=windows binary-format=pe threadapi=win32 runtime-link=static +$(package)_config_opts_x86_64=architecture=x86 address-model=64 +$(package)_config_opts_i686=architecture=x86 address-model=32 +$(package)_config_opts_aarch64=address-model=64 +$(package)_config_opts_armv7a=address-model=32 +ifneq (,$(findstring clang,$($(package)_cxx))) +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc +endif +$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test +$(package)_cxxflags+=-std=c++17 -fvisibility=hidden +$(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_freebsd=-fPIC + +ifeq ($(host_os),freebsd) + $(package)_ldflags+=-static-libstdc++ -lcxxrt +else + $(package)_ldflags+=-static-libstdc++ -lc++abi +endif + +endef + +define $(package)_preprocess_cmds + echo "using $($(package)_toolset_$(host_os)) : : $($(package)_cxx) : \"$($(package)_cflags)\" \"$($(package)_cxxflags)\" \"$($(package)_cppflags)\" \"$($(package)_ldflags)\" \"$($(package)_ar)\" \"$(host_STRIP)\" \"$(host_RANLIB)\" \"$(host_WINDRES)\" : ;" > user-config.jam +endef + +define $(package)_config_cmds + ./bootstrap.sh --without-icu --with-libraries=$($(package)_config_libraries) --with-toolset=$($(package)_toolset_$(host_os)) --with-bjam=b2 +endef + +define $(package)_build_cmds + b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) stage +endef + +define $(package)_stage_cmds + b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install +endef + +# Boost uses the MSVC convention of libboost_foo.lib as the naming pattern when +# compiling for Windows, even though we use MinGW which follows the libfoo.a +# convention. This causes issues with lld, so we rename all .lib files to .a. +ifeq ($(host_os),mingw32) +define $(package)_postprocess_cmds + for f in lib/*.lib; do mv -- "$$$$f" "$$$${f%.lib}.a"; done +endef +endif diff --git a/depend/zcash/depends/packages/googletest.mk b/depend/zcash/depends/packages/googletest.mk new file mode 100644 index 000000000..51c49e311 --- /dev/null +++ b/depend/zcash/depends/packages/googletest.mk @@ -0,0 +1,36 @@ +package=googletest +$(package)_version=1.8.1 +$(package)_download_path=https://github.com/google/$(package)/archive/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_download_file=release-$($(package)_version).tar.gz +$(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c + +ifneq ($(host_os),darwin) +$(package)_dependencies=libcxx +endif + +define $(package)_set_vars +$(package)_cxxflags+=-std=c++17 +$(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_freebsd=-fPIC + +ifeq ($(host_os),freebsd) + $(package)_ldflags+=-static-libstdc++ -lcxxrt +else + $(package)_ldflags+=-static-libstdc++ -lc++abi +endif + +endef + +define $(package)_build_cmds + $(MAKE) -C googlemock/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gmock.a && \ + $($(package)_build_env) $(MAKE) -C googletest/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gtest.a +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \ + install ./googlemock/make/gmock.a $($(package)_staging_dir)$(host_prefix)/lib/libgmock.a && \ + install ./googletest/make/gtest.a $($(package)_staging_dir)$(host_prefix)/lib/libgtest.a && \ + cp -a ./googlemock/include $($(package)_staging_dir)$(host_prefix)/ && \ + cp -a ./googletest/include $($(package)_staging_dir)$(host_prefix)/ +endef diff --git a/depend/zcash/depends/packages/libcxx.mk b/depend/zcash/depends/packages/libcxx.mk new file mode 100644 index 000000000..bbadd228e --- /dev/null +++ b/depend/zcash/depends/packages/libcxx.mk @@ -0,0 +1,75 @@ +package=libcxx +$(package)_version=$(native_clang_version) + +ifneq ($(canonical_host),$(build)) +ifneq ($(host_os),mingw32) +# Clang is provided pre-compiled for a bunch of targets; fetch the one we need +# and stage its copies of the static libraries. +$(package)_download_path=$(native_clang_download_path) +$(package)_download_file_aarch64_linux=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_file_name_aarch64_linux=clang-llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_sha256_hash_aarch64_linux=15ff2db12683e69e552b6668f7ca49edaa01ce32cb1cbc8f8ed2e887ab291069 +$(package)_download_file_linux=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz +$(package)_file_name_linux=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz +$(package)_sha256_hash_linux=84a54c69781ad90615d1b0276a83ff87daaeded99fbc64457c350679df7b4ff0 + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib && \ + cp lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ + cp lib/libc++abi.a $($(package)_staging_prefix_dir)/lib +endef + +else +# For Windows cross-compilation, use the MSYS2 binaries. +# Using 13.0.0-3 because 13.0.1-1 has missing `new` and `delete` symbols. +$(package)_download_path=https://repo.msys2.org/mingw/x86_64 +$(package)_download_file=mingw-w64-x86_64-libc++-13.0.0-3-any.pkg.tar.zst +$(package)_file_name=mingw-w64-x86_64-libcxx-13.0.0-3-any.pkg.tar.zst +$(package)_sha256_hash=0f8819e88273579f7c9262456c6b8f4d73e1693095c2364d1192c61c5f6a1a4f + +$(package)_libcxxabi_download_file=mingw-w64-x86_64-libc++abi-13.0.0-3-any.pkg.tar.zst +$(package)_libcxxabi_file_name=mingw-w64-x86_64-libcxxabi-13.0.0-3-any.pkg.tar.zst +$(package)_libcxxabi_sha256_hash=7224a7252a566938afe91ea8f130682abd29b10e13c9a3c2347af523ca0d7c42 + +$(package)_extra_sources += $($(package)_libcxxabi_file_name) + +define $(package)_fetch_cmds +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_libcxxabi_download_file),$($(package)_libcxxabi_file_name),$($(package)_libcxxabi_sha256_hash)) +endef + +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_libcxxabi_sha256_hash) $($(package)_source_dir)/$($(package)_libcxxabi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + mkdir -p libcxxabi && \ + tar --no-same-owner --strip-components=1 -C libcxxabi -xf $($(package)_source_dir)/$($(package)_libcxxabi_file_name) && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib && \ + mv include/ $($(package)_staging_prefix_dir) && \ + cp lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ + cp libcxxabi/lib/libc++abi.a $($(package)_staging_prefix_dir)/lib +endef +endif + +else +# For native compilation, use the static libraries from native_clang. +# We explicitly stage them so that subsequent dependencies don't link to the +# shared libraries distributed with Clang. +define $(package)_fetch_cmds +endef + +define $(package)_extract_cmds +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib && \ + cp $(build_prefix)/lib/libc++.a $($(package)_staging_prefix_dir)/lib && \ + if [ -f "$(build_prefix)/lib/libc++abi.a" ]; then cp $(build_prefix)/lib/libc++abi.a $($(package)_staging_prefix_dir)/lib; fi +endef + +endif diff --git a/depend/zcash/depends/packages/libevent.mk b/depend/zcash/depends/packages/libevent.mk new file mode 100644 index 000000000..1f1c305aa --- /dev/null +++ b/depend/zcash/depends/packages/libevent.mk @@ -0,0 +1,40 @@ +package=libevent +$(package)_version=2.1.12 +$(package)_download_path=https://github.com/libevent/libevent/archive/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_download_file=release-$($(package)_version)-stable.tar.gz +$(package)_sha256_hash=7180a979aaa7000e1264da484f712d403fcf7679b1e9212c4e3d09f5c93efc24 +$(package)_patches=0001-fix-windows-getaddrinfo.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/0001-fix-windows-getaddrinfo.patch && \ + ./autogen.sh +endef + +# When building for Windows, we set _WIN32_WINNT to target the same Windows +# version as we do in configure. Due to quirks in libevents build system, this +# is also required to enable support for ipv6. See #19375. +define $(package)_set_vars + $(package)_config_opts=--disable-shared --disable-openssl --disable-libevent-regress + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking + $(package)_config_opts_release=--disable-debug-mode + $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic + $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depend/zcash/depends/packages/libsodium.mk b/depend/zcash/depends/packages/libsodium.mk new file mode 100644 index 000000000..332072577 --- /dev/null +++ b/depend/zcash/depends/packages/libsodium.mk @@ -0,0 +1,26 @@ +package=libsodium +$(package)_version=1.0.18 +$(package)_download_path=https://download.libsodium.org/libsodium/releases/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1 +$(package)_dependencies= +$(package)_patches=1.0.15-pubkey-validation.diff 1.0.15-signature-validation.diff +$(package)_config_opts= + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/1.0.15-pubkey-validation.diff && \ + patch -p1 < $($(package)_patch_dir)/1.0.15-signature-validation.diff && \ + cd $($(package)_build_subdir); DO_NOT_UPDATE_CONFIG_SCRIPTS=1 ./autogen.sh +endef + +define $(package)_config_cmds + $($(package)_autoconf) --enable-static --disable-shared +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depend/zcash/depends/packages/native_b2.mk b/depend/zcash/depends/packages/native_b2.mk new file mode 100644 index 000000000..aaa37cdcf --- /dev/null +++ b/depend/zcash/depends/packages/native_b2.mk @@ -0,0 +1,20 @@ +package=native_b2 +$(package)_version=$(boost_version) +$(package)_download_path=$(boost_download_path) +$(package)_file_name=$(boost_file_name) +$(package)_sha256_hash=$(boost_sha256_hash) +$(package)_build_subdir=tools/build/src/engine +ifneq (,$(findstring clang,$($(package)_cxx))) +$(package)_toolset_$(host_os)=clang +else +$(package)_toolset_$(host_os)=gcc +endif + +define $(package)_build_cmds + CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)" ./build.sh "$($(package)_toolset_$(host_os))" +endef + +define $(package)_stage_cmds + mkdir -p "$($(package)_staging_prefix_dir)"/bin/ && \ + cp b2 "$($(package)_staging_prefix_dir)"/bin/ +endef diff --git a/depend/zcash/depends/packages/native_ccache.mk b/depend/zcash/depends/packages/native_ccache.mk new file mode 100644 index 000000000..4c5dde76d --- /dev/null +++ b/depend/zcash/depends/packages/native_ccache.mk @@ -0,0 +1,25 @@ +package=native_ccache +$(package)_version=3.7.12 +$(package)_download_path=https://github.com/ccache/ccache/releases/download/v$($(package)_version) +$(package)_file_name=ccache-$($(package)_version).tar.gz +$(package)_sha256_hash=d2abe88d4c283ce960e233583061127b156ffb027c6da3cf10770fc0c7244194 + +define $(package)_set_vars +$(package)_config_opts= +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf lib include +endef diff --git a/depend/zcash/depends/packages/native_cctools.mk b/depend/zcash/depends/packages/native_cctools.mk new file mode 100644 index 000000000..5febaa3b9 --- /dev/null +++ b/depend/zcash/depends/packages/native_cctools.mk @@ -0,0 +1,62 @@ +package=native_cctools +$(package)_version=55562e4073dea0fbfd0b20e0bf69ffe6390c7f97 +$(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 +$(package)_build_subdir=cctools +$(package)_dependencies=native_clang +$(package)_patches=ignore-otool.diff + +$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef +$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz +$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 + +$(package)_extra_sources += $($(package)_libtapi_file_name) + +define $(package)_fetch_cmds +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ +$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) +endef + +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + mkdir -p libtapi && \ + tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ + tar --no-same-owner --strip-components=1 -xf $($(package)_source) +endef + +define $(package)_set_vars + $(package)_config_opts=--target=$(host) --with-libtapi=$($(package)_extract_dir) + $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$(build_prefix)/bin/llvm-config + $(package)_cc=$(build_prefix)/bin/clang + $(package)_cxx=$(build_prefix)/bin/clang++ +endef + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/ignore-otool.diff && \ + cd $($(package)_build_subdir); DO_NOT_UPDATE_CONFIG_SCRIPTS=1 ./autogen.sh +endef + +define $(package)_config_cmds + rm -f $(build_prefix)/lib/libc++abi.so* && \ + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ../libtapi/build.sh && \ + CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ../libtapi/install.sh && \ + $($(package)_config_env) $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ + mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ + cd $($(package)_extract_dir) && \ + cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ +endef diff --git a/depend/zcash/depends/packages/native_clang.mk b/depend/zcash/depends/packages/native_clang.mk new file mode 100644 index 000000000..662e088eb --- /dev/null +++ b/depend/zcash/depends/packages/native_clang.mk @@ -0,0 +1,51 @@ +package=native_clang +$(package)_major_version=13 +$(package)_version=13.0.1 +$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_path_linux=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_file_linux=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz +$(package)_file_name_linux=clang-llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-18.04.tar.xz +$(package)_sha256_hash_linux=84a54c69781ad90615d1b0276a83ff87daaeded99fbc64457c350679df7b4ff0 +$(package)_download_path_darwin=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_file_darwin=clang+llvm-$($(package)_version)-x86_64-apple-darwin.tar.xz +$(package)_file_name_darwin=clang-llvm-$($(package)_version)-x86_64-apple-darwin.tar.xz +$(package)_sha256_hash_darwin=dec02d17698514d0fc7ace8869c38937851c542b02adf102c4e898f027145a4d +$(package)_download_path_freebsd=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_file_freebsd=clang+llvm-$($(package)_version)-amd64-unknown-freebsd12.tar.xz +$(package)_file_name_freebsd=clang-llvm-$($(package)_version)-amd64-unknown-freebsd12.tar.xz +$(package)_sha256_hash_freebsd=8101c8d3a920bf930b33987ada5373f43537c5de8c194be0ea10530fd0ad5617 +$(package)_download_file_aarch64_linux=clang+llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_file_name_aarch64_linux=clang-llvm-$($(package)_version)-aarch64-linux-gnu.tar.xz +$(package)_sha256_hash_aarch64_linux=15ff2db12683e69e552b6668f7ca49edaa01ce32cb1cbc8f8ed2e887ab291069 + +ifneq (,$(wildcard /etc/arch-release)) +$(package)_dependencies=native_libtinfo +endif + +# Ensure we have clang native to the builder, not the target host +ifneq ($(canonical_host),$(build)) +$(package)_exact_download_path=$($(package)_download_path_$(build_os)) +$(package)_exact_download_file=$($(package)_download_file_$(build_os)) +$(package)_exact_file_name=$($(package)_file_name_$(build_os)) +$(package)_exact_sha256_hash=$($(package)_sha256_hash_$(build_os)) +endif + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/bin && \ + cp bin/clang-$($(package)_major_version) $($(package)_staging_prefix_dir)/bin && \ + cp bin/lld $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-ar $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-config $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-nm $($(package)_staging_prefix_dir)/bin && \ + cp bin/llvm-objcopy $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/clang $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/ld.lld $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/ld64.lld $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/lld-link $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/llvm-ranlib $($(package)_staging_prefix_dir)/bin && \ + cp -P bin/llvm-strip $($(package)_staging_prefix_dir)/bin && \ + mv include/ $($(package)_staging_prefix_dir) && \ + mv lib/ $($(package)_staging_prefix_dir) && \ + mv libexec/ $($(package)_staging_prefix_dir) +endef diff --git a/depend/zcash/depends/packages/native_libtinfo.mk b/depend/zcash/depends/packages/native_libtinfo.mk new file mode 100644 index 000000000..d3c200660 --- /dev/null +++ b/depend/zcash/depends/packages/native_libtinfo.mk @@ -0,0 +1,22 @@ +package=native_tinfo +$(package)_version=5.6.0 +$(package)_download_path_linux=http://ftp.debian.org/debian/pool/main/n/ncurses/ +$(package)_download_file_linux=libtinfo5_6.0+20161126-1+deb9u2_amd64.deb +$(package)_file_name_linux=libtinfo5_6.0+20161126-1+deb9u2_amd64.deb +$(package)_sha256_hash_linux=1d249a3193568b5ef785ad8993b9ba6d6fdca0eb359204c2355532b82d25e9f5 + +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ + mkdir -p libtinfo5 && \ + ar x --output libtinfo5 $($(package)_source_dir)/$($(package)_file_name) && \ + cd libtinfo5 && \ + tar xf data.tar.xz +endef + +define $(package)_stage_cmds + pwd && \ + mkdir -p $($(package)_staging_prefix_dir)/lib && \ + cp libtinfo5/lib/x86_64-linux-gnu/libtinfo.so.5.9 $($(package)_staging_prefix_dir)/lib/libtinfo.so.5 +endef diff --git a/depend/zcash/depends/packages/native_rust.mk b/depend/zcash/depends/packages/native_rust.mk new file mode 100644 index 000000000..a1901a8fe --- /dev/null +++ b/depend/zcash/depends/packages/native_rust.mk @@ -0,0 +1,61 @@ +package=native_rust +$(package)_version=1.59.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=0c1c2da3fa26372e5178123aa5bb0fdcd4933fbad9bfb268ffbd71807182ecae +$(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash_darwin=d82204f536af0c7bfd2ea2213dc46b99911860cfc5517f7321244412ae96f159 +$(package)_file_name_freebsd=rust-$($(package)_version)-x86_64-unknown-freebsd.tar.gz +$(package)_sha256_hash_freebsd=83f9c49b6e9025b712fc5d65e49f1b6ad959966534cd39c8dc2ce2c85a6ca484 +$(package)_file_name_aarch64_linux=rust-$($(package)_version)-aarch64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_aarch64_linux=ab5da30a3de5433e26cbc74c56b9d97b569769fc2e456fc54378adc8baaee4f0 + +# 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-pc-linux-gnu=x86_64-unknown-linux-gnu +$(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=81dbd37919f631f962ac0798111803eb8f06ffde608f0e5dd3682d701cf5566d +$(package)_rust_std_sha256_hash_x86_64-apple-darwin=959af8bafbc9f3916a1d1111d7378fdd7aa459410cdd2d3bbfc2d9d9a6db0683 +$(package)_rust_std_sha256_hash_x86_64-pc-windows-gnu=9a67ae84e9e75efb57eeeab617e32379a555de336a30bb74a476e575cd38f63a +$(package)_rust_std_sha256_hash_x86_64-unknown-freebsd=cf5e4303dd7c3b70a738a2336097c9f2189c8b702a89a8c453d83ac0dee4602c + +define rust_target +$(if $($(1)_rust_target_$(2)),$($(1)_rust_target_$(2)),$(if $(findstring darwin,$(3)),x86_64-apple-darwin,$(if $(findstring freebsd,$(3)),x86_64-unknown-freebsd,$(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)) + +define $(package)_fetch_cmds +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ +$(call fetch_file,$(package),$($(package)_download_path),$($(package)_file_name_$(build_os)),$($(package)_file_name_$(build_os)),$($(package)_sha256_hash_$(build_os))) +endef + +define $(package)_extract_cmds + mkdir -p $($(package)_extract_dir) && \ + 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 $(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 + bash ./install.sh --without=rust-docs --destdir=$($(package)_staging_dir) --prefix=$(build_prefix) --disable-ldconfig && \ + ../$(canonical_host)/install.sh --destdir=$($(package)_staging_dir) --prefix=$(build_prefix) --disable-ldconfig +endef +else + +define $(package)_stage_cmds + bash ./install.sh --without=rust-docs --destdir=$($(package)_staging_dir) --prefix=$(build_prefix) --disable-ldconfig +endef +endif diff --git a/depend/zcash/depends/packages/packages.mk b/depend/zcash/depends/packages/packages.mk new file mode 100644 index 000000000..2d85c3226 --- /dev/null +++ b/depend/zcash/depends/packages/packages.mk @@ -0,0 +1,20 @@ +zcash_packages := libsodium utfcpp +packages := boost libevent zeromq $(zcash_packages) googletest +native_packages := native_clang native_ccache native_rust + +ifneq (,$(wildcard /etc/arch-release)) +native_packages += native_libtinfo +endif + +wallet_packages=bdb + +$(host_arch)_$(host_os)_native_packages += native_b2 + +ifneq ($(build_os),darwin) +darwin_native_packages=native_cctools +endif + +# We use a complete SDK for Darwin, which includes libc++. +ifneq ($(host_os),darwin) +packages += libcxx +endif diff --git a/depend/zcash/depends/packages/utfcpp.mk b/depend/zcash/depends/packages/utfcpp.mk new file mode 100644 index 000000000..2a0620e21 --- /dev/null +++ b/depend/zcash/depends/packages/utfcpp.mk @@ -0,0 +1,10 @@ +package=utfcpp +$(package)_version=3.2.1 +$(package)_download_path=https://github.com/nemtrif/$(package)/archive/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_download_file=v$($(package)_version).tar.gz +$(package)_sha256_hash=8d6aa7d77ad0abb35bb6139cb9a33597ac4c5b33da6a004ae42429b8598c9605 + +define $(package)_stage_cmds + cp -a ./source $($(package)_staging_dir)$(host_prefix)/include +endef diff --git a/depend/zcash/depends/packages/zeromq.mk b/depend/zcash/depends/packages/zeromq.mk new file mode 100644 index 000000000..c067cfa32 --- /dev/null +++ b/depend/zcash/depends/packages/zeromq.mk @@ -0,0 +1,47 @@ +package=zeromq +$(package)_version=4.3.4 +$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5 +$(package)_patches=windows-unused-variables.diff + +ifneq ($(host_os),darwin) +$(package)_dependencies=libcxx +endif + +define $(package)_set_vars + $(package)_config_opts=--without-docs --disable-shared --disable-curve --disable-curve-keygen --disable-perf + $(package)_config_opts += --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci + $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking + $(package)_config_opts += --disable-drafts --enable-option-checking + $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic + $(package)_cxxflags+=-std=c++17 + + ifeq ($(host_os),freebsd) + $(package)_ldflags+=-static-libstdc++ -lcxxrt + else + $(package)_ldflags+=-static-libstdc++ -lc++abi + endif + +endef + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/windows-unused-variables.diff +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) src/libzmq.la +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-includeHEADERS install-pkgconfigDATA +endef + +define $(package)_postprocess_cmds + rm -rf bin share lib/*.la +endef diff --git a/depend/zcash/depends/patches/bdb/clang-12-stpcpy-issue.diff b/depend/zcash/depends/patches/bdb/clang-12-stpcpy-issue.diff new file mode 100644 index 000000000..671938e0b --- /dev/null +++ b/depend/zcash/depends/patches/bdb/clang-12-stpcpy-issue.diff @@ -0,0 +1,17 @@ +diff -ur db-6.2.23-orig/src/blob/blob_util.c db-6.2.23/src/blob/blob_util.c +--- db-6.2.23-orig/src/blob/blob_util.c 2016-03-28 20:45:53.000000000 +0100 ++++ db-6.2.23/src/blob/blob_util.c 2021-07-30 19:52:37.082811600 +0100 +@@ -544,7 +544,12 @@ + goto err; + + memset(path, 0, len); +- name_len += sprintf(path, "%s", blob_sub_dir); ++ // Clang 12 introduced an "libcall optimization" that lowers the above ++ // to stpcpy to avoid the machinery involved in parsing format strings. ++ // This causes build problems when cross-compiling to Windows with the ++ // version of mingw-w64 that Zcash supports. We haven't figured out why ++ // but in the meantime using "%s%s" inhibits the optimization. ++ name_len += sprintf(path, "%s%s", blob_sub_dir, ""); + + __blob_calculate_dirs(blob_id, path, &name_len, &depth); + diff --git a/depend/zcash/depends/patches/bdb/winioctl-and-atomic_init_db.patch b/depend/zcash/depends/patches/bdb/winioctl-and-atomic_init_db.patch new file mode 100644 index 000000000..788da5be4 --- /dev/null +++ b/depend/zcash/depends/patches/bdb/winioctl-and-atomic_init_db.patch @@ -0,0 +1,136 @@ +diff --git a/src/dbinc/atomic.h b/src/dbinc/atomic.h +index e4420aa..4799b5f 100644 +--- a/src/dbinc/atomic.h ++++ b/src/dbinc/atomic.h +@@ -70,7 +70,7 @@ typedef struct { + * These have no memory barriers; the caller must include them when necessary. + */ + #define atomic_read(p) ((p)->value) +-#define atomic_init(p, val) ((p)->value = (val)) ++#define atomic_init_db(p, val) ((p)->value = (val)) + + #ifdef HAVE_ATOMIC_SUPPORT + +@@ -225,7 +225,7 @@ static inline int __atomic_compare_exchange_int( + #define atomic_dec(env, p) (--(p)->value) + #define atomic_compare_exchange(env, p, oldval, newval) \ + (DB_ASSERT(env, atomic_read(p) == (oldval)), \ +- atomic_init(p, (newval)), 1) ++ atomic_init_db(p, (newval)), 1) + #else + #define atomic_inc(env, p) __atomic_inc_int(env, p) + #define atomic_dec(env, p) __atomic_dec_int(env, p) +diff --git a/src/dbinc/win_db.h b/src/dbinc/win_db.h +index f5228f4..6e44659 100644 +--- a/src/dbinc/win_db.h ++++ b/src/dbinc/win_db.h +@@ -51,7 +51,7 @@ + #include + #include + #ifndef DB_WINCE +-#include ++#include + #endif + + #ifdef HAVE_GETADDRINFO +diff --git a/src/mp/mp_fget.c b/src/mp/mp_fget.c +index 59fe9fe..fa4ced7 100644 +--- a/src/mp/mp_fget.c ++++ b/src/mp/mp_fget.c +@@ -654,7 +654,7 @@ alloc: /* Allocate a new buffer header and data space. */ + + /* Initialize enough so we can call __memp_bhfree. */ + alloc_bhp->flags = 0; +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + #ifdef DIAGNOSTIC + if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) { + __db_errx(env, DB_STR("3025", +@@ -969,7 +969,7 @@ alloc: /* Allocate a new buffer header and data space. */ + MVCC_MPROTECT(bhp->buf, mfp->pagesize, + PROT_READ); + +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + MUTEX_LOCK(env, alloc_bhp->mtx_buf); + alloc_bhp->priority = bhp->priority; + alloc_bhp->pgno = bhp->pgno; +diff --git a/src/mp/mp_mvcc.c b/src/mp/mp_mvcc.c +index 83c4d72..0a47202 100644 +--- a/src/mp/mp_mvcc.c ++++ b/src/mp/mp_mvcc.c +@@ -281,7 +281,7 @@ __memp_bh_freeze(dbmp, infop, hp, bhp, need_frozenp) + #else + memcpy(frozen_bhp, bhp, SSZA(BH, buf)); + #endif +- atomic_init(&frozen_bhp->ref, 0); ++ atomic_init_db(&frozen_bhp->ref, 0); + if (mutex != MUTEX_INVALID) + frozen_bhp->mtx_buf = mutex; + else if ((ret = __mutex_alloc(env, MTX_MPOOL_BH, +@@ -440,7 +440,7 @@ __memp_bh_thaw(dbmp, infop, hp, frozen_bhp, alloc_bhp) + #endif + alloc_bhp->mtx_buf = mutex; + MUTEX_LOCK(env, alloc_bhp->mtx_buf); +- atomic_init(&alloc_bhp->ref, 1); ++ atomic_init_db(&alloc_bhp->ref, 1); + F_CLR(alloc_bhp, BH_FROZEN); + } + +diff --git a/src/mp/mp_region.c b/src/mp/mp_region.c +index 4d95e4f..e97459c 100644 +--- a/src/mp/mp_region.c ++++ b/src/mp/mp_region.c +@@ -278,7 +278,7 @@ __memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg) + MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0) + return (ret); + SH_TAILQ_INIT(&htab[i].hash_bucket); +- atomic_init(&htab[i].hash_page_dirty, 0); ++ atomic_init_db(&htab[i].hash_page_dirty, 0); + } + + mtx_base = mtx_prev = MUTEX_INVALID; +@@ -332,7 +332,7 @@ no_prealloc: + DB_MUTEX_SHARED, &hp->mtx_hash)) != 0) + return (ret); + SH_TAILQ_INIT(&hp->hash_bucket); +- atomic_init(&hp->hash_page_dirty, 0); ++ atomic_init_db(&hp->hash_page_dirty, 0); + #ifdef HAVE_STATISTICS + hp->hash_io_wait = 0; + hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0; +diff --git a/src/mutex/mut_method.c b/src/mutex/mut_method.c +index 72b34de..a9f9868 100644 +--- a/src/mutex/mut_method.c ++++ b/src/mutex/mut_method.c +@@ -501,7 +501,7 @@ __atomic_compare_exchange_int(env, v, oldval, newval) + MUTEX_LOCK(env, mtx); + ret = atomic_read(v) == oldval; + if (ret) +- atomic_init(v, newval); ++ atomic_init_db(v, newval); + MUTEX_UNLOCK(env, mtx); + + return (ret); +diff --git a/src/mutex/mut_tas.c b/src/mutex/mut_tas.c +index 7899c4b..d9420fa 100644 +--- a/src/mutex/mut_tas.c ++++ b/src/mutex/mut_tas.c +@@ -47,7 +47,7 @@ __db_tas_mutex_init(env, mutex, flags) + + #ifdef HAVE_SHARED_LATCHES + if (F_ISSET(mutexp, DB_MUTEX_SHARED)) +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + else + #endif + if (MUTEX_INIT(&mutexp->tas)) { +@@ -643,7 +643,7 @@ was_not_locked: + F_CLR(mutexp, DB_MUTEX_LOCKED); + /* Flush flag update before zeroing count */ + MEMBAR_EXIT(); +- atomic_init(&mutexp->sharecount, 0); ++ atomic_init_db(&mutexp->sharecount, 0); + } else { + DB_ASSERT(env, sharecount > 0); + MEMBAR_EXIT(); diff --git a/depend/zcash/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depend/zcash/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch new file mode 100644 index 000000000..a98cd90bd --- /dev/null +++ b/depend/zcash/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch @@ -0,0 +1,15 @@ +diff -ur libevent-2.1.8-stable.orig/configure.ac libevent-2.1.8-stable/configure.ac +--- libevent-2.1.8-stable.orig/configure.ac 2017-01-29 17:51:00.000000000 +0000 ++++ libevent-2.1.8-stable/configure.ac 2020-03-07 01:11:16.311335005 +0000 +@@ -389,6 +389,10 @@ + #ifdef HAVE_NETDB_H + #include + #endif ++#ifdef _WIN32 ++#include ++#include ++#endif + ]], + [[ + getaddrinfo; +Only in libevent-2.1.8-stable: configure.ac~ diff --git a/depend/zcash/depends/patches/libsodium/1.0.15-pubkey-validation.diff b/depend/zcash/depends/patches/libsodium/1.0.15-pubkey-validation.diff new file mode 100644 index 000000000..3a9b7ea86 --- /dev/null +++ b/depend/zcash/depends/patches/libsodium/1.0.15-pubkey-validation.diff @@ -0,0 +1,17 @@ +diff -ur libsodium-1.0.18-orig/src/libsodium/crypto_sign/ed25519/ref10/open.c libsodium-1.0.18/src/libsodium/crypto_sign/ed25519/ref10/open.c +--- libsodium-1.0.18-orig/src/libsodium/crypto_sign/ed25519/ref10/open.c 2019-05-18 16:32:11.000000000 -0400 ++++ libsodium-1.0.18/src/libsodium/crypto_sign/ed25519/ref10/open.c 2020-01-21 18:55:22.474233831 -0500 +@@ -32,8 +32,11 @@ + ge25519_has_small_order(sig) != 0) { + return -1; + } +- if (ge25519_is_canonical(pk) == 0 || +- ge25519_has_small_order(pk) != 0) { ++ unsigned char d = 0; ++ for (int i = 0; i < 32; ++i) { ++ d |= pk[i]; ++ } ++ if (d == 0) { + return -1; + } + #endif diff --git a/depend/zcash/depends/patches/libsodium/1.0.15-signature-validation.diff b/depend/zcash/depends/patches/libsodium/1.0.15-signature-validation.diff new file mode 100644 index 000000000..87bae480c --- /dev/null +++ b/depend/zcash/depends/patches/libsodium/1.0.15-signature-validation.diff @@ -0,0 +1,78 @@ +diff -ur libsodium-1.0.18-orig/src/libsodium/crypto_sign/ed25519/ref10/open.c libsodium-1.0.18/src/libsodium/crypto_sign/ed25519/ref10/open.c +--- libsodium-1.0.18-orig/src/libsodium/crypto_sign/ed25519/ref10/open.c 2019-05-18 21:32:11.000000000 +0100 ++++ libsodium-1.0.18/src/libsodium/crypto_sign/ed25519/ref10/open.c 2020-02-18 00:00:08.544107613 +0000 +@@ -10,6 +10,65 @@ + #include "private/ed25519_ref10.h" + #include "utils.h" + ++#ifndef ED25519_COMPAT ++int ++_crypto_sign_ed25519_small_order(const unsigned char p[32]) ++{ ++ CRYPTO_ALIGN(16) ++ static const unsigned char blacklist[][32] = { ++ { 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 }, ++ { 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 }, ++ { 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, ++ 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, ++ 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 }, ++ { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, ++ 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, ++ 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a }, ++ { 0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, ++ 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, ++ 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85 }, ++ { 0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, ++ 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, ++ 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa }, ++ { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, ++ { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, ++ { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, ++ { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, ++ { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, ++ { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } ++ }; ++ size_t i, j; ++ unsigned char c; ++ ++ for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { ++ c = 0; ++ for (j = 0; j < 32; j++) { ++ c |= p[j] ^ blacklist[i][j]; ++ } ++ if (c == 0) { ++ return 1; ++ } ++ } ++ return 0; ++} ++#endif ++ + int + _crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, +@@ -29,7 +88,7 @@ + } + #else + if (sc25519_is_canonical(sig + 32) == 0 || +- ge25519_has_small_order(sig) != 0) { ++ _crypto_sign_ed25519_small_order(sig) != 0) { + return -1; + } + if (ge25519_is_canonical(pk) == 0 || diff --git a/depend/zcash/depends/patches/native_cctools/ignore-otool.diff b/depend/zcash/depends/patches/native_cctools/ignore-otool.diff new file mode 100644 index 000000000..fdb348ede --- /dev/null +++ b/depend/zcash/depends/patches/native_cctools/ignore-otool.diff @@ -0,0 +1,24 @@ +diff -ur cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97-orig/cctools/Makefile.am cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/Makefile.am +--- cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97-orig/cctools/Makefile.am 2020-07-30 15:01:05.680000000 +0100 ++++ cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/Makefile.am 2020-07-30 15:01:34.900000000 +0100 +@@ -1,7 +1,7 @@ + if ISDARWIN +-SUBDIRS=libstuff libmacho ar as misc otool efitools ld64 man ++SUBDIRS=libstuff libmacho ar as misc efitools ld64 man + else +-SUBDIRS=libobjc2 libstuff libmacho ar as misc otool efitools ld64 man ++SUBDIRS=libobjc2 libstuff libmacho ar as misc efitools ld64 man + endif + + ACLOCAL_AMFLAGS = -I m4 +diff -ur cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97-orig/cctools/configure.ac cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/configure.ac +--- cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97-orig/cctools/configure.ac 2020-07-30 15:01:05.680000000 +0100 ++++ cctools-port-55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/configure.ac 2020-07-30 15:01:47.330000000 +0100 +@@ -466,7 +466,6 @@ + AC_CONFIG_FILES([as/ppc64/Makefile]) + AC_CONFIG_FILES([man/Makefile]) + AC_CONFIG_FILES([misc/Makefile]) +-AC_CONFIG_FILES([otool/Makefile]) + AC_CONFIG_FILES([efitools/Makefile]) + AC_CONFIG_FILES([libobjc2/Makefile]) + AC_CONFIG_FILES([ld64/Makefile]) diff --git a/depend/zcash/depends/patches/zeromq/windows-unused-variables.diff b/depend/zcash/depends/patches/zeromq/windows-unused-variables.diff new file mode 100644 index 000000000..8526ee5f9 --- /dev/null +++ b/depend/zcash/depends/patches/zeromq/windows-unused-variables.diff @@ -0,0 +1,17 @@ +diff -ur zeromq-4.3.3-orig/src/clock.cpp zeromq-4.3.3/src/clock.cpp +--- zeromq-4.3.3-orig/src/clock.cpp 2020-10-13 13:44:04.190000000 +0100 ++++ zeromq-4.3.3/src/clock.cpp 2020-10-13 13:47:04.170000000 +0100 +@@ -126,9 +126,13 @@ + init_compatible_get_tick_count64 (); + #endif + ++#ifndef ZMQ_HAVE_WINDOWS + const uint64_t usecs_per_msec = 1000; ++#endif + const uint64_t usecs_per_sec = 1000000; ++#if !defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_HAVE_FREEBSD) + const uint64_t nsecs_per_usec = 1000; ++#endif + + zmq::clock_t::clock_t () : + _last_tsc (rdtsc ()), diff --git a/depend/zcash/doc/Doxyfile b/depend/zcash/doc/Doxyfile new file mode 100644 index 000000000..dc7be6658 --- /dev/null +++ b/depend/zcash/doc/Doxyfile @@ -0,0 +1,1752 @@ +# Doxyfile 1.7.4 + +# !!! Invoke doxygen from project root using: +# doxygen doc/Doxyfile + +# 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 +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Bitcoin + +# 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 = 0.11.2 + +# 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 = "P2P Digital Currency" + +# 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 = doc/bitcoin_logo_doxygen.png + +# 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 = doc/doxygen + +# 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 = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# 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. + +STRIP_FROM_PATH = + +# 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 in the value part of an alias to insert newlines. + +ALIASES = + +# 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 = + +# 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 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 + +#--------------------------------------------------------------------------- +# 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_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# 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 = NO + +# 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 + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# 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. The 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 = + +#--------------------------------------------------------------------------- +# 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 + +# 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 https://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 = *.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 + +# 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 +# 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. + +EXCLUDE = src/leveldb src/json src/test /src/qt/test + +# The EXCLUDE_SYMLINKS tag can be used 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 = boost google + +# 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 = + +# 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 = NO + +# 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 and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# 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 https://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 = html + +# 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 the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_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 stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see https://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 = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# 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. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# 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 at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# 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 + +# 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. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# 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 also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# 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.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# 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 = + +# 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 = YES + +# 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 = YES + +# 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 + +#--------------------------------------------------------------------------- +# 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 stylesheet 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. +# Optionally an initial location of the external documentation +# can be added for each tagfile. 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. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# 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 = YES + +# 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 write a font called Helvetica to the output +# directory and reference it in 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 output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +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 +# 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 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, SHOW_DIRECTORIES 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. + +DOT_IMAGE_FORMAT = svg + +# 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/depend/zcash/doc/authors.md b/depend/zcash/doc/authors.md new file mode 100644 index 000000000..5700307b9 --- /dev/null +++ b/depend/zcash/doc/authors.md @@ -0,0 +1,252 @@ +Zcash Contributors +================== + +Jack Grigg (1142) +Kris Nuttycombe (524) +Simon Liu (460) +Sean Bowe (379) +Daira Hopwood (325) +Eirik Ogilvie-Wigley (216) +Wladimir J. van der Laan (150) +Alfredo Garcia (119) +Taylor Hornby (118) +Marshall Gaucher (112) +Pieter Wuille (106) +Jonas Schnelli (90) +Jay Graber (89) +Larry Ruane (88) +Ying Tong Lai (87) +Marco Falke (82) +Cory Fields (75) +Nathan Wilcox (56) +Matt Corallo (52) +sasha (51) +practicalswift (38) +Kevin Gallagher (38) +Dimitris Apostolou (38) +fanquake (36) +Carl Dong (26) +Gregory Maxwell (23) +Jorge Timón (22) +John Newbery (22) +Luke Dashjr (21) +Jonathan "Duke" Leto (18) +syd (16) +Patick Strateman (16) +furszy (15) +Charlie O'Keefe (15) +avnish (14) +Per Grön (14) +Benjamin Winston (13) +Steven Smith (12) +Pavel Janík (12) +Patrick Strateman (12) +Ariel Gabizon (12) +Suhas Daftuar (11) +Paige Peterson (11) +Kaz Wesley (11) +Alex Morcos (11) +Philip Kaufmann (10) +Peter Todd (10) +Marius Kjærstad (10) +João Barbosa (10) +ying tong (9) +teor (9) +nomnombtc (9) +kozyilmaz (8) +Zancas Wilcox (8) +Jeremy Rubin (8) +Jeff Garzik (8) +Ben Wilson (8) +Karl-Johan Alm (7) +James O'Beirne (6) +David Mercer (6) +Daniel Kraft (6) +Daniel Cousens (6) +Chun Kuan Lee (6) +Casey Rodarmor (6) +jnewbery (5) +ca333 (5) +Sasha (5) +MeshCollider (5) +Johnathan Corgan (5) +George Tankersley (5) +Gavin Andresen (5) +Gareth Davies (5) +Alex Wied (5) +sandakersmann (4) +gladcow (4) +WO (4) +Sjors Provoost (4) +Russell Yanofsky (4) +Nate Wilcox (4) +mruddy (3) +lpescher (3) +isle2983 (3) +elbandi (3) +NikVolf (3) +Martin Ankerl (3) +Julian Fleischer (3) +Jim Posen (3) +Jason Davies (3) +Evan Klitzke (3) +Ethan Heilman (3) +Eric Lombrozo (3) +Danny Willems (3) +Anthony Towns (3) +Alfie John (3) +whythat (2) +rofl0r (2) +ptschip (2) +noname45688@gmail.com (2) +kpcyrd (2) +kobake (2) +hexabot (2) +face (2) +aniemerg (2) +Yuri Zhykin (2) +UdjinM6 (2) +Tim Ruffing (2) +Thomas Snider (2) +Solar Designer (2) +Sebastian Falbesoner (2) +Scott (2) +S. Matthew English (2) +Robert C. Seacord (2) +Pejvan (2) +Pavol Rusnak (2) +Pavel Vasin (2) +Mustafa (2) +Matthew King (2) +Mary Moore-Simmons (2) +Marek (2) +Joe Turgeon (2) +Jeffrey Czyz (2) +Jack Gavigan (2) +ITH4Coinomia (2) +Dagur Valberg Johannsson (2) +Conrado Gouvea (2) +Bryant Eisenbach (2) +Brad Miller (2) +Bjorn Hjortsberg (2) +Ben Woosley (2) +Amgad Abdelhafez (2) +Alex Tsankov (2) +Akio Nakamura (2) +Aditya Kulkarni (2) +ロãƒãƒ³ ダル (1) +zathras-crypto (1) +vim88 (1) +unsystemizer (1) +tulip (1) +tpantin (1) +sgmoore (1) +randy-waterhouse (1) +plutoforever (1) +murrayn (1) +mrbandrews (1) +kirkalx (1) +kazcw (1) +jeff-liang (1) +jc (1) +instagibbs (1) +glowang (1) +ewillbefull@gmail.com (1) +emilrus (1) +dexX7 (1) +dependabot[bot] (1) +daniel (1) +codetriage-readme-bot (1) +calebogden (1) +ayleph (1) +avnish98 (1) +adityapk00 (1) +Za Wilcox (1) +William M Peaster (1) +Vidar Holen (1) +Vasil Dimov (1) +Ulrich Kempken (1) +Tom Ritter (1) +Tom Harding (1) +Technetium (1) +Stephen (1) +Shaul Kfir (1) +Ross Nicoll (1) +Rod Vagg (1) +Robert McLaughlin (1) +Richard Littauer (1) +René Nyffenegger (1) +R E Broadley (1) +Puru (1) +Peter Pratscher (1) +Peter Bushnell (1) +Pedro Branco (1) +Paul Georgiou (1) +Paragon Initiative Enterprises, LLC (1) +NicolasDorier (1) +Nicolas DORIER (1) +Nick (1) +Nathaniel Mahieu (1) +Murilo Santana (1) +Miles Manley (1) +Maxwell Gubler (1) +Matt Quinn (1) +Marko Bencun (1) +Mark Friedenbach (1) +Luv Khemani (1) +Louis Nyffenegger (1) +LongShao007 (1) +LitecoinZ (1) +Leo Arias (1) +Lauda (1) +Lars-Magnus Skog (1) +Kristaps Kaupe (1) +Kevin Pan (1) +Karel Bilek (1) +Josh Lehan (1) +Josh Ellithorpe (1) +Jonas Nick (1) +Jesse Cohen (1) +Jeffrey Walton (1) +Janito Vaqueiro Ferreira Filho (1) +Jainan-Tandel (1) +Igor Cota (1) +Ian T (1) +Ian Munoz (1) +Ian Kelling (1) +Hennadii Stepanov (1) +Gregory Sanders (1) +Gaurav Rana (1) +Forrest Voight (1) +Florian Schmaus (1) +Eran Tromer (1) +Elliot Olds (1) +Dimitris Tsapakidis (1) +DesWurstes (1) +Denis Lukianov (1) +David Llop (1) +Dan Raviv (1) +Christian von Roques (1) +Chirag Davé (1) +Cameron Boehmer (1) +BtcDrak (1) +Bryan Stitt (1) +Bruno Arueira (1) +Braydon Fuller (1) +Boris Hajduk (1) +Bob McElrath (1) +Bitcoin Error Log (1) +Bernhard M. Wiedemann (1) +Ashley Holman (1) +Andrew Chow (1) +Allan Niemerg (1) +Alex van der Peet (1) +Alex (1) +Ahmad Kazi (1) +Adam Weiss (1) +Adam Langley (1) +Adam Brown (1) +Aaron Clauson (1) +4ZEC (1) +251 (1) +21E14 (1) diff --git a/depend/zcash/doc/bips.md b/depend/zcash/doc/bips.md new file mode 100644 index 000000000..14c7e372f --- /dev/null +++ b/depend/zcash/doc/bips.md @@ -0,0 +1,4 @@ +BIPs that are implemented by Zcash (up-to-date up to **v1.1.0**): + +* Numerous historic BIPs were present in **v1.0.0** at launch; see [the protocol spec](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf) for details. +* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, but only enforced for peer versions `>=170004` as of **v1.1.0** ([PR #2814](https://github.com/zcash/zcash/pull/2814)). diff --git a/depend/zcash/doc/book/.gitignore b/depend/zcash/doc/book/.gitignore new file mode 100644 index 000000000..7585238ef --- /dev/null +++ b/depend/zcash/doc/book/.gitignore @@ -0,0 +1 @@ +book diff --git a/depend/zcash/doc/book/book.toml b/depend/zcash/doc/book/book.toml new file mode 100644 index 000000000..a67147b67 --- /dev/null +++ b/depend/zcash/doc/book/book.toml @@ -0,0 +1,6 @@ +[book] +authors = ["Jack Grigg"] +language = "en" +multilingual = false +src = "src" +title = "The zcashd Book" diff --git a/depend/zcash/doc/book/src/README.md b/depend/zcash/doc/book/src/README.md new file mode 100644 index 000000000..3bad00702 --- /dev/null +++ b/depend/zcash/doc/book/src/README.md @@ -0,0 +1 @@ +{{#include ../../../README.md}} diff --git a/depend/zcash/doc/book/src/SUMMARY.md b/depend/zcash/doc/book/src/SUMMARY.md new file mode 100644 index 000000000..b886446f3 --- /dev/null +++ b/depend/zcash/doc/book/src/SUMMARY.md @@ -0,0 +1,14 @@ +# The zcashd Book + +[zcashd](README.md) +- [User Documentation](user.md) + - [Metrics](user/metrics.md) + - [Deprecated Features](user/deprecation.md) +- [Developer Documentation](dev.md) + - [Rust in `zcashd`](dev/rust.md) + - [Regtest tips and hints](dev/regtest.md) + - [Deprecation Procedure](dev/deprecation.md) +- [Design](design.md) + - [Chain state](design/chain-state.md) + - ["Coins" view](design/coins-view.md) + - [P2P data propagation](design/p2p-data-propagation.md) diff --git a/depend/zcash/doc/book/src/design.md b/depend/zcash/doc/book/src/design.md new file mode 100644 index 000000000..643207e11 --- /dev/null +++ b/depend/zcash/doc/book/src/design.md @@ -0,0 +1,9 @@ +# Design + +Zcash was originally a fork of Bitcoin 0.11.2, and as such the `zcashd` node architecture +is very similar to `bitcoind`. There are however several differences, most notably the +addition of shielded pools to the consensus logic and full node state. + +In this section of the book, we describe the overall architecture that we inherit from +`bitcoind`, the changes we have made to the inherited components, and the new components +we have introduced. diff --git a/depend/zcash/doc/book/src/design/chain-state.md b/depend/zcash/doc/book/src/design/chain-state.md new file mode 100644 index 000000000..0e5057f13 --- /dev/null +++ b/depend/zcash/doc/book/src/design/chain-state.md @@ -0,0 +1,3 @@ +# Chain state + +TBD diff --git a/depend/zcash/doc/book/src/design/coins-view.md b/depend/zcash/doc/book/src/design/coins-view.md new file mode 100644 index 000000000..79a44fdf2 --- /dev/null +++ b/depend/zcash/doc/book/src/design/coins-view.md @@ -0,0 +1,10 @@ +# "Coins" view + +TBD + +## Notes + +- This is the main context in which `CTxOut::IsNull()` is used. The other is a + single spot in the mempool code. Once we've backported the + [per-txout CoinsDB](https://github.com/bitcoin/bitcoin/pull/10195) we can + hopefully eliminate this method. diff --git a/depend/zcash/doc/book/src/design/p2p-data-propagation.md b/depend/zcash/doc/book/src/design/p2p-data-propagation.md new file mode 100644 index 000000000..6296e9df1 --- /dev/null +++ b/depend/zcash/doc/book/src/design/p2p-data-propagation.md @@ -0,0 +1,43 @@ +# P2P data propagation + +This page contains notes about how block and transaction data is tracked and propagated by +`zcashd`. Most of this behaviour is inherited from Bitcoin Core, but some differences have +developed. + +Some of this content is duplicated from in-code comments, but assembling this summary in +one place is generally useful for understanding the overall dynamic :) + +## `recentRejects` + +When a transaction is rejected by `AcceptToMemoryPool`, the transaction is added to the +`recentRejects` Bloom filter, so that we don't process it again. The Bloom filter resets +whenever the chain tip changes, as previously invalid transactions might become valid. + +To prevent DoS attacks against wallets submitting transactions, `recentRejects` needs to +store a commitment to the entire transaction. This ensures that if a transaction is +malleated by a network peer to invalidate its authorizing data, the node will ignore +future advertisements of that specific transaction, but still request alternative versions +of the same txid (which might have valid authorizing data). + +- For pre-v5 transactions, the txid commits to the entire transaction, and the wtxid is + the txid with a globally-fixed (all-ones) suffix. +- For v5+ transactions, the wtxid commits to the entire transaction. + +## `mapOrphanTransactions` + +Upstream uses this map to store transactions that are rejected by `AcceptToMemoryPool` +because the node doesn't have their transparent inputs. `zcashd` inherits this behaviour +but limits it to purely-transparent transactions (that is, if a transaction contains any +shielded components, the node rejects it as invalid and adds it to `recentRejects`). + +`mapOrphanTransactions` indexes transactions by txid. This means that if an orphan +transaction is received (spending transparent UTXOs the node does not know about), and it +also happens to be invalid for other reasons (subsequent `AcceptToMemoryPool` rules that +haven't yet been checked), then the node will not request any v5+ transactions with the +same txid but different authorizing data. This does not create a DoS problem for wallets, +because an adversary that manipulated an orphan transaction to be invalid under the above +constraints would also need to prevent the orphan's parent from entering the mempool, and +eventually a parent is reached that is not an orphan. Once the orphan's direct parent is +accepted, the orphan is re-evaluated, and if it had been manipulated to be invalid, its +wtxid is added to `recentRejects` while its txid is removed from `mapOrphanTransactions`, +enabling the wallet to rebroadcast the unmodified transaction. diff --git a/depend/zcash/doc/book/src/dev.md b/depend/zcash/doc/book/src/dev.md new file mode 100644 index 000000000..8fcbaddd0 --- /dev/null +++ b/depend/zcash/doc/book/src/dev.md @@ -0,0 +1,3 @@ +# Developer Documentation + +This section contains documentation aimed at contributors to the `zcashd` codebase. diff --git a/depend/zcash/doc/book/src/dev/deprecation.md b/depend/zcash/doc/book/src/dev/deprecation.md new file mode 100644 index 000000000..16e68e9f3 --- /dev/null +++ b/depend/zcash/doc/book/src/dev/deprecation.md @@ -0,0 +1,38 @@ +Deprecation Procedure +===================== + +From time to time, features of `zcashd` and its associated wallet and RPC API are +deprecated to allow eventual removal of functionality that has been superseded +by more recent improvements. Deprecation follows a process whereby deprecate +features can be explicitly turned on or off using the +`-allowdeprecated=` CLI argument. + +`zcashd` internally supports two sets of deprecated feature flags in +`src/deprecation.h`: +- `DEFAULT_ALLOW_DEPRECATED` contains the set of features that remain available + for use without having to be specifically enabled using `-allowdeprecated`. +- `DEFAULT_DENY_DEPRECATED` contains the set of features that are not enabled + by default, and must be explicitly enabled using `-allowdeprecated`. + +Deprecation of a feature occurs as a 3-step process: + +1. A deprecation flag is selected for the feature, and added to + `DEFAULT_ALLOW_DEPRECATED`. The fact of its deprecation is announced, and + any functionality that supersedes the deprecated feature (if any) is + documented, in the release notes. The string `DEPRECATED` is added to + user-facing API documentation and CLI help text. +2. The deprecation flag is removed from `DEFAULT_ALLOW_DEPRECATED` and added to + `DEFAULT_DENY_DEPRECATED`. +3. The deprecated feature is removed entirely, and its deprecation flag is + removed. + +Features that enter Stage 1 in a particular release should be disabled by +default after no fewer than 3 releases that update `zcashd`'s +minor-version, and features should only be fully removed after a total of 6 minor-version +updates. `zcashd`'s release schedule intends to produce a release that updates +the minor version every 6 weeks, so deprecated features remain accessible by +default for approximately 18 weeks, and then can be expected to be removed no +less than 36 weeks from their initial deprecation. The deprecation timeline for +each newly deprecated feature should be documented in +[../user/deprecation.md](../user/deprecation.md). + diff --git a/depend/zcash/doc/book/src/dev/regtest.md b/depend/zcash/doc/book/src/dev/regtest.md new file mode 100644 index 000000000..649d9107c --- /dev/null +++ b/depend/zcash/doc/book/src/dev/regtest.md @@ -0,0 +1,165 @@ +# Regtest + +_Regtest_ ("regression test") is one of the three _network types_ +supported by Zcash, the others being `testnet` and `mainnet`. +Regtest is an entirely local, self-contained mode -- your node or nodes +do not talk with peers out in the world. It gives you complete +control of the state of the blockchain and the sequence of events. +You start with an empty blockchain (just the genesis block, block 0). +Blocks can be mined instantly, and must be created explicitly. + +You can run one or more regtest nodes on the same system. +The [RPC tests](https://github.com/zcash/zcash/tree/master/qa/rpc-tests) +use `regtest` mode (usually starting multiple nodes), but you may use it +manually and interactively to learn, test, and experiment. Most often +just one node is used in this case. + +## Example session + +Here's a sample session (after you've built `zcashd` and `zcash-cli`): + +``` +$ mkdir /tmp/regtest-datadir +$ cat </tmp/regtest-datadir/zcash.conf +regtest=1 +rpcuser=u +rpcpassword=p +rpcport=18132 +EOF +$ src/zcashd -daemon -datadir=/tmp/regtest-datadir +``` + +Watch `tmp/regtest-datadir/regtest/debug.log` to see what `zcashd` is doing. +It may also be useful to start `zcashd` with `-debug` to generate much +more logging. Now we can send RPCs to the node: + +``` +$ src/zcash-cli -datadir=/tmp/regtest-datadir getblockchaininfo +{ + "chain": "regtest", + "blocks": 0, + "initial_block_download_complete": false, + "headers": 0, + (...) +} +# Generate (mine) three blocks: +$ src/zcash-cli -datadir=/tmp/regtest-datadir generate 3 +[ + "05040271f43f78e3870a88697eba201aa361ea5802c69eadaf920ff376787242", + "0469f2df43dda69d521c482679b2db3c637b1721222511302584ac75e057c859", + "0ab7a26e7b3b5dfca077728de90da0cfd1c49e1edbc130a52de4062b1aecac75" +] +$ src/zcash-cli -datadir=/tmp/regtest-datadir getblockchaininfo +{ + "chain": "regtest", + "blocks": 3, + "initial_block_download_complete": true, + "headers": 3, + (...) +} +$ src/zcash-cli -datadir=/tmp/regtest-datadir stop +Zcash server stopping +$ +``` +## Network upgrades + +Zcash has adopted a series of +[network upgrades](https://github.com/zcash/zcash/blob/master/src/consensus/upgrades.cpp). +On `mainnet` and `testnet`, these activate at +fixed, known block heights ([example](https://github.com/zcash/zcash/blob/master/src/chainparams.cpp#L117)). +In `regtest` mode, you determine the activation heights. Upgrades may occur at +any height greater than 0, and multiple upgrades can occur at the same height. The upgrades +have a strict ordering (as shown in the upgrades source file); for example, Canopy can't +be activated before Blossom. + +You specify the upgrade heights using multiple `-nuparams=`_\_ arguments. +(The branch IDs are available in the +[upgrades.cpp file](https://github.com/zcash/zcash/blob/master/src/consensus/upgrades.cpp)) +It's convenient to add these to the configuration file, for example: +``` +$ cat <>/tmp/regtest-datadir/zcash.conf +nuparams=76b809bb:1 +nuparams=f5b9230b:5 +EOF +``` +(Alternatively, you can specify these on the `zcashd` command line.) +You need not activate every upgrade explicitly. The example activates Sapling +(branchID 76b809bb) at height 1; activating Sapling implies activating Overwinter, so this +is done automatically. Similarly, activating Heartwood at height 5 +also simultaneously activates Blossom. Since no later upgrades are specified, none +of them will activate, regardless of height reached. + +**IMPORTANT**: if you change the network upgrade heights from one +test run to the next, it's almost always necessary to start fresh +by removing the data directory, otherwise you'll encounter strange errors. + +You can see which network upgrades are currently active and which are pending +(using the above `nuparams` settings as an example): +``` +$ src/zcash-cli -datadir=/tmp/regtest-datadir generate 2 +$ src/zcash-cli -datadir=/tmp/regtest-datadir getblockchaininfo +{ + "blocks": 2, + (...) + "upgrades": { + "5ba81b19": { + "name": "Overwinter", + "activationheight": 1, + "status": "active", + "info": "See https://z.cash/upgrade/overwinter/ for details." + }, + "76b809bb": { + "name": "Sapling", + "activationheight": 1, + "status": "active", + "info": "See https://z.cash/upgrade/sapling/ for details." + }, + "2bb40e60": { + "name": "Blossom", + "activationheight": 5, + "status": "pending", + "info": "See https://z.cash/upgrade/blossom/ for details." + }, + "f5b9230b": { + "name": "Heartwood", + "activationheight": 5, + "status": "pending", + "info": "See https://z.cash/upgrade/heartwood/ for details." + } + }, + (...) +} +``` + +## Manual testing within an RPC (Python) test run + +It is often useful, either when debugging an issue or simply when you want to put +the node into a certain state, to use the RPC test framework to produce the desired +state and then be able to manually interrogate and modify that state using `zcash-cli` +to execute RPC calls. An easy way to do that is as follows: + +Add the line `import time; time.sleep(999999)` (the units are seconds) somewhere +within an RPC test to pause its execution at that point. Start the test, and then: + +``` +$ ps alx | grep zcashd +0 1000 96247 96246 20 0 1426304 123952 futex_ SLl+ pts/12 0:18 /g/zcash/src/zcashd -datadir=/tmp/test9d907s8a/96246/node0 -keypool=1 -discover=0 -rest -nuparams=5ba81b19:1 -nuparams=76b809bb:1 -debug=mempool -mempooltxcostlimit=8000 +0 1000 96274 96246 20 0 744092 85568 - RLl+ pts/12 0:05 /g/zcash/src/zcashd -datadir=/tmp/test9d907s8a/96246/node1 -keypool=1 -discover=0 -rest -nuparams=5ba81b19:1 -nuparams=76b809bb:1 -debug=mempool -mempooltxcostlimit=8000 +$ +``` +Now you can interact with the running test node by copy-and-pasting its +`-datadir` argument, for example: + +``` +$ src/zcash-cli -datadir=/tmp/test9d907s8a/96246/node0 getblockchaininfo +``` +(The other `zcashd` command-line arguments are generally not needed by +`zcash-cli`.) You can see the running node's debug log file: +``` +$ cat /tmp/test9d907s8a/96246/node0/regtest/debug.log +``` +or look at its configuration file. +``` +$ cat /tmp/test9d907s8a/96246/node0/zcash.conf +``` +In this way, the RPC test framework can teach us more about running `regtest` nodes. \ No newline at end of file diff --git a/depend/zcash/doc/book/src/dev/rust.md b/depend/zcash/doc/book/src/dev/rust.md new file mode 100644 index 000000000..cae406f3a --- /dev/null +++ b/depend/zcash/doc/book/src/dev/rust.md @@ -0,0 +1,56 @@ +# Rust in `zcashd` + +`zcashd` is primarily a C++ codebase, but most new code is being written in Rust +where possible. + +## Adding new dependencies in online-Rust mode + +The `zcashd` build system pins all dependencies, and in order to facilitate +deterministic builds, `cargo` is configured to run in offline mode with vendored +crates. This means that if, for example, you add the `foobar` crate to +`Cargo.toml`, you will likely see an error similar to this: + +``` +$ cargo check +error: no matching package named `foobar` found +location searched: registry `https://github.com/rust-lang/crates.io-index` +required by package `librustzcash v0.2.0 (/path/to/zcash)` +``` + +Instead, you first need to build `zcashd` in online-Rust mode: +``` +CONFIGURE_FLAGS=--enable-online-rust ./zcutil/build.sh +``` + +After doing so, you can add a new dependency as follows: + +1. Add the new dependency to `Cargo.toml`. +2. Run `cargo check` to update the `Cargo.lock` file. +3. Commit `Cargo.toml` and `Cargo.lock`. + +## Using a local Rust dependency + +During development, you can use a locally checked out version of a dependency +by applying a [`cargo` patch](https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html#the-patch-section). + +For example, to use a local version of the `orchard` crate that includes a new +API, add the following patch to `Cargo.toml`: + +``` +[dependencies] +# This dependency is listed with a version, meaning it comes from crates.io; the +# patch goes into a [patch.crates-io] section. +orchard = "0.0" +... + +[patch.crates-io] +# Comment out any existing patch, if present. +# orchard = { git = "https://github.com/zcash/orchard.git", rev = "..." } + +# Add this patch (both relative and absolute paths work): +orchard = { path = "../relative/path/to/orchard" } +``` + +Usually you can apply a patch to use a locally checked out dependency without +needing to build `zcashd` in online-Rust mode. However, if your local changes +include a new dependency, you will need to ensure you are in online-Rust mode. diff --git a/depend/zcash/doc/book/src/doc/imgs/logo.png b/depend/zcash/doc/book/src/doc/imgs/logo.png new file mode 120000 index 000000000..15d77010f --- /dev/null +++ b/depend/zcash/doc/book/src/doc/imgs/logo.png @@ -0,0 +1 @@ +../../../../imgs/logo.png \ No newline at end of file diff --git a/depend/zcash/doc/book/src/doc/imgs/zcashd_screen.gif b/depend/zcash/doc/book/src/doc/imgs/zcashd_screen.gif new file mode 120000 index 000000000..c16cb866f --- /dev/null +++ b/depend/zcash/doc/book/src/doc/imgs/zcashd_screen.gif @@ -0,0 +1 @@ +../../../../imgs/zcashd_screen.gif \ No newline at end of file diff --git a/depend/zcash/doc/book/src/user.md b/depend/zcash/doc/book/src/user.md new file mode 100644 index 000000000..e23cdcf42 --- /dev/null +++ b/depend/zcash/doc/book/src/user.md @@ -0,0 +1,6 @@ +# User Documentation + +This section contains user documentation specific to `zcashd`. + +See [here](https://zcash.readthedocs.io/) for more general Zcash documentation, as well as +installation instructions for `zcashd`. diff --git a/depend/zcash/doc/book/src/user/deprecation.md b/depend/zcash/doc/book/src/user/deprecation.md new file mode 100644 index 000000000..f0c55da38 --- /dev/null +++ b/depend/zcash/doc/book/src/user/deprecation.md @@ -0,0 +1,71 @@ +Deprecated Features +=================== + +In order to support the continuous improvement of `zcashd`, features are +periodically deprecated and removed when they have been superseded or are no +longer useful. Deprecation follows a 3-stage process: + +1. Initially, a feature will be marked as DEPRECATED in the release notes and + user-facing documentation, but no other changes are made; the feature + continues to be available and function as normal. While features at this + stage remain enabled by default, they may be explicitly disabled by + specifying `-allowdeprecated=none` on the command line when starting the + node, or by including `allowdeprecated=none` as a line in the `zcash.conf` + file. +2. In the next stage of deprecation, the feature will be disabled by default. + Disabled features may be reenabled via use of the `-allowdeprecated` flag. +3. In the third stage, the feature is fully removed and is no longer available. + +Features that enter Stage 1 in a particular release will be disabled by default +after no fewer than 3 releases that update `zcashd`'s minor-version, and +features will only be fully removed after a total of at least 6 minor-version updates. +`zcashd`'s release schedule intends to produce a release that updates the minor +version every 6 weeks, so deprecated features remain accessible by default for +approximately 18 weeks, and then can be expected to be removed no less than 36 +weeks after their initial deprecation. Deprecation and removal timelines might +be extended beyond this on a case-by-case basis to satisfy user requirements. + +Currently Deprecated +==================== + +Stage 1 +------- + +The following features are deprecated, but remain enabled by default. These features +will be disabled if `-allowdeprecated=none` is added to the CLI arguments when starting +the node, or if an `allowdeprecated=none` line is added to `zcash.conf`. + +### Deprecated in 5.0.0 + +The following features are deprecated as of release 5.0.0 and will be disabled by +default as of release 5.3.0. + + - `legacy_privacy` - The default "legacy" privacy policy for z_sendmany is + deprecated. Use `-allowdeprecated=none` to require the default behavior to + conform to the `FullPrivacy` directive in all cases instead of just for + transactions involving unified addresses. + - `getnewaddress` - The `getnewaddress` RPC method is deprecated. + - `getrawchangeaddress` - The `getrawchangeaddress` RPC method is deprecated. + - `z_getbalance` - The `z_getbalance` RPC method is deprecated. + - `z_gettotalbalance` - The `z_gettotalbalance` RPC method is deprecated. + - `z_getnewaddress` - The `z_getnewaddress` RPC method is deprecated. + - `z_listaddresses` - The `z_listaddresses` RPC method is deprecated. + - `addrtype` - The `type` attribute is deprecated in the results of RPC + methods that return address metadata. It is recommended that applications + using this metadata be updated to use the `pool` or `address_type` + attributes, which have replaced the `type` attribute, as appropriate. + +Stage 2 +------- + +Each feature in the lists below may be enabled by adding `-allowdeprecated=` +to the CLI arguments when starting the node, or by adding an `allowdeprecated=` +line to `zcash.conf`. + +### Disabled in 5.0.0 + +The following features are disabled by default, and will be removed in release 5.3.0. + + - `zcrawreceive` - The `zcrawreceive` RPC method is disabled. + - `zcrawjoinsplit` - The `zcrawjoinsplit` RPC method is disabled. + - `zcrawkeygen` - The `zcrawkeygen` RPC method is disabled. diff --git a/depend/zcash/doc/book/src/user/metrics.md b/depend/zcash/doc/book/src/user/metrics.md new file mode 100644 index 000000000..3775b0f4f --- /dev/null +++ b/depend/zcash/doc/book/src/user/metrics.md @@ -0,0 +1,85 @@ +# zcashd metrics + +## Metrics UI + +This is the user interface that `zcashd` displays by default when run. It +displays a small selection of interesting metrics, but is not intended for +programmatic consumption. + +## RPC methods + +`zcashd` provides the following JSON-RPC methods that expose node metrics: + +- Chain: + - `getblockchaininfo`: Various state info regarding block chain processing. + - `gettxoutsetinfo`: Statistics about the unspent transparent transaction output set. + - `getmempoolinfo`: Details on the active state of the TX memory pool. +- P2P network: + - `getnetworkinfo`: Various state info regarding P2P networking. + - `getpeerinfo`: Data about each connected network node. + - `getdeprecationinfo`: The current node version and deprecation block height. +- Miscellaneous + - `getmemoryinfo`: Information about memory usage. + - `getmininginfo`: Mining-related information. + - `getinfo` (deprecated): A small subset of the above metrics. + +You can see what each method provides with `zcash-cli help METHOD_NAME`. + +## Prometheus support + +`zcashd` can optionally expose an HTTP server that acts as a Prometheus scrape +endpoint. The server will respond to `GET` requests on any request path. + +To enable the endpoint, add `-prometheusport=` to your `zcashd` +configuration (either in `zcash.conf` or on the command line). After +restarting `zcashd` you can then test the endpoint by querying it: + +``` +$ curl http://127.0.0.1: +# TYPE zcash_net_out_messages counter +zcash_net_out_messages 181 + +# TYPE zcash_net_in_bytes_total counter +zcash_net_in_bytes_total 3701998 + +# TYPE zcash_net_in_messages counter +zcash_net_in_messages 184 + +# TYPE zcashd_build_info counter +zcashd_build_info{version="v4.2.0"} 1 + +# TYPE zcash_chain_verified_block_total counter +zcash_chain_verified_block_total 162 +... +``` + +By default, access is restricted to localhost. This can be expanded with +`-metricsallowip=`, which can specify IPs or subnets. Note that HTTPS is not +supported, and therefore connections to the endpoint are not encrypted or +authenticated. Access to the endpoint should be assumed to compromise the +privacy of node operations, by the provided metrics and/or by timing side +channels. Non-localhost access is **strongly discouraged** if the node has a +wallet holding live funds. + +### Example metrics collection with Docker + +The example instructions below were tested on Windows 10 using Docker Desktop +with the WSL 2 backend, connected to a `zcashd` running inside WSL2 (but not +inside Docker): + +``` +# Create a storage volume for Grafana (once) +docker volume create grafana-storage + +# Create a storage volume for Prometheus (once) +docker volume create prometheus-storage + +# Run Prometheus +# You will need to modify ~/contrib/metrics/prometheus.yaml to match the +# port configured with -prometheusport and -metricsbind / -metricsallowip +# (and possibly also for your Docker network setup). +docker run --detach -p 9090:9090 --volume prometheus-storage:/prometheus --volume ~/contrib/metrics/prometheus.yaml:/etc/prometheus/prometheus.yml prom/prometheus + +# Run Grafana +docker run --detach -p 3030:3030 --env GF_SERVER_HTTP_PORT=3030 --volume grafana-storage:/var/lib/grafana grafana/grafana +``` diff --git a/depend/zcash/doc/developer-notes.md b/depend/zcash/doc/developer-notes.md new file mode 100644 index 000000000..a4139ee2b --- /dev/null +++ b/depend/zcash/doc/developer-notes.md @@ -0,0 +1,369 @@ +Coding +==================== + +Various coding styles have been used during the history of the codebase, +and the result is not very consistent. However, we're now trying to converge to +a single style, so please use it in new code. Old code will be converted +gradually. +- Basic rules specified in src/.clang-format. Use a recent clang-format-3.5 to format automatically. + - Braces on new lines for namespaces, classes, functions, methods. + - Braces on the same line for everything else. + - 4 space indentation (no tabs) for every block except namespaces. + - No indentation for public/protected/private or for namespaces. + - No extra spaces inside parenthesis; don't do ( this ) + - No space after function names; one space after if, for and while. + +Block style example: +```c++ +namespace foo +{ +class Class +{ + bool Function(char* psz, int n) + { + // Comment summarising what this section of code does + for (int i = 0; i < n; i++) { + // When something fails, return early + if (!Something()) + return false; + ... + } + + // Success return is usually at the end + return true; + } +} +} +``` + +Doxygen comments +----------------- + +To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields. + +For example, to describe a function use: +```c++ +/** + * ... text ... + * @param[in] arg1 A description + * @param[in] arg2 Another argument description + * @pre Precondition for function... + */ +bool function(int arg1, const char *arg2) +``` +A complete list of `@xxx` commands can be found at http://www.stack.nl/~dimitri/doxygen/manual/commands.html. +As Doxygen recognizes the comments by the delimiters (`/**` and `*/` in this case), you don't +*need* to provide any commands for a comment to be valid; just a description text is fine. + +To describe a class use the same construct above the class definition: +```c++ +/** + * Alerts are for notifying old versions if they become too obsolete and + * need to upgrade. The message is displayed in the status bar. + * @see GetWarnings() + */ +class CAlert +{ +``` + +To describe a member or variable use: +```c++ +int var; //!< Detailed description after the member +``` + +or +```cpp +//! Description before the member +int var; +``` + +Also OK: +```c++ +/// +/// ... text ... +/// +bool function2(int arg1, const char *arg2) +``` + +Not OK (used plenty in the current source, but not picked up): +```c++ +// +// ... text ... +// +``` + +A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html, +but if possible use one of the above styles. + +Development tips and tricks +--------------------------- + +**compiling for debugging** + +Run configure with the --enable-debug option, then make. Or run configure with +CXXFLAGS="-g -ggdb -O0" or whatever debug flags you need. + +**compiling for gprof profiling** + +Run configure with the --enable-gprof option, then make. + +**debug.log** + +If the code is behaving strangely, take a look in the debug.log file in the data directory; +error and debugging messages are written there. + +The -debug=... command-line option controls debugging; running with just -debug or -debug=1 will turn +on all categories (and give you a very large debug.log file). + +**testnet and regtest modes** + +Run with the -testnet option to run with "play zcash" on the test network, if you +are testing multi-machine code that needs to operate across the internet. + +If you are testing something that can run on one machine, run with the -regtest option. +In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests +that run in -regtest mode. + +**DEBUG_LOCKORDER** + +Zcash is a multithreaded application, and deadlocks or other multithreading bugs +can be very difficult to track down. Compiling with -DDEBUG_LOCKORDER (configure +CXXFLAGS="-DDEBUG_LOCKORDER -g") inserts run-time checks to keep track of which locks +are held, and adds warnings to the debug.log file if inconsistencies are detected. + +**Sanitizers** + +Bitcoin can be compiled with various "sanitizers" enabled, which add +instrumentation for issues regarding things like memory safety, thread race +conditions, or undefined behavior. This is controlled with the +`--with-sanitizers` configure flag, which should be a comma separated list of +sanitizers to enable. The sanitizer list should correspond to supported +`-fsanitize=` options in your compiler. These sanitizers have runtime overhead, +so they are most useful when testing changes or producing debugging builds. + +Some examples: + +```bash +# Enable both the address sanitizer and the undefined behavior sanitizer +./configure --with-sanitizers=address,undefined + +# Enable the thread sanitizer +./configure --with-sanitizers=thread +``` + +If you are compiling with GCC you will typically need to install corresponding +"san" libraries to actually compile with these flags, e.g. libasan for the +address sanitizer, libtsan for the thread sanitizer, and libubsan for the +undefined sanitizer. If you are missing required libraries, the configure script +will fail with a linker error when testing the sanitizer flags. + +The test suite should pass cleanly with the `thread` and `undefined` sanitizers, +but there are a number of known problems when using the `address` sanitizer. The +address sanitizer is known to fail in +[sha256_sse4::Transform](/src/crypto/sha256_sse4.cpp) which makes it unusable +unless you also use `--disable-asm` when running configure. We would like to fix +sanitizer issues, so please send pull requests if you can fix any errors found +by the address sanitizer (or any other sanitizer). + +Not all sanitizer options can be enabled at the same time, e.g. trying to build +with `--with-sanitizers=address,thread` will fail in the configure script as +these sanitizers are mutually incompatible. Refer to your compiler manual to +learn more about these options and which sanitizers are supported by your +compiler. + +Additional resources: + + * [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) + * [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html) + * [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html) + * [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) + * [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) + * [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html) + * [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki) + * [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691) + +Locking/mutex usage notes +------------------------- + +The code is multi-threaded, and uses mutexes and the +LOCK/TRY_LOCK macros to protect data structures. + +Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main +and then cs_wallet, while thread 2 locks them in the opposite order: +result, deadlock as each waits for the other to release its lock) are +a problem. Compile with -DDEBUG_LOCKORDER to get lock order +inconsistencies reported in the debug.log file. + +Re-architecting the core code so there are better-defined interfaces +between the various components is a goal, with any necessary locking +done by the components (e.g. see the self-contained CKeyStore class +and its cs_KeyStore lock for example). + +Threads +------- + +- ThreadScriptCheck : Verifies block scripts. + +- ThreadImport : Loads blocks from blk*.dat files or bootstrap.dat. + +- StartNode : Starts other threads. + +- ThreadDNSAddressSeed : Loads addresses of peers from the DNS. + +- ThreadMapPort : Universal plug-and-play startup/shutdown + +- ThreadSocketHandler : Sends/Receives data from peers on port 8233. + +- ThreadOpenAddedConnections : Opens network connections to added nodes. + +- ThreadOpenConnections : Initiates new connections to peers. + +- ThreadMessageHandler : Higher-level message handling (sending and receiving). + +- DumpAddresses : Dumps IP addresses of nodes to peers.dat. + +- ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used in 500ms. + +- ThreadRPCServer : Remote procedure call handler, listens on port 8232 for connections and services them. + +- ZcashMiner : Generates zcash (if wallet is enabled). + +- Shutdown : Does an orderly shutdown of everything. + +Pull Request Terminology +------------------------ + +Concept ACK - Agree with the idea and overall direction, but have neither reviewed nor tested the code changes. + +utACK (untested ACK) - Reviewed and agree with the code changes but haven't actually tested them. + +Tested ACK - Reviewed the code changes and have verified the functionality or bug fix. + +ACK - A loose ACK can be confusing. It's best to avoid them unless it's a documentation/comment only change in which case there is nothing to test/verify; therefore the tested/untested distinction is not there. + +NACK - Disagree with the code changes/concept. Should be accompanied by an explanation. + +See the [Development Guidelines](https://zcash.readthedocs.io/en/latest/rtd_pages/development_guidelines.html) documentation for preferred workflows, information on continuous integration and release versioning. + +Strings and formatting +------------------------ + +- Avoid using locale dependent functions if possible. You can use the provided + [`lint-locale-dependence.sh`](../test/lint/lint-locale-dependence.sh) + to check for accidental use of locale-dependent functions. + + - *Rationale*: Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix. + + - These functions are known to be locale-dependent: + `alphasort`, `asctime`, `asprintf`, `atof`, `atoi`, `atol`, `atoll`, `atoq`, + `btowc`, `ctime`, `dprintf`, `fgetwc`, `fgetws`, `fprintf`, `fputwc`, + `fputws`, `fscanf`, `fwprintf`, `getdate`, `getwc`, `getwchar`, `isalnum`, + `isalpha`, `isblank`, `iscntrl`, `isdigit`, `isgraph`, `islower`, `isprint`, + `ispunct`, `isspace`, `isupper`, `iswalnum`, `iswalpha`, `iswblank`, + `iswcntrl`, `iswctype`, `iswdigit`, `iswgraph`, `iswlower`, `iswprint`, + `iswpunct`, `iswspace`, `iswupper`, `iswxdigit`, `isxdigit`, `mblen`, + `mbrlen`, `mbrtowc`, `mbsinit`, `mbsnrtowcs`, `mbsrtowcs`, `mbstowcs`, + `mbtowc`, `mktime`, `putwc`, `putwchar`, `scanf`, `snprintf`, `sprintf`, + `sscanf`, `stoi`, `stol`, `stoll`, `strcasecmp`, `strcasestr`, `strcoll`, + `strfmon`, `strftime`, `strncasecmp`, `strptime`, `strtod`, `strtof`, + `strtoimax`, `strtol`, `strtold`, `strtoll`, `strtoq`, `strtoul`, + `strtoull`, `strtoumax`, `strtouq`, `strxfrm`, `swprintf`, `tolower`, + `toupper`, `towctrans`, `towlower`, `towupper`, `ungetwc`, `vasprintf`, + `vdprintf`, `versionsort`, `vfprintf`, `vfscanf`, `vfwprintf`, `vprintf`, + `vscanf`, `vsnprintf`, `vsprintf`, `vsscanf`, `vswprintf`, `vwprintf`, + `wcrtomb`, `wcscasecmp`, `wcscoll`, `wcsftime`, `wcsncasecmp`, `wcsnrtombs`, + `wcsrtombs`, `wcstod`, `wcstof`, `wcstoimax`, `wcstol`, `wcstold`, + `wcstoll`, `wcstombs`, `wcstoul`, `wcstoull`, `wcstoumax`, `wcswidth`, + `wcsxfrm`, `wctob`, `wctomb`, `wctrans`, `wctype`, `wcwidth`, `wprintf` + +Scripts +-------------------------- + +### Shebang + +- Use `#!/usr/bin/env bash` instead of obsolete `#!/bin/bash`. + + - [*Rationale*](https://github.com/dylanaraps/pure-bash-bible#shebang): + + `#!/bin/bash` assumes it is always installed to /bin/ which can cause issues; + + `#!/usr/bin/env bash` searches the user's PATH to find the bash binary. + + OK: + +```bash +#!/usr/bin/env bash +``` + + Wrong: + +```bash +#!/bin/bash +``` + +Source code organization +-------------------------- + +- Use include guards to avoid the problem of double inclusion. The header file + `foo/bar.h` should use the include guard identifier `ZCASH_FOO_BAR_H`, e.g. + +```c++ +#ifndef ZCASH_FOO_BAR_H +#define ZCASH_FOO_BAR_H +... +#endif // ZCASH_FOO_BAR_H +``` + +Subtrees +---------- + +Several parts of the repository are subtrees of software maintained elsewhere. + +Some of these are maintained by active developers of Zcash or Bitcoin Core, in which case changes should probably go +directly upstream without being PRed directly against the project. They will be merged back in the next +subtree merge. + +Others are external projects without a tight relationship with our project. Changes to these should also +be sent upstream, but bugfixes may also be prudent to PR against Zcash and/or Bitcoin Core so that they can be integrated +quickly. Cosmetic changes should be purely taken upstream. + +There is a tool in `test/lint/git-subtree-check.sh` ([instructions](../test/lint#git-subtree-checksh)) to check a subtree directory for consistency with +its upstream repository. + +Current subtrees include: + +- src/leveldb + - Upstream at https://github.com/google/leveldb ; Maintained by Google, but + open important PRs to Core to avoid delay. + - **Note**: Follow the instructions in [Upgrading LevelDB](#upgrading-leveldb) when + merging upstream changes to the LevelDB subtree. + +- src/secp256k1 + - Upstream at https://github.com/bitcoin-core/secp256k1/ ; actively maintained by Core contributors. + +- src/crypto/ctaes + - Upstream at https://github.com/bitcoin-core/ctaes ; actively maintained by Core contributors. + +- src/univalue + - Upstream at https://github.com/bitcoin-core/univalue ; actively maintained by Core contributors, deviates from upstream https://github.com/jgarzik/univalue + +Scripted diffs +-------------- + +For reformatting and refactoring commits where the changes can be easily automated using a bash script, we use +scripted-diff commits. The bash script is included in the commit message and our Travis CI job checks that +the result of the script is identical to the commit. This aids reviewers since they can verify that the script +does exactly what it's supposed to do. It is also helpful for rebasing (since the same script can just be re-run +on the new master commit). + +To create a scripted-diff: + +- start the commit message with `scripted-diff:` (and then a description of the diff on the same line) +- in the commit message include the bash script between lines containing just the following text: + + - `-BEGIN VERIFY SCRIPT-` + - `-END VERIFY SCRIPT-` + +The scripted-diff is verified by the tool `test/lint/commit-script-check.sh` + +Commit `ccd074a5` is an example of a scripted-diff. diff --git a/depend/zcash/doc/dnsseed-policy.md b/depend/zcash/doc/dnsseed-policy.md new file mode 100644 index 000000000..54d739a9a --- /dev/null +++ b/depend/zcash/doc/dnsseed-policy.md @@ -0,0 +1,6 @@ +Expectations for DNS Seed operators +==================================== + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/dnsseed_policy.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/dnsseed_policy.rst \ No newline at end of file diff --git a/depend/zcash/doc/files.md b/depend/zcash/doc/files.md new file mode 100644 index 000000000..b29865e58 --- /dev/null +++ b/depend/zcash/doc/files.md @@ -0,0 +1,5 @@ +# Data Directory Files + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/files.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/files.rst diff --git a/depend/zcash/doc/hotfix-process.md b/depend/zcash/doc/hotfix-process.md new file mode 100644 index 000000000..1dd60d7ae --- /dev/null +++ b/depend/zcash/doc/hotfix-process.md @@ -0,0 +1,49 @@ +Hotfix Release Process +====================== + +Hotfix releases are versioned by incrementing the patch number of the latest +release. For example: + + First hotfix: v1.0.0 -> v1.0.1 + Second hotfix: v1.0.1 -> v1.0.2 + +In the commands below, and are prefixed with a v, ie. +v1.0.2 (not 1.0.2). + +## Create a hotfix branch + +Create a hotfix branch from the previous release tag, and push it to the main +repository: + + $ git branch hotfix- + $ git push 'git@github.com:zcash/zcash' hotfix- + +## Implement hotfix changes + +Hotfix changes are implemented the same way as regular changes (developers work +in separate branches per change, and push the branches to their own repositories), +except that the branches are based on the hotfix branch instead of master: + + $ git checkout hotfix- + $ git checkout -b + +## Merge hotfix PRs + +Hotfix PRs are created like regular PRs, except using the hotfix branch as the +base instead of `master`. Each PR should be reviewed and merged as normal. + +## Release process + +The majority of this process is identical to the standard release process. +Release candidates for hotfixes should be created and tested as normal, using +the `hotfix-` branch in place of the release stabilization branch, +with a couple of minor differences: + +- When running the release script, use the `--hotfix` flag. Provide the hash of + the commit to be released as the first argument: + + $ ./zcutil/make-release.py --hotfix + +- To review the automated changes in git: + + $ git log hotfix-..HEAD diff --git a/depend/zcash/doc/imgs/logo.png b/depend/zcash/doc/imgs/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..52ea66ec32c7d3e53b1cc3ca6949e3aba0a5c6be GIT binary patch literal 10950 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 literal 0 HcmV?d00001 diff --git a/depend/zcash/doc/imgs/zcashd_screen.gif b/depend/zcash/doc/imgs/zcashd_screen.gif new file mode 100644 index 0000000000000000000000000000000000000000..2eebc1cba0846d0d1723eccd279616bb9b2b320e GIT binary patch literal 39787 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 z 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�#*QbG(%&0orG@y3v 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 IZ0P%c08QS;I{*Lx literal 0 HcmV?d00001 diff --git a/depend/zcash/doc/man/Makefile.am b/depend/zcash/doc/man/Makefile.am new file mode 100644 index 000000000..27917a208 --- /dev/null +++ b/depend/zcash/doc/man/Makefile.am @@ -0,0 +1 @@ +dist_man1_MANS=zcashd.1 zcash-cli.1 zcash-fetch-params.1 zcash-tx.1 diff --git a/depend/zcash/doc/man/zcash-cli.1 b/depend/zcash/doc/man/zcash-cli.1 new file mode 100644 index 000000000..38c89ee81 --- /dev/null +++ b/depend/zcash/doc/man/zcash-cli.1 @@ -0,0 +1,88 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH ZCASH-CLI "1" "May 2022" "zcash-cli v5.0.0" "User Commands" +.SH NAME +zcash-cli \- manual page for zcash-cli v5.0.0 +.SH DESCRIPTION +Zcash RPC client version v5.0.0 +.PP +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . +.SS "Usage:" +.TP +zcash\-cli [options] [params] +Send command to Zcash +.TP +zcash\-cli [options] help +List commands +.TP +zcash\-cli [options] help +Get help for a command +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: zcash.conf) +.HP +\fB\-datadir=\fR +.IP +Specify data directory (this path cannot use '~') +.HP +\fB\-stdin\fR +.IP +Read extra arguments from standard input, one per line until EOF/Ctrl\-D +(recommended for sensitive information such as passphrases). If first +extra argument is `walletpassphrase` then the first line(password) will +not be echoed. +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing tools +and app development. +.HP +\fB\-rpcconnect=\fR +.IP +Send commands to node running on (default: 127.0.0.1) +.HP +\fB\-rpcport=\fR +.IP +Connect to JSON\-RPC on (default: 8232 or testnet: 18232) +.HP +\fB\-rpcwait\fR +.IP +Wait for RPC server to start +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcclienttimeout=\fR +.IP +Timeout in seconds during HTTP requests, or 0 for no timeout. (default: +900) +.SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + +Copyright (C) 2009-2022 The Bitcoin Core Developers +Copyright (C) 2015-2022 The Zcash Developers + +This is experimental software. + +Distributed under the MIT software license, see the accompanying file COPYING +or . diff --git a/depend/zcash/doc/man/zcash-fetch-params.1 b/depend/zcash/doc/man/zcash-fetch-params.1 new file mode 100644 index 000000000..76dab4c23 --- /dev/null +++ b/depend/zcash/doc/man/zcash-fetch-params.1 @@ -0,0 +1,28 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. +.TH ZCASH-FETCH-PARAMS "1" "January 2017" "Zcash - zcash-fetch-params" "User Commands" +.SH NAME +zcash-fetch-params \- Downloads the Zcash network parameters +.SH DESCRIPTION +Zcash \- zcash-fetch\-params +.PP +This script will fetch the Zcash zkSNARK parameters and verify their +integrity with sha256sum. +.PP +If they already exist locally, it will exit now and do nothing else. +.PP +This script will fetch the Zcash zkSNARK parameters and verify their +integrity with sha256sum. +.PP +If they already exist locally, it will exit now and do nothing else. +.SH "SEE ALSO" +The full documentation for +.B Zcash +is maintained as a Texinfo manual. If the +.B info +and +.B Zcash +programs are properly installed at your site, the command +.IP +.B info Zcash +.PP +should give you access to the complete manual. diff --git a/depend/zcash/doc/man/zcash-tx.1 b/depend/zcash/doc/man/zcash-tx.1 new file mode 100644 index 000000000..79863fa8d --- /dev/null +++ b/depend/zcash/doc/man/zcash-tx.1 @@ -0,0 +1,100 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH ZCASH-TX "1" "May 2022" "zcash-tx v5.0.0" "User Commands" +.SH NAME +zcash-tx \- manual page for zcash-tx v5.0.0 +.SH DESCRIPTION +Zcash zcash\-tx utility version v5.0.0 +.SS "Usage:" +.TP +zcash\-tx [options] [commands] +Update hex\-encoded zcash transaction +.TP +zcash\-tx [options] \fB\-create\fR [commands] +Create hex\-encoded zcash transaction +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-create\fR +.IP +Create new, empty TX. +.HP +\fB\-json\fR +.IP +Select JSON output +.HP +\fB\-txid\fR +.IP +Output only the hex\-encoded transaction id of the resultant transaction. +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.HP +\fB\-regtest\fR +.IP +Enter regression test mode, which uses a special chain in which blocks +can be solved instantly. This is intended for regression testing tools +and app development. +.PP +Commands: +.IP +delin=N +.IP +Delete input N from TX +.IP +delout=N +.IP +Delete output N from TX +.IP +in=TXID:VOUT(:SEQUENCE_NUMBER) +.IP +Add input to TX +.IP +locktime=N +.IP +Set TX lock time to N +.IP +nversion=N +.IP +Set TX version to N +.IP +outaddr=VALUE:ADDRESS +.IP +Add address\-based output to TX +.IP +outscript=VALUE:SCRIPT +.IP +Add raw script output to TX +.IP +sign=HEIGHT:SIGHASH\-FLAGS +.IP +Add zero or more signatures to transaction. This command requires JSON +registers:prevtxs=JSON object, privatekeys=JSON object. See +signrawtransaction docs for format of sighash flags, JSON objects. +.PP +Register Commands: +.IP +load=NAME:FILENAME +.IP +Load JSON file FILENAME into register NAME +.IP +set=NAME:JSON\-STRING +.IP +Set register NAME to given JSON\-STRING +.SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + +Copyright (C) 2009-2022 The Bitcoin Core Developers +Copyright (C) 2015-2022 The Zcash Developers + +This is experimental software. + +Distributed under the MIT software license, see the accompanying file COPYING +or . diff --git a/depend/zcash/doc/man/zcashd-wallet-tool.1 b/depend/zcash/doc/man/zcashd-wallet-tool.1 new file mode 100644 index 000000000..4adf72a35 --- /dev/null +++ b/depend/zcash/doc/man/zcashd-wallet-tool.1 @@ -0,0 +1,53 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH ZCASHD-WALLET-TOOL "1" "May 2022" "zcashd-wallet-tool v5.0.0" "User Commands" +.SH NAME +zcashd-wallet-tool \- manual page for zcashd-wallet-tool v5.0.0 +.SH SYNOPSIS +.B zcashd-wallet-tool +[\fI\,OPTIONS\/\fR] +.SH DESCRIPTION +.SS "Optional arguments:" +.TP +\fB\-\-help\fR +Print this help output +.TP +\fB\-\-conf\fR FILENAME +Specify configuration filename, relative to the data directory (default: zcash.conf) +.TP +\fB\-\-datadir\fR PATH +Specify data directory (this path cannot use '~') +.TP +\fB\-\-testnet\fR +Use the test chain +.TP +\fB\-\-rpcconnect\fR IPADDR +Send commands to node running on IPADDR (default: 127.0.0.1) +.TP +\fB\-\-rpcport\fR PORT +Connect to JSON\-RPC on PORT (default: 8232 or testnet: 18232) +.TP +\fB\-\-rpcuser\fR USERNAME +Username for JSON\-RPC connections +.TP +\fB\-\-rpcpassword\fR PASSWORD +Password for JSON\-RPC connections +.TP +\fB\-\-rpcclienttimeout\fR SECONDS +Timeout in seconds during HTTP requests, or 0 for no timeout. (default: 900) +.PP +Options can be given in GNU style (`\-\-conf=CONF` or `\-\-conf CONF`), +or in Bitcoin style with a single hyphen (`\-conf=CONF`). +.PP +The environment variable RUST_LOG controls debug output, e.g. +`RUST_LOG=debug`. +.SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + +Copyright (C) 2015-2022 The Zcash Developers + +This is experimental software. + +Distributed under the MIT software license, see the accompanying file COPYING +or . diff --git a/depend/zcash/doc/man/zcashd.1 b/depend/zcash/doc/man/zcashd.1 new file mode 100644 index 000000000..186b1518a --- /dev/null +++ b/depend/zcash/doc/man/zcashd.1 @@ -0,0 +1,593 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. +.TH ZCASHD "1" "May 2022" "zcashd v5.0.0" "User Commands" +.SH NAME +zcashd \- manual page for zcashd v5.0.0 +.SH DESCRIPTION +Zcash Daemon version v5.0.0 +.PP +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . +.SS "Usage:" +.TP +zcashd [options] +Start Zcash Daemon +.SH OPTIONS +.HP +\-? +.IP +This help message +.HP +\fB\-alerts\fR +.IP +Receive and display P2P network alerts (default: 1) +.HP +\fB\-alertnotify=\fR +.IP +Execute command when a relevant alert is received or we see a really +long fork (%s in cmd is replaced by message) +.HP +\fB\-allowdeprecated=\fR +.IP +Explicitly allow the use of the specified deprecated feature. Multiple +instances of this parameter are permitted; values for must be +selected from among {"none", "addrtype", "getnewaddress", +"getrawchangeaddress", "legacy_privacy", "z_getbalance", +"z_getnewaddress", "z_gettotalbalance", "z_listaddresses", +"zcrawjoinsplit", "zcrawkeygen", "zcrawreceive"} +.HP +\fB\-blocknotify=\fR +.IP +Execute command when the best block changes (%s in cmd is replaced by +block hash) +.HP +\fB\-checkblocks=\fR +.IP +How many blocks to check at startup (default: 288, 0 = all) +.HP +\fB\-checklevel=\fR +.IP +How thorough the block verification of \fB\-checkblocks\fR is (0\-4, default: 3) +.HP +\fB\-conf=\fR +.IP +Specify configuration file (default: zcash.conf) +.HP +\fB\-daemon\fR +.IP +Run in the background as a daemon and accept commands +.HP +\fB\-datadir=\fR +.IP +Specify data directory (this path cannot use '~') +.HP +\fB\-paramsdir=\fR +.IP +Specify Zcash network parameters directory +.HP +\fB\-dbcache=\fR +.IP +Set database cache size in megabytes (4 to 16384, default: 450) +.HP +\fB\-debuglogfile=\fR +.IP +Specify location of debug log file: this can be an absolute path or a +path relative to the data directory (default: debug.log) +.HP +\fB\-exportdir=\fR +.IP +Specify directory to be used when exporting data +.HP +\fB\-ibdskiptxverification\fR +.IP +Skip transaction verification during initial block download up to the +last checkpoint height. Incompatible with flags that disable +checkpoints. (default = 0) +.HP +\fB\-loadblock=\fR +.IP +Imports blocks from external blk000??.dat file on startup +.HP +\fB\-maxorphantx=\fR +.IP +Keep at most unconnectable transactions in memory (default: 100) +.HP +\fB\-par=\fR +.IP +Set the number of script verification threads (\fB\-16\fR to 16, 0 = auto, <0 = +leave that many cores free, default: 0) +.HP +\fB\-pid=\fR +.IP +Specify pid file (default: zcashd.pid) +.HP +\fB\-prune=\fR +.IP +Reduce storage requirements by pruning (deleting) old blocks. This mode +disables wallet support and is incompatible with \fB\-txindex\fR. Warning: +Reverting this setting requires re\-downloading the entire blockchain. +(default: 0 = disable pruning blocks, >550 = target size in MiB to use +for block files) +.HP +\fB\-reindex\-chainstate\fR +.IP +Rebuild chain state from the currently indexed blocks (implies \fB\-rescan\fR +unless pruning or unless \fB\-rescan\fR=\fI\,0\/\fR is explicitly specified) +.HP +\fB\-reindex\fR +.IP +Rebuild chain state and block index from the blk*.dat files on disk +(implies \fB\-rescan\fR unless pruning or unless \fB\-rescan\fR=\fI\,0\/\fR is explicitly +specified) +.HP +\fB\-sysperms\fR +.IP +Create new files with system default permissions, instead of umask 077 +(only effective with disabled wallet functionality) +.HP +\fB\-txexpirynotify=\fR +.IP +Execute command when transaction expires (%s in cmd is replaced by +transaction id) +.HP +\fB\-txindex\fR +.IP +Maintain a full transaction index, used by the getrawtransaction rpc +call (default: 0) +.PP +Connection options: +.HP +\fB\-addnode=\fR +.IP +Add a node to connect to and attempt to keep the connection open +.HP +\fB\-banscore=\fR +.IP +Threshold for disconnecting misbehaving peers (default: 100) +.HP +\fB\-bantime=\fR +.IP +Number of seconds to keep misbehaving peers from reconnecting (default: +86400) +.HP +\fB\-bind=\fR +.IP +Bind to given address and always listen on it. Use [host]:port notation +for IPv6 +.HP +\fB\-connect=\fR +.IP +Connect only to the specified node(s); \fB\-noconnect\fR or \fB\-connect\fR=\fI\,0\/\fR alone to +disable automatic connections +.HP +\fB\-discover\fR +.IP +Discover own IP addresses (default: 1 when listening and no \fB\-externalip\fR +or \fB\-proxy\fR) +.HP +\fB\-dns\fR +.IP +Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR (default: 1) +.HP +\fB\-dnsseed\fR +.IP +Query for peer addresses via DNS lookup, if low on addresses (default: 1 +unless \fB\-connect\fR/\-noconnect) +.HP +\fB\-externalip=\fR +.IP +Specify your own public address +.HP +\fB\-forcednsseed\fR +.IP +Always query for peer addresses via DNS lookup (default: 0) +.HP +\fB\-listen\fR +.IP +Accept connections from outside (default: 1 if no \fB\-proxy\fR or +\fB\-connect\fR/\-noconnect) +.HP +\fB\-listenonion\fR +.IP +Automatically create Tor hidden service (default: 1) +.HP +\fB\-maxconnections=\fR +.IP +Maintain at most connections to peers (default: 125) +.HP +\fB\-maxreceivebuffer=\fR +.IP +Maximum per\-connection receive buffer, *1000 bytes (default: 5000) +.HP +\fB\-maxsendbuffer=\fR +.IP +Maximum per\-connection send buffer, *1000 bytes (default: 1000) +.HP +\fB\-mempoolevictionmemoryminutes=\fR +.IP +The number of minutes before allowing rejected transactions to re\-enter +the mempool. (default: 60) +.HP +\fB\-mempooltxcostlimit=\fR +.IP +An upper bound on the maximum size in bytes of all transactions in the +mempool. (default: 80000000) +.HP +\fB\-onion=\fR +.IP +Use separate SOCKS5 proxy to reach peers via Tor hidden services +(default: \fB\-proxy\fR) +.HP +\fB\-onlynet=\fR +.IP +Only connect to nodes in network (ipv4, ipv6 or onion) +.HP +\fB\-permitbaremultisig\fR +.IP +Relay non\-P2SH multisig (default: 1) +.HP +\fB\-peerbloomfilters\fR +.IP +Support filtering of blocks and transaction with bloom filters (default: +1) +.HP +\fB\-port=\fR +.IP +Listen for connections on (default: 8233 or testnet: 18233) +.HP +\fB\-proxy=\fR +.IP +Connect through SOCKS5 proxy +.HP +\fB\-proxyrandomize\fR +.IP +Randomize credentials for every proxy connection. This enables Tor +stream isolation (default: 1) +.HP +\fB\-seednode=\fR +.IP +Connect to a node to retrieve peer addresses, and disconnect +.HP +\fB\-timeout=\fR +.IP +Specify connection timeout in milliseconds (minimum: 1, default: 5000) +.HP +\fB\-torcontrol=\fR: +.IP +Tor control port to use if onion listening enabled (default: +127.0.0.1:9051) +.HP +\fB\-torpassword=\fR +.IP +Tor control port password (default: empty) +.HP +\fB\-whitebind=\fR +.IP +Bind to given address and whitelist peers connecting to it. Use +[host]:port notation for IPv6 +.HP +\fB\-whitelist=\fR +.IP +Whitelist peers connecting from the given netmask or IP address. Can be +specified multiple times. Whitelisted peers cannot be DoS banned and +their transactions are always relayed, even if they are already in the +mempool, useful e.g. for a gateway +.HP +\fB\-whitelistrelay\fR +.IP +Accept relayed transactions received from whitelisted inbound peers even +when not relaying transactions (default: 1) +.HP +\fB\-whitelistforcerelay\fR +.IP +Force relay of transactions from whitelisted inbound peers even they +violate local relay policy (default: 1) +.HP +\fB\-maxuploadtarget=\fR +.IP +Tries to keep outbound traffic under the given target (in MiB per 24h), +0 = no limit (default: 0) +.PP +Wallet options: +.HP +\fB\-disablewallet\fR +.IP +Do not load the wallet and disable wallet RPC calls +.HP +\fB\-keypool=\fR +.IP +Set key pool size to (default: 100) +.HP +\fB\-migration\fR +.IP +Enable the Sprout to Sapling migration +.HP +\fB\-migrationdestaddress=\fR +.IP +Set the Sapling migration address +.HP +\fB\-mintxfee=\fR +.IP +Fees (in ZEC/kB) smaller than this are considered zero fee for +transaction creation (default: 0.00001) +.HP +\fB\-orchardactionlimit=\fR +.IP +Set the maximum number of Orchard actions permitted in a transaction +(default 50) +.HP +\fB\-paytxfee=\fR +.IP +Fee (in ZEC/kB) to add to transactions you send (default: 0.00) +.HP +\fB\-rescan\fR +.IP +Rescan the block chain for missing wallet transactions on startup +.HP +\fB\-salvagewallet\fR +.IP +Attempt to recover private keys from a corrupt wallet on startup +(implies \fB\-rescan\fR) +.HP +\fB\-sendfreetransactions\fR +.IP +Send transactions as zero\-fee transactions if possible (default: 0) +.HP +\fB\-spendzeroconfchange\fR +.IP +Spend unconfirmed change when sending transactions (default: 1) +.HP +\fB\-txconfirmtarget=\fR +.IP +If paytxfee is not set, include enough fee so transactions begin +confirmation on average within n blocks (default: 2) +.HP +\fB\-txexpirydelta\fR +.IP +Set the number of blocks after which a transaction that has not been +mined will become invalid (min: 4, default: 20 (pre\-Blossom) or 40 +(post\-Blossom)) +.HP +\fB\-upgradewallet\fR +.IP +Upgrade wallet to latest format on startup +.HP +\fB\-wallet=\fR +.IP +Specify wallet file absolute path or a path relative to the data +directory (default: wallet.dat) +.HP +\fB\-walletbroadcast\fR +.IP +Make the wallet broadcast transactions (default: 1) +.HP +\fB\-walletnotify=\fR +.IP +Execute command when a wallet transaction changes (%s in cmd is replaced +by TxID) +.HP +\fB\-zapwallettxes=\fR +.IP +Delete all wallet transactions and only recover those parts of the +blockchain through \fB\-rescan\fR on startup (1 = keep tx meta data e.g. +account owner and payment request information, 2 = drop tx meta data) +.HP +\fB\-walletrequirebackup=\fR +.IP +By default, the wallet will not allow generation of new spending keys & +addresses from the mnemonic seed until the backup of that seed has been +confirmed with the `zcashd\-wallet\-tool` utility. A user may start zcashd +with `\-walletrequirebackup=false` to allow generation of spending keys +even if the backup has not yet been confirmed. +.PP +ZeroMQ notification options: +.HP +\fB\-zmqpubhashblock=\fR
+.IP +Enable publish hash block in
+.HP +\fB\-zmqpubhashtx=\fR
+.IP +Enable publish hash transaction in
+.HP +\fB\-zmqpubrawblock=\fR
+.IP +Enable publish raw block in
+.HP +\fB\-zmqpubrawtx=\fR
+.IP +Enable publish raw transaction in
+.PP +Monitoring options: +.HP +\fB\-metricsallowip=\fR +.IP +Allow metrics connections from specified source. Valid for are a +single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) +or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified +multiple times. (default: only localhost) +.HP +\fB\-metricsbind=\fR +.IP +Bind to given address to listen for metrics connections. (default: bind +to all interfaces) +.HP +\fB\-prometheusport=\fR +.IP +Expose node metrics in the Prometheus exposition format. An HTTP +listener will be started on , which responds to GET requests on +any request path. Use \fB\-metricsallowip\fR and \fB\-metricsbind\fR to control +access. +.PP +Debugging/Testing options: +.HP +\fB\-debug=\fR +.IP +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, mempoolrej, net, +partitioncheck, pow, proxy, prune, rand, receiveunsafe, reindex, rpc, +selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc). For multiple +specific categories use \fB\-debug=\fR multiple times. +.HP +\fB\-experimentalfeatures\fR +.IP +Enable use of experimental features +.HP +\fB\-help\-debug\fR +.IP +Show all debugging options (usage: \fB\-\-help\fR \fB\-help\-debug\fR) +.HP +\fB\-logips\fR +.IP +Include IP addresses in debug output (default: 0) +.HP +\fB\-logtimestamps\fR +.IP +Prepend debug output with timestamp (default: 1) +.HP +\fB\-minrelaytxfee=\fR +.IP +Fees (in ZEC/kB) smaller than this are considered zero fee for relaying, +mining and transaction creation (default: 0.000001) +.HP +\fB\-maxtxfee=\fR +.IP +Maximum total fees (in ZEC) to use in a single wallet transaction or raw +transaction; setting this too low may abort large transactions (default: +0.10) +.HP +\fB\-printtoconsole\fR +.IP +Send trace/debug info to console instead of debug.log file +.PP +Chain selection options: +.HP +\fB\-testnet\fR +.IP +Use the test chain +.PP +Node relay options: +.HP +\fB\-datacarrier\fR +.IP +Relay and mine data carrier transactions (default: 1) +.HP +\fB\-datacarriersize\fR +.IP +Maximum size of data in data carrier transactions we relay and mine +(default: 83) +.PP +Block creation options: +.HP +\fB\-blockminsize=\fR +.IP +Set minimum block size in bytes (default: 0) +.HP +\fB\-blockmaxsize=\fR +.IP +Set maximum block size in bytes (default: 2000000) +.HP +\fB\-blockprioritysize=\fR +.IP +Set maximum size of high\-priority/low\-fee transactions in bytes +(default: 1000000) +.PP +Mining options: +.HP +\fB\-gen\fR +.IP +Generate coins (default: 0) +.HP +\fB\-genproclimit=\fR +.IP +Set the number of threads for coin generation if enabled (\fB\-1\fR = all +cores, default: 1) +.HP +\fB\-equihashsolver=\fR +.IP +Specify the Equihash solver to be used if enabled (default: "default") +.HP +\fB\-mineraddress=\fR +.IP +Send mined coins to a specific single address +.HP +\fB\-minetolocalwallet\fR +.IP +Require that mined blocks use a coinbase address in the local wallet +(default: 1) +.PP +RPC server options: +.HP +\fB\-server\fR +.IP +Accept command line and JSON\-RPC commands +.HP +\fB\-rest\fR +.IP +Accept public REST requests (default: 0) +.HP +\fB\-rpcbind=\fR +.IP +Bind to given address to listen for JSON\-RPC connections. Use +[host]:port notation for IPv6. This option can be specified multiple +times (default: bind to all interfaces) +.HP +\fB\-rpcuser=\fR +.IP +Username for JSON\-RPC connections +.HP +\fB\-rpcpassword=\fR +.IP +Password for JSON\-RPC connections +.HP +\fB\-rpcauth=\fR +.IP +Username and hashed password for JSON\-RPC connections. The field + comes in the format: :$. A canonical +python script is included in share/rpcuser. This option can be specified +multiple times +.HP +\fB\-rpcport=\fR +.IP +Listen for JSON\-RPC connections on (default: 8232 or testnet: +18232) +.HP +\fB\-rpcallowip=\fR +.IP +Allow JSON\-RPC connections from specified source. Valid for are a +single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) +or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified +multiple times +.HP +\fB\-rpcthreads=\fR +.IP +Set the number of threads to service RPC calls (default: 4) +.PP +Metrics Options (only if \fB\-daemon\fR and \fB\-printtoconsole\fR are not set): +.HP +\fB\-showmetrics\fR +.IP +Show metrics on stdout (default: 1 if running in a console, 0 otherwise) +.HP +\fB\-metricsui\fR +.IP +Set to 1 for a persistent metrics screen, 0 for sequential metrics +output (default: 1 if running in a console, 0 otherwise) +.HP +\fB\-metricsrefreshtime\fR +.IP +Number of seconds between metrics refreshes (default: 1 if running in a +console, 600 otherwise) +.SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + +Copyright (C) 2009-2022 The Bitcoin Core Developers +Copyright (C) 2015-2022 The Zcash Developers + +This is experimental software. + +Distributed under the MIT software license, see the accompanying file COPYING +or . diff --git a/depend/zcash/doc/payment-api.md b/depend/zcash/doc/payment-api.md new file mode 100644 index 000000000..786fb6f3c --- /dev/null +++ b/depend/zcash/doc/payment-api.md @@ -0,0 +1,5 @@ +# Zcash Payment API + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/payment_api.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/payment_api.rst \ No newline at end of file diff --git a/depend/zcash/doc/payment-disclosure.md b/depend/zcash/doc/payment-disclosure.md new file mode 100644 index 000000000..d0aa68a96 --- /dev/null +++ b/depend/zcash/doc/payment-disclosure.md @@ -0,0 +1,107 @@ +# 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 ZEC 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): + + zcash-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: + + zcash-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/depend/zcash/doc/reduce-traffic.md b/depend/zcash/doc/reduce-traffic.md new file mode 100644 index 000000000..e5ccd8ca2 --- /dev/null +++ b/depend/zcash/doc/reduce-traffic.md @@ -0,0 +1,55 @@ +Reduce Traffic +============== + +Some node operators need to deal with bandwidth caps imposed by their ISPs. + +By default, bitcoin-core allows up to 125 connections to different peers, 8 of +which are outbound. You can therefore, have at most 117 inbound connections. + +The default settings can result in relatively significant traffic consumption. + +Ways to reduce traffic: + +## 1. Use `-maxuploadtarget=` + +A major component of the traffic is caused by serving historic blocks to other nodes +during the initial blocks download phase (syncing up a new node). +This option can be specified in MiB per day and is turned off by default. +This is *not* a hard limit; only a threshold to minimize the outbound +traffic. When the limit is about to be reached, the uploaded data is cut by no +longer serving historic blocks (blocks older than one week). +Keep in mind that new nodes require other nodes that are willing to serve +historic blocks. **The recommended minimum is 1152 blocks per day (max. 2304MB +per day)** + +Whitelisted peers will never be disconnected, although their traffic counts for +calculating the target. + +## 2. Disable "listening" (`-listen=0`) + +Disabling listening will result in fewer nodes connected (remember the maximum of 8 +outbound peers). Fewer nodes will result in less traffic usage as you are relaying +blocks and transactions to fewer nodes. + +## 3. Reduce maximum connections (`-maxconnections=`) + +Reducing the maximum connected nodes to a minimum could be desirable if traffic +limits are tiny. Keep in mind that bitcoin's trustless model works best if you are +connected to a handful of nodes. + +## 4. Turn off transaction relay (`-blocksonly`) + +Forwarding transactions to peers increases the P2P traffic. To only sync blocks +with other peers, you can disable transaction relay. + +Be reminded of the effects of this setting. + +- Fee estimation will no longer work. +- It sets the flag "-walletbroadcast" to be "0", only if it is currently unset. + Doing so disables the automatic broadcasting of transactions from the wallet. Not + relaying other's transactions could hurt your privacy if used while the wallet + is loaded or if you use the node to broadcast transactions. +- If a peer is whitelisted and "-whitelistforcerelay" is set to "1" (which will + also set "whitelistrelay" to "1"), we will still receive and relay their transactions. +- It makes block propagation slower because compact block relay can only be + used when transaction relay is enabled. diff --git a/depend/zcash/doc/reducing-memory-usage.md b/depend/zcash/doc/reducing-memory-usage.md new file mode 100644 index 000000000..333ea0086 --- /dev/null +++ b/depend/zcash/doc/reducing-memory-usage.md @@ -0,0 +1,8 @@ +In-memory caches +---------------- + +The size of some in-memory caches can be reduced. As caches trade off memory usage for performance, usually reducing these have a negative effect on performance. + +- `-dbcache=` - the UTXO database cache size, this defaults to `450` (`100` before 1.0.15). The unit is MiB (where 1 GiB = 1024 MiB). + - The minimum value for `-dbcache` is 4. + - A lower dbcache make initial sync time much longer. After the initial sync, the effect is less pronounced for most use-cases, unless fast validation of blocks is important such as for mining. diff --git a/depend/zcash/doc/release-notes.md b/depend/zcash/doc/release-notes.md new file mode 100644 index 000000000..a29094b51 --- /dev/null +++ b/depend/zcash/doc/release-notes.md @@ -0,0 +1,6 @@ +(note: this is a temporary file, to be added-to by anybody, and moved to +release-notes at release time) + +Notable changes +=============== + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z2.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z2.md new file mode 100644 index 000000000..107a86c7a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z2.md @@ -0,0 +1,35 @@ +Daira Hopwood (2): + Add Code of Conduct. fixes #802 + Specify Sean as the second contact for conduct issues. + +Jack Grigg (6): + Implement validator and basic solver for Equihash + Add test vectors for Equihash + Use Equihash for Proof-of-Work + Adjust genesis blocks to have valid solutions and hashes + Fix tests that depend on old block header format + Fix pow_tests to work with Equihash + +Nathan Wilcox (4): + Log all failing rpc tests concisely. + Apply a patch from Sean to update wallet to use our new founders-reward aware balances. + Fix (most) rpc tests by updating balances. zcpour, zcpourdoublespend, and txn_doublespend currently fail. + Update a bunch of docs by adding a banner, delete a bunch of known bitrot docs; does not update release-process.md. + +Sean Bowe (5): + Fix miner_tests to work with equihash + Add missing synchronization that causes race condition in test. + Implementation of Founders' Reward. + Fix remaining RPC tests. + Change pchMessageStart for new testnet. + +Taylor Hornby (8): + Add automated performance measurement system. + Add equihash solving benchmarks + Add JoinSplit verification benchmarks + Add verify equihash benchmark + Don't leave massif.out lying around after the benchmarks + Use a separate datadir for the benchmarks + Make benchmark specified by command-line arguments + Benchmark a random equihash input. + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z3.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z3.md new file mode 100644 index 000000000..656c0df7d --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z3.md @@ -0,0 +1,69 @@ +Daira Hopwood (1): + zkSNARK: Add constraint that the total value in a JoinSplit is a 64-bit integer. + +Nathan Wilcox (4): + Add a depends description for googletest. + Add a zcash-gtest binary to our build with a single tautological test. + Add coverage support scoped to only the zcash-gtest run; invoke with make zcash-cov; make cov is a superset. + Add googlemock 1.7.0 dependency. + +Sean Bowe (49): + Add serialization for primitive boost::optional. + New implementation of incremental merkle tree + Integrate new incremental merkle tree implementation into consensus. + Test old tree along with new tree as much as possible. + Deprecate the old tree and remove old tree tests from the test suite. + Initialize curve/field parameters in case another test hasn't done so. + Improve well-formedness checks and add additional serialization/deserialization tests. + Add more well-formedness checks/tests to tree. + Make appending algorithm more succinct. + Move incremental merkle tree tests to zcash-gtest. + NoteEncryption implementation and integration, removal of ECIES and crypto++ dependencies. + Move NoteEncryption tests to gtest suite. + Add additional tests for ephemeral key behavior. + Clarify the usage of decryption API. + Check exception has specific string message. + Small nit fixes + Run `zcash-gtest` in `make check` and fix performance tests. + Perform zerocash tests as part of full-test-suite, in preparation for removal of zerocash waterfall. + Distinguish the failure cases of wfcheck in tree. + Change ciphertext length to match protocol spec, and refactor the use of constants. + Initialize libsodium in the gtest suite. + Introduce new `libzcash` Zcash protocol API and crypto constructions surrounding the zkSNARK circuit. + zkSNARK: Foundations of circuit design and verification logic. + zkSNARK: Add "zero" constant variable. + zkSNARK: Enforce spend-authority of input notes. + zkSNARK: Enforce disclosure of input note nullifiers + zkSNARK: Authenticate h_sig with a_sk + zkSNARK: Enforce that new output notes have unique `rho` to prevent faerie gold attack. + zkSNARK: Enforce disclosure of commitments to output notes. + zkSNARK: Ensure that values balance correctly. + zkSNARK: Witness commitments to input notes. + zkSNARK: Enforce merkle authentication path from nonzero-valued public inputs to root. + libzcash: Add tests for API + Remove scriptPubKey/scriptSig from CPourTx, and add randomSeed. + Transplant of libzcash. + Added public zkSNARK parameter generation utility. + Stop testing old tree against new tree. + Remove nearly all of libzerocash. + Update public zkSNARK parameters for new circuit. + Fix performance measurements due to modified transaction structure. + Remove the zerocash tests from the full test suite. + Protect-style joinsplits should anchor to the latest root for now, until #604 is resolved. + Use inheritance for PRF gadgets. + Rename ZCASH_ constants to ZC_. + Rename hmac -> mac in circuit. + `Note` values should be little-endian byte order. + Update zkSNARK proving/verifying keys. + Add h_sig test vectors. + Change testnet network magics. + +Taylor Hornby (7): + Add check that vpubs are not both nonzero and test it. + Fix sighash tests + Add empty merkle/noteencryption tests so Sean can rebase. + Fix RPC tests + Rename bitcoin.conf and bitcoind.pid to zcash.conf and zcashd.pid in qa/ and src/ + Trivial change: Capitalize the Z in Zerocash + Remove the Merkle tree hash function's fixed point. + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z4.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z4.md new file mode 100644 index 000000000..cbdbafc26 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z4.md @@ -0,0 +1,70 @@ +Alex (1): + add sha256sum support for Mac OS X + +Alfie John (1): + Rename libzerocash to libzcash + +Jack Grigg (21): + Implement mining slow start with a linear ramp + Update subsidy tests to account for mining slow start + Update miner tests to account for mining slow start + Disable mining slow start in regtest mode + Fix failing miner test + Add Zcash revision to version strings + Bitcoin -> Zcash in version and help text + Add Zcash Developers to CLI copyright notice + Minor error message tweak + Refactor StepRow to make optimisation easier + Cleanups + Implement index-truncation Equihash optimisation + Store truncated indices in the same char* as the hash (H/T tromp for the idea!) + Use template parameters to statically initialise Equihash + Merge *StepRow XOR and trimming operations + Use comparator object for sorting StepRows + Store full indices in the same char* as the hash + Use fixed-width array for storing hash and indices + Use optimised Equihash solver for miner and benchmarks + Fix comment + Fix nits after review + +Nathan Wilcox (1): + Fix a test name bug so that ``make cov-zcash`` correctly runs the ``zcash-gtest`` binary. Fixes #946. + +Sean Bowe (14): + Refactor PRF_gadget to hand responsibility to PRF_addr_a_pk_gadget for creating the '0' argument to the PRF. + Enforce first four bits are zero for all spending keys and phi. + Enable binary serializations of proofs and r1cs keys, and make the `CPourTx` proof field fixed-size. + Reorder fields of CPourTx to reflect the spec. + Update proving key and tests that depend on transaction structure changes + Enable MULTICORE proving behavior with omp. + Pass `-fopenmp` at compile-time to enable MULTICORE. + Switch to Ed25519 for cryptographic binding of joinsplits to transactions. + Enforce that the `S` value of the ed25519 signature is smaller than the group order to prevent malleability attacks. + Use joinsplit_sig_t in more places. + Wrap lines in *CTransaction constructors. + Change error for invalid joinsplit signature for consistency. + Add additional assertions. + Update performance measurement transaction. + +Simon (2): + Remove Bitcoin testnet seeds. + Remove Bitcoin mainnet seeds. + +Taylor Hornby (16): + Fix build warnings in sighash tests. + Fix FORTIFY_SOURCE build errors. + Use HARDENED_CPPFLAGS in the Makefile consistently. + Use left shift instead of floating-point pow() in equihash. + Ignore deprecated declaration warnings. + Remove unused code in libzerocash util.cpp + Turn on -Werror for the Zcash build. + Patch libsnark to build with my compiler. Upstream PR #35. + Hide new Boost warnings on GCC 6. + Add ability to run things under valgrind. + Pass -DPURIFY to OpenSSL so it doesn't clutter valgrind output. + Enable -v for valgrind so we can see counts for each error. + Sign JoinSplit transactions + We don't want to benchmark signature creation / verification. + Implement signature verification in CheckTransaction + Fix tests for JoinSplit signatures + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z5.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z5.md new file mode 100644 index 000000000..5c86083ff --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z5.md @@ -0,0 +1,78 @@ +Ethan Heilman (1): + Increase test coverage for addrman and addrinfo + +EthanHeilman (1): + Creates unittests for addrman, makes addrman testable. Adds several unittests for addrman to verify it works as expected. Makes small modifications to addrman to allow deterministic and targeted tests. + +Jack Grigg (24): + Use depth-first scan for eliminating partial solutions instead of breadth-first + Add a 256-bit reserved field to the block header + Set -relaypriority default to false + Regenerate genesis blocks + Update tests to account for reserved field + Update RPC tests to account for reserved field + Decrease block interval to 2.5 minutes + Update tests to account for decreased block interval + Update RPC tests to account for decreased block interval + Updated a hard-coded number of blocks to account for decreased block interval + Fix failing tests + Increase Equihash parameters to n = 96, k = 3 (about 430 MiB) + Update tests to account for new Equihash parameters + Speed up FullStepRow index comparison by leveraging big-endian byte layout + Use little-endian for hash personalisation and hashing indices + Use htole32 and htobe32 for endian conversions + Regenerate genesis blocks + Update miner tests for platform-independent Equihash + Tweaks after review + Implement new difficulty algorithm (#931) + Update tests for new difficulty algorithm + Improve comments per review + Handle full Zcash version string in AC_INIT + Fix bug in network hashrate lookup window configuration + +Patrick Strateman (1): + CAddrMan::Deserialize handle corrupt serializations better. + +Philip Kaufmann (1): + remove using namespace std from addrman.cpp + +Sean Bowe (28): + Move new coins tests to within coins_tests test suite. + Ensure merkle tree fixed point removal is tested against inside coins_tests. + Allow pours to be anchored to intermediate treestates of a transaction. + Test behavior of chained pour consensus rules. + Remove redundant constraints. + Change merkle tree depth to 29. + Update the zkSNARK parameters. + Add test to ensure parent treestates only can appear earlier in the transaction or in the global state, not later. + Minor changes to coins_tests. + Rename `CheckInputs` to `ContextualCheckInputs` since it relies on a global variable and assumes calling conditions. + Refactor contextual and noncontextual input checks. + Prevent coinbases from being spent to transparent outputs. + Disable coinbase-must-be-protected rule on regtest. + Ensure mempool integrity checks don't trip on chained joinsplits. + Enforce BIP16 and BIP30 unconditionally to all blocks. + Enforce remaining softfork activation rules unconditionally. + Ensure NonContextualCheckInputs runs before routines in ContextualCheckInputs. + Rename to `fCoinbaseMustBeProtected`. + Disable enforced coinbase protection in miner_tests. + Do not encode leading bytes in `PaymentAddress` serialization; this is a task for a higher-level API. + Use base58check to encode Zcash payment addresses, such that the first two bytes are "zc". + Add tests for `CZCPaymentAddress`. + Fix test against merkle tree root. + Added encoding for Zcash spending keys. + Guarantee first two bytes of spending key are SK + Make testnet addresses always start with 'tn'. + Add test to ensure spending keys always encode with 'SK' at beginning. + Testnet spending keys should start with 'TK'. + +Simon (5): + Fix issue #717 where if addrman is starved of addresses (e.g. on testnet) the Select_() function will loop endlessly trying to find an address, and therefore eat up 100% cpu time on the 'opencon' thread. + Declare constants for the maximum number of retries, when to sleep between retries and how long for. + Implement issue #997 to reduce time for test_bitcoin due to sleeps in addrman. Related to issue #717. + Update to DistinctIndices function (for issue #857). Replaces pull request #974. + Update variable name. + +Taylor Hornby (1): + Enable -alertnotify for hard fork detection. Test it. + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z6.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z6.md new file mode 100644 index 000000000..5d6054509 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z6.md @@ -0,0 +1,18 @@ +Jack Grigg (4): + Equihash: Only compare the first n/(k+1) bits when sorting. + Randomise the nonce in the block header. + Clear mempool before using it for benchmark test, fix parameter name. + Fix memory leak in large tx benchmark. + +Sean Bowe (5): + Increase block size to 2MB and update performance test. + Make sigop limit `20000` just as in Bitcoin, ignoring our change to the blocksize limit. + Remove the mainnet checkpoints. + Fix performance test for block verification. + Make `validatelargetx` test more accurate. + +Taylor Hornby (1): + Add example mock test of CheckTransaction. + +aniemerg (1): + Suppress Libsnark Debugging Info. diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z7.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z7.md new file mode 100644 index 000000000..a6a14af96 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z7.md @@ -0,0 +1,90 @@ +Daira Hopwood (2): + .clang-format: change standard to C++11 + Bucket -> note. + +Jack Grigg (4): + Collect all permutations of final solutions + Add test case that requires the fix + Reinstate previous testnet adjustment behaviour + Hardfork to the previous testnet difficulty adjustment behaviour at block 43400 + +Nathan Wilcox (1): + A script to remove "unofficial" tags from a remote, such as github. + +Sean Bowe (36): + Flush to disk more consistently by accounting memory usage of serials/anchors in cache. + Always check valid joinsplits during performance tests, and avoid recomputing them every time we change the circuit. + Remove the rest of libzerocash. + Update tests with cache usage computations + Reorder initialization routines to ensure verifying key log messages appear in debug.log. + Remove zerocash tests from full-test-suite. + Rename samplepour to samplejoinsplit + Update libsnark to our fork. + Initialize libsodium in this routine, which is now necessary because libsnark uses its PRNG. + Pass our constraint system to libsnark, so that it doesn't need to (de)serialize it in the proving key. + Rename CPourTx to JSDescription. + Rename vpour to vjoinsplit. + Rename JSDescription's `serials` to `nullifiers`. + Test fixes. + Rename GetPourValueIn to GetJoinSplitValueIn + Rename HavePourRequirements to HaveJoinSplitRequirements. + Rename GetSerial to GetNullifier. + Renaming SetSerial to SetNullifier. + Rename CSerialsMap to CNullifiersMap. + Rename mapSerials to mapNullifiers. + Rename some usage of 'pour'. + Rename more usage of `serial`. + Rename cacheSerials to cacheNullifiers and fix tests. + Rename CSerialsCacheEntry. + Change encryptedbucket1 to encryptednote1. + Rename pour RPC tests + Fix tests + Remove more usage of `serial`. + Fixes for indentation and local variable names. + Change `serial` to `nf` in txdb. + Rename `pour` in RPC tests. + Remove the constraint system from the alpha proving key. + Introduce `zcsamplejoinsplit` for creating a raw joinsplit description, and use it to construct the joinsplit for the performance tests that verify joinsplits. + Bump the (minimum) protocol version to avoid invoking legacy behavior from upstream. + Remove more from libsnark, and fix potential remote-DoS. + Add test for non-intuitive merkle tree gadget witnessing behavior. + +bitcartel (15): + Disable USE_ASM when building libsnark (issue 932). + Add getblocksubsidy RPC command to return the block reward for a given block, taking into account the mining slow start. + Replace index with height in help message for getblocksubsidy RPC call. + Narrow scope of lock. + Add founders reward to output. + Use new public/private key pairs for alert system. + Add sendalert.cpp to repo. + Fixes to integrate sendalert.cpp. Add sendalert.cpp to build process. Add alertkeys.h as a placeholder for private keys. + Disable QT alert message. + Update comments. + Update alert ID start value and URL in comment. + Update alert protocol version comment. + Update URL for zcash alert IDs. + Remove QT alert message box. + New alert test data generated for new alert key pair. Added test fixture to create new test data. Added instructions for developer. + Update tor.md for Zcash + +Taylor Hornby (17): + WIP: Add mock test coverage of CheckTransaction + Split JoinSplit proof verification out of CheckTransaction. + More testing of CheckTransaction + Test non-canonical ed25519 signature check + Rename zerocash to zcash in some places. + Remove references to libzerocash in .gitignore + Rename qa/zerocash to qa/zcash in Makefile.am + Rename zerocash_packages to zcash_packages in packages.mk + Add security warnings doc with warning about side channels. + Add another security warning + Add the results of #784 to security warnings. + Fix bad_txns_oversize test for increased block size. + Note that the actual secret spending key may be leaked. + Mention physical access / close proximity + Remove in-band error signalling from SignatureHash, fixing the SIGHASH_SINGLE bug. + Fix the tests that the SIGHASH_SINGLE bugfix breaks. + Remove insecurely-downloaded dependencies that we don't currently use. + +aniemerg (1): + Update GetDifficulty() to use consensus.powLimit from consensus parameters. Fixes #1032. diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z8.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z8.md new file mode 100644 index 000000000..073d771f1 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z8.md @@ -0,0 +1,61 @@ +Daira Hopwood (1): + README.md: simplify the title, drop "Core" + +Jack Grigg (23): + Make Equihash solvers cancellable + Add tests that exercise the cancellation code branches + Fix segfault by indirectly monitoring chainActive.Tip(), locking on mutex + Move initialisations to simplify cancelled checks + Use std::shared_ptr to deallocate partialSolns automatically + Equihash: Pass each obtained solution to a callback for immediate checking + Remove hardfork from special testnet difficulty rules + Fix bug in 'generate' RPC method that caused it to fail with high probability + Add thread parameter to solveequihash benchmark + Eliminate some of the duplicates caused by truncating indices + Use fixed-size array in IsProbablyDuplicate to avoid stack protector warning + Eliminate probably duplicates in final round + Simplify IsProbablyDuplicate() + Add missing assert + Simplify optional parameters + Fix previous commit + Remove the assumption that n/(k+1) is a multiple of 8. + Add Equihash support for n = 200, k = 9 + Add test showing bug in IsProbablyDuplicate() + Fix bug in IsProbablyDuplicate() + Change Equihash parameters to n = 200, k = 9 (about 563-700 MiB) + Update tests to account for new Equihash parameters + Ignore duplicate entries after partial recreation + +Simon (21): + Inform user that zcraw... rpc calls are being deprecated. + Add GetTxid() which returns a non-malleable txid. + Update genesis blocks. + Update precomputed equihash solutions used in test. + Update block and tx data used in bloom filter tests. + Updated test data for script_tests by uncommenting UPDATE_JSON_TESTS flag. + Rename GetHash() method to GetSerializeHash(). + Replace calls to GetHash() with GetTxid() for transaction objects. + Set nLockTime in CreateNewBlock() so coinbase txs do not have the same txid. Update test data in miner_tests. + Refactor GetTxid() into UpdateTxid() to match coding style of hash member variable. + Revert "Set nLockTime in CreateNewBlock() so coinbase txs do not have the same txid." + Fix issue where a coinbase tx should have it's sigscript hashed to avoid duplicate txids, as discussed in BIP34 and BIP30. + Update genesis block hashes and test data. + Make txid const. + Update deprecation message for zcraw api. + Fix comment. + Update comment. + Extend try catch block around calls to libsnark, per discussion in #1126. + Remove GetSerializeHash() method. + Use -O1 opimitization flag when building libzcash. Continuation of #1064 and related to #1168. + Add test for non-malleable txids. To run just this test: ./zcash-gtest --gtest_filter="txid_tests*" + +Taylor Hornby (8): + Make the --enable-hardening flag explicit. + Enable -O1 for better FORTIFY_SOURCE protections. + Add checksec.sh from http://www.trapkit.de/tools/checksec.html + Add tests for security hardening features + Pull in upstream's make check-security, based on upstream PR #6854 and #7424. + Make security options in configure.ac fail if unavailable. + Put hardened stuff in libzcash CPPFLAGS. + Add more commands to run unit tests under valgrind. + diff --git a/depend/zcash/doc/release-notes/release-notes-0.11.2.z9.md b/depend/zcash/doc/release-notes/release-notes-0.11.2.z9.md new file mode 100644 index 000000000..3c45b9d9a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-0.11.2.z9.md @@ -0,0 +1,55 @@ +Sean Bowe (6): + Change memo field size and relocate `ciphertexts` field of JoinSplit description. + Implement zkSNARK compression. + Perform curve parameter initialization at start of gtest suite. + Update libsnark dependency. + Enable MONTGOMERY_OUTPUT everywhere. + Update proving/verifying keys. + +Jack Grigg (11): + Add support for spending keys to the basic key store. + Merge AddSpendingKeyPaymentAddress into AddSpendingKey to simplify API. + Add methods for byte array expansion and compression. + Update Equihash hash generation to match the Zcash spec. + Extend byte array expansion and compression methods with optional padding. + Store the Equihash solution in minimal representation in the block header. + Enable branch coverage in coverage reports. + Add gtest coverage and intermediates to files deleted by "make clean". + Remove non-libsnark dependencies and test harness code from coverage reports. + Add separate lock for SpendingKey key store operations. + Test conversion between solution indices and minimal representation. + +Daira Hopwood (6): + Move bigint arithmetic implementations to libsnark. + Add mostly-static checks on consistency of Equihash parameters, MAX_HEADERS_RESULTS, and MAX_PROTOCOL_MESSAGE_LENGTH. + Change some asserts in equihash.cpp to be static. + Decrease MAX_HEADERS_RESULTS to 160. fixes #1289 + Increment version numbers for z9 release. + Add these release notes for z9. + +Taylor Hornby (5): + Disable hardening when building for coverage reports. + Upgrade libsodium for AVX2-detection bugfix. + Fix inconsistent optimization flags; single source of truth. + Add -fwrapv -fno-strict-aliasing; fix libzcash flags. + Use libsodium's s < L check, instead checking that libsodium checks that. + +Simon Liu (3): + Fixes #1193 so that during verification benchmarking it does not unncessarily create thousands of CTransaction objects. + Closes #701 by adding documentation about the Payment RPC interface. + Add note about zkey and encrypted wallets. + +Gaurav Rana (1): + Update zcash-cli stop message. + +Tom Ritter (1): + Clarify comment about nonce space for Note Encryption. + +Robert C. Seacord (1): + Memory safety and correctness fixes found in NCC audit. + +Patrick Strateman (1): + Pull in some DoS mitigations from upstream. (#1258) + +Wladimir J. van der Laan (1): + net: correctly initialize nMinPingUsecTime. diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-beta1.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-beta1.md new file mode 100644 index 000000000..8c28b92aa --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-beta1.md @@ -0,0 +1,159 @@ +Daira Hopwood (1): + Update steps after D + +Jack Grigg (43): + Undo debugging change from 5be6abbf84c46e8fc4c8ef9be987a44de22d0d05 + Output Equihash solution in RPC results as a hex string + Add optional bool to disable computation of proof in JSDescription constructor + Add wallet method for finding spendable notes in a CTransaction + Store mapping between notes and PaymentAddresses in CWalletTx + Keep track of spent notes, and detect and report conflicts + Create mapping from nullifiers to received notes + Add caching of incremental witnesses for spendable notes + Update cached incremental witnesses when the active block chain tip changes + Test solution output of blockToJSON() + Pass ZCIncrementalMerkleTree to wallet to prevent race conditions + Remove GetNoteDecryptors(), lock inside FindMyNotes() instead + Replace vAnchorCache with a cache size counter + mapNullifiers -> mapNullifiersToNotes for clarity + Set witness cache size equal to coinbase maturity duration + Add transactions to wallet if we spend notes in them + Add test for GetNoteDecryptor() + Keep any existing cached witnesses when updating transactions + Changes after review + Add test showing that the witness cache isn't being serialised + Fix the failing test! + Increase coverage of GetNoteDecryptor() + Add coverage of the assertion inside GetNoteWitnesses() + Separate concepts of block difficulty and network difficulty in RPC + Add test comparing GetDifficulty() with GetNetworkDifficulty() + Remove mainnet DNS seeds, set checkpoint to genesis + Fix failing test + Adjust from average difficulty instead of previous difficulty + Remove testnet-only difficulty rules + Add comments explaining changed semantics of pow_tests + Expand bounds on difficulty adjustment + Remove accidental double-semicolon (harmless but odd) + Add test of difficulty averaging + Simplify difficulty averaging code + Restrict powLimit due to difficulty averaging + Regenerate genesis blocks for new powLimits + Update tests for new genesis blocks + Adjust test to avoid spurious failures + Remove unnecessary method + Adjust test to account for integer division precision loss + Refactor wallet note code for testing + Add tests for refactored wallet code + Remove .z# suffix from version + +Lars-Magnus Skog (1): + changed module name from "bitcoin" to "Zcash" in FormatException() + +Sean Bowe (7): + Deallocate the public parameters during Shutdown. + Update libsnark again. + Fix CheckTransaction bugs. + Remove TODO 808. + Fix transaction test in test_bitcoin. + Change version to 1.0.0. This is just a beta. + Update pchMessageStart and add testnet DNS boostrapper. + +Simon (91): + Implemented RPC calls z_importkey, z_exportkey, z_getnewaddress. Modified RPC calls dumpwallet and importwallet to include spending keys. + Add z_importwallet and z_exportwallet to handle keys for both taddr and zaddr. Restore behaviour of dumpwallet and importwallet to only handle taddr. + Implemented z_listaddresses to return all the zaddr in the wallet. + Add gtest to cover new methods in: CWallet - GenerateNewZKey() - AddZKey() - LoadZKey() - LoadZKeyMetadata() CWalletDB - WriteZKey() + Don't mark wallet as dirty if key already exists. Fix incorrect method name used in error message. + Added wallet rpc tests to cover: z_importwallet, z_exportwallet z_importkey, z_exportkey z_listaddresses + Add test coverage for RPC call z_getnewaddress. + Fix comment. + Remove one line of dead code. + Add "zkey" to list of key types (used by the wallet to decide whether or not it can be recovered if it detects bad records). + Fix comments. + Rename methods to avoid using prefix of _ underscore which is reserved. Added logging of explicit exception rather than a catch all. Removed redundant spending key check. Updated user facing help message. + Fixes #1122 where json_spirit could stack overflow because there was no maximum limit set on the number of nested compound elements. + Throw a domain error as json_spirit is a third-party library. + Closes #1315. RPC getblocksubsidy height parameter is now optional and a test has been added to verify parameter input and results. + Remove #1144 from transaction.h. + Remove #1144 from transaction.cpp by reverting back to commit 942bc46. + Remove #1144 from bloom_tests by reverting to commit 5012190. + Remove #1144 from input data of script_tests. + Update txid gtest to verify #1144 has been removed: GetTxid() and GetHash() return the same result. + Refactor: replace calls to GetTxid() with GetHash() + Remove GetTxid() from CTransaction and update test_txid + Replace GetTxid() with GetHash() after rebase on latest. + Add async RPC queue and operation classes. Add z_getoperationstatus RPC command. Add z_sendmany RPC command (dummy implementation, does not send actual coins). + Add prefix to async operation id so it is easier to manage on cli. + Add config option 'rpcasyncthreads' to specify number of async rpc workers. Default is 1. + Add public field 'memo' to JSOutput to enable creation of notes with custom memos. + Implement z_sendmany RPC call. + Update find_unspent_notes() as mapNoteAddrs_t has been replaced by mapNoteData_t. + z_sendmany from a taddr now routes change to a new address instead of back to the sender's taddr, + Successful result of z_sendmany returns txid so it doesn't need to return raw hex. + Add public method to get state as a human readable string from an AsyncRPCOperation. + Add public method to AsycnRPCQueue to retrieve all the known operation ids. + Implement RPC call z_listoperationids and update z_getoperationstatus to take a list parameter. + Refactoring and small improvements to async rpc operations. + Closes #1293 by adding z_getoperationresult and making z_getoperationstatus idempotent. + Add chaining of JoinSplits within a transaction. + Disable option to allow multiple async rpc workers. + Coinbase utxos can only be spent when sending to a single zaddr. Change from the transaction will be sent to the same zaddr. + Fix bug where call to sign and send a transaction was in wrong scope. + Added option to close a queue and wait for queued up operations to finish, rather than just closing a queue and immediately cancelling all operations. + Fix bug where wallet was not persisting witnesses to disk. Author: str4d + Refactor to use wallet note tracking from commit a72379 + Clear the operation queue when closing it. + Add test for AsyncRPCQueue and AsyncRPCOperation. + Add shared queue to AsynRPCQueue. + Update RPCServer to use AsyncRPCQueue's shared queue. + Remove redundant check when getting spending key for a payment address. + Add tests for async queue and rpc commands: z_getoperationstatus, z_getoperationresult, z_listoperationids, z_sendmany + Remove redundant call. + Add logging under the category "asyncrpc". + Add extra checking of memo data in hexadecimal string format. + Add friend class for testing private members of AsyncRPCOperation_sendmany. + Add z_getbalance and z_gettotalbalance RPC calls to close #1201. + Fix typo in error message + Disable proof generation when testmode is enabled in async SendMany operation. + Reduce use of global pzcashParams with private member variable + Revert "Reduce use of global pzcashParams with private member variable" + Replace zcashParams_ with global. + Add tests to try and improve coverage of perform_joinsplit. + Add GetUnspentNotes to wallet. + Add test for GetUnspentNotes() in wallet. + Refactor async sendmany and getbalance calls to use GetUnspentNotes(). + Add more logging. + Disable z_sendmany in safe mode + Rename GetUnspentNotes to GetFilteredNotes + Add z_listreceivedbyaddress RPC call + Add 'DEPRECATED' to help message of zcraw* commands + Update formatting and documentation. + Move lock guard to start of addOperation to protect isClosed() and isFinishing() + Fix formatting + Add lock guard to getNumberOfWorkers() + Replace unique_lock with lock_guard, where appropriate, for consistency + Add extra RPC parameter checks for minconf<0 and zaddr not belonging to wallet. + Add test for calling RPC z_getbalance, z_gettotalbalance, z_listreceivedbyaddress with invalid parameters. + Fix formatting + Update log statement to include fee. + Fix incorrect default value for argument of GetFilteredNotes. + Formatting and updated test per review. + Add lock for member variables. Clean up and clarify that id_ and creation_time_ are never to be mutated anywhere. Fix incomplete copy/assignment constructors. + Remove unused varible. + Add ticket number to issues raised in comment. + Add assert for two mutually exclusive member variables. + Improve error reporting when attempting to spend coinbase utxos. + Use zcash constants + Fix formatting + Add assert + Update comment with ticket issue number + Remove line of commented out code we don't need + Improve check that user supplied memo field is too long. + Replace GetTxid() with GetHash() + Update payment-api.md + Update security-warnings.md about REST interface + Update payment API documentation for beta 1 + +Taylor Hornby (2): + Add -Wformat -Wformat-security + Use -Wformat in the test for -Wformat-security diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-beta2.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-beta2.md new file mode 100644 index 000000000..90d9286a9 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-beta2.md @@ -0,0 +1,119 @@ +Alfie John (2): + Typo in params README + Updating wording to match Beta Guide + +Bryan Stitt (1): + Link to beta guide + +Daira Hopwood (9): + Benchmark 50 iterations of solveequihash + Remove FindAndDelete. refs #1386 + Update my email address in the Code of Conduct. + Repair FormatSubVersion tests. refs #1138 + WIP: update address prefixes. refs #812 + Reencode keys in JSON test data. refs #812 + CBitcoinAddress should use nVersionBytes == 2. + Repair bitcoin-util-test. + Repair rpc-tests/signrawtransactions.py. + +Gregory Maxwell (1): + Limit setAskFor and retire requested entries only when a getdata returns. + +Jack Grigg (43): + Add support for encrypting spending keys + Check we haven't trashed the first key entry with the second + Move serialized Zcash address length constants into zcash/Address.hpp + Measure multithreaded solveequihash time per-thread + Add a make command for checking expected failures + Enable high-priority alerts to put the RPC into safe mode + Fix test + Add wallet method to clear the note witness cache + Clear note witness caches on reindex + Write note witness cache atomically to disk to avoid corruption + Test that invalid keys fail to unlock the keystore + Implement CSecureDataStream for streaming CKeyingMaterial + Cache note decryptors in encrypted keystore + Use correct lock for spending keys + Upgrade Boost to 1.62.0 + Upgrade libgmp to 6.1.1 + Upgrade OpenSSL to 1.1.0b + Upgrade miniupnpc to 2.0 + Upgrade ccache to 3.3.1 + Release process: check dependencies for updates + Fix auto_ptr deprecation warning in Boost + Replace auto_ptr with unique_ptr + Re-enable disabled compiler warnings + Disable nearly everything in OpenSSL + Add libsnark to pre-release dependency checks + Assert that new OpenSSL allocators succeed + Remove no-autoalginit and no-autoerrinit OpenSSL flags + Use asserts to check allocation errors in CECKey::Recover + Simplify ClearNoteWitnessCache() + Add tests for alerts enabling RPC safe mode + Ensure correctness if asserts are compiled out + Disable OP_CODESEPARATOR + Remove OP_CODESEPARATOR from tests + Downgrade bdb to 5.3.28 + Use CLIENT_VERSION_BUILD to represent -beta and -rc in client version + Update release process with version schema + Formatting fix + Mark previously-valid test data as invalid + Re-encode hard-coded addresses in tests + Re-encode Founders' Reward keys + Fix secp256k1 test compilation + Fix zkey test + Update address in Founders' Reward gtest + +Jay Graber (4): + Link to z.cash on security-warnings.md + Add section abt confs and reorgs to security-warnings.md + Update wording + Final edits + +Kevin Gallagher (5): + Lock to prevent parallel execution of fetch-params.sh + Updates dns.testnet.z.cash -> dnsseed.testnet.z.cash + Verify TLS certificates w/ wget in fetch-params.sh + Inserts some notes related to testnet deployment + Adds note about updating guide during testnet deployment + +Pieter Wuille (1): + Fix and improve relay from whitelisted peers + +Robert C. Seacord (1): + Changes to upgrade bdb to 6.2.23 + +Sean Bowe (1): + Update to `beta2` public parameters, remove `regtest`/`testnet3` parameters subdirectories. + +Simon (20): + Replace %i format specifier with more commonly used %d. + Fix GetFilteredNotes to use int for minDepth like upstream and avoid casting problems. Don't use FindMyNotes as mapNoteData has already been set on wallet tx. + Update test to filter and find notes. + Add support for spending keys to the encrypted wallet. + Update to use new API in CCryptoKeyStore and store a viewing key in walletdb. + Fix comment and formatting per review + Add founders reward to ChainParams. Fix bug where subsidy slow shift was ignored. + Founders reward: changed index computation, added new test and some refactoring. + Founders reward: Refactor test and formatting per review. + Refactor to add test to verify number of rewards each mainnet address will receive + Refactor and fix per review + Update comment per review + Update founders reward test to output path of temporary wallet.dat file which contains keys which can be used for testing founders reward addresses. + Update testnet founders reward addresses + Add mainnet 2-of-3 multisig addresses for testing. + Add field fMinerTestModeForFoundersRewardScript to chainparams + Update mainnet addresses used for testing to have the correct number + Fixes #1345 so that UTXO debit and credits are computed correctly for a transaction. + Closes #1371 by updating signed message + Modify message string so we don't need to backport commits which implement FormatStateMessage and GetDebugMessage and involve changes to consensus/validation.h + +Wladimir J. van der Laan (1): + build: remove libressl check + +fanquake (1): + [depends] OpenSSL 1.0.1k - update config_opts + +kazcw (1): + prevent peer flooding request queue for an inv + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc1.md new file mode 100644 index 000000000..4d9763ec7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc1.md @@ -0,0 +1,121 @@ +4ZEC (1): + Correct line swap + +Cory Fields (7): + release: add _IO_stdin_used to ignored exports + release: add check-symbols and check-security make targets + release: always link librt for glibc back-compat builds + release: add security/symbol checks to gitian + depends: allow for CONFIG_SITE to be used rather than stealing prefix + gitian: use CONFIG_SITE rather than hijacking the prefix + gitian: create debug packages for linux/windows + +Daira Hopwood (6): + Fix RPC tests to not rely on accounts. + Cosmetics in RPC tests. + Fix blank lines in DEBIAN/copyright license texts. + Move the increment of nWitnessCacheSize to make the later assertions correct. + Add another assertion to narrow down where the bug occurs. + Add another assertion about the witness cache. + +Jack Grigg (25): + Update release process to sign release tags + WriteWitnessCache: Catch errors and abort transaction + Throw an RPC error for all accounts except the default + Update tests for account deprecation + Deprecated -> Unsupported in RPC error + Correct docstring + Add unit tests for WriteWitnessCache + Document CWalletTx::FindMyNotes + Refactor test to clarify expectations + Add unit test that fails when calling FindMyNotes on a locked wallet + Add RPC test showing correct handling of JS txns from blockchain + Break the RPC test by encrypting the mirroring wallet + Delay caching of nullifiers when wallet is locked + Update comments + Only ignore runtime errors caused by failed note decryption + Remaining changes from bitcoin/bitcoin#6854 + [gitian] Don't call "make check-symbols" + Fix Makefiles so "make dist" will run + Render full version correctly in configure.ac + Update libsnark to include determinism fix + Address review comments + Add more asserts to track down the bug + Increment witnesses for new transactions on rescan + Add clear error message for upgrading users + Set CBlockIndex.hashAnchor correctly in ConnectBlock + +Jay Graber (17): + Document wallet reindexing for z_importkey description in payment-api.md + Rm beta 1 release note about encrypted wallets + Note that Coinbase maturity interval does not protect JoinSplits + Refer to Zcash wiki in INSTALL + Rm bitcoin logo + Rm build-unix.md, to keep single copy of build instructions for Zcash on github wiki + Rm Bitcoin-specific documentation + Add note that document is not updated for Zcash to translation policy + Rm doc for disabled REST interface + Change alpha to beta testnet, add zcash hidden service + Improve documentation on connecting to zcash hidden server + Improve documentation on connecting to zcash hidden server + Update tor.md + Distinguish between connecting to 1 vs multiple tor nodes + Revert "Rm Bitcoin-specific documentation" + Mv btc release notes to doc/bitcoin-release-notes + Reword joinsplit anchor paragraph + +Kevin Gallagher (24): + Set wget retry options for fetching parameters + Increases timeout to 30s, wait before retry to 3s + Initial packaging for Debian + Moves zcash-fetch-params to /usr/bin + Adds newline between source and package definition + Adds copyright file back to Debian package + Updates Linux gitian descriptor file for Zcash + Updates trusty -> jessie in Gitian Linux descriptor + Adds distro: debian to gitian-linux.yml + Updates Gitian descriptor for Zcash + Removes Windows and OSX packaging from EXTRA_DIST + Moves V=1 and NO_QT=1 to MAKEOPTS + Include contrib/devtools/split-debug.sh from upstream + Adds faketime to Gitian build dependencies + Inlude crypto/equihash.tcc in list of sources for dist + Adds zcash/Zcash.h to LIBZCASH sources + Adds zcash/Proof.hpp to LIBZCASH_H + Add alertkeys.h to libbitcoin_server_a_SOURCES + Adds files in src/zcash/circuit to libzcash_a_SOURCES + Adds zcbenchmarks.h to libbitcoin_wallet_a_SOURCES + Adds json_test_vectors.h to zcash_gtest_SOURCES + Adds additional licenses to Debian copyright file + Updates Zcash Core developers -> Zcash developers + Adds . to blank lines in Google license + +MarcoFalke (3): + [gitian] Set reference date to something more recent + [gitian] Default reference_datetime to commit author date + [gitian] hardcode datetime for depends + +Sean Bowe (1): + Make 100KB transaction size limit a consensus rule, rather than a standard rule. + +Simon (11): + Add vjoinsplit to JSON output of RPC call gettransaction + Fixes #1478 by ensuring wallet tests have the -datadir environment set appropriately. + Fixes #1491 by updating help message for rpc call z_importkey + Fix incorrect check of number of parameters for z_getnewaddress. + Add tests to verify that all z_* rpc calls return an error if there are too many input parameters. + Rename client identifier from Satoshi to MagicBean (closes #1481) + Use -debug=zrpc for z_* rpc calls (#1504) + Document CWallet::GetFilteredNotes and fix return type which should be void. + Fix test so that the encrypted wallet is output to the test_bitcoin -datadir folder. + Reorder gtests in zcash-gtest. + Return improved error message when trying to spend Coinbase coins (#1373). + +Wladimir J. van der Laan (6): + devtools: add libraries for bitcoin-qt to symbol check + gitian: use trusty for building + gitian: make windows build deterministic + gitian: Need `ca-certificates` and `python` for LXC builds + build: Remove unnecessary executables from gitian release + gitian: Add --disable-bench to config flags for windows + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-rc2.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc2.md new file mode 100644 index 000000000..27f115a75 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc2.md @@ -0,0 +1,106 @@ +Daira Hopwood (22): + Add link to protocol specification. + Add tests for IsStandardTx applied to v2 transactions. + Make v2 transactions standard. This also corrects a rule about admitting large orphan transactions into the mempool, to account for v2-specific fields. + Changes to build on Alpine Linux. + Add Tromp's implementation of Equihash solver (as of tromp/equihash commit 690fc5eff453bc0c1ec66b283395c9df87701e93). + Integrate Tromp solver into miner code and remove its dependency on extra BLAKE2b implementation. + Minor edits to dnsseed-policy.md. + Avoid boost::posix_time functions that have potential out-of-bounds read bugs. ref #1459 + Add help for -equihashsolver= option. + Assert that the Equihash solver is a supported option. + Repair check-security-hardening.sh. + Revert "Avoid boost::posix_time functions that have potential out-of-bounds read bugs. ref #1459" + Fix race condition in rpc-tests/wallet_protectcoinbase.py. closes #1597 + Fix other potential race conditions similar to ref #1597 in RPC tests. + Update the error message string for tx version too low. ref #1600 + Static assertion that standard and network min tx versions are consistent. + Update comments in chainparams.cpp. + Update unit-tests documentation. closes #1530 + Address @str4d's comments on unit-tests doc. ref #1530 + Remove copyright entries for some files we deleted. + Update license text in README.md. closes #38 + Bump version numbers to 1.0.0-rc2. + +David Mercer (4): + explicitly pass HOST and BUILD to ./configure + allow both HOST and BUILD to be passed in from the zcutil/build.sh + pass in both HOST and BUILD to depends system, needed for deterministic builds + explicitly pass HOST and BUILD to libgmp ./configure + +Gregory Maxwell (1): + Only send one GetAddr response per connection. + +Jack Grigg (31): + Implement MappedShuffle for tracking the permutation of an array + Implement static method for creating a randomized JSDescription + Randomize JoinSplits in z_sendmany + Refactor test code to better test JSDescription::Randomized() + Remove stale comment + Rename libbitcoinconsensus to libzcashconsensus + Rename bitcoin-tx to zcash-tx + Remove the RC 1 block index error message + Disable wallet encryption + Add more assertions, throw if find_output params are invalid + Clear witness cache when re-witnessing notes + Add heights to log output + Throw an error when encryptwallet is disabled + Document that wallet encryption is disabled + Document another wallet encryption concern + Improve security documentation + Fix RPC tests that require wallet encryption + Add test that encryptwallet is disabled + Revert "Revert "Avoid boost::posix_time functions that have potential out-of-bounds read bugs. ref #1459"" + GBT: Support coinbasetxn instead of coinbasevalue + GBT: Add informational founders' reward value to coinbasetxn + GBT: Correct block header in proposals RPC test + GBT: Add RPC tests + Disallow v0 transactions as a consensus rule + Reject block versions lower than 4 + Regenerate genesis blocks with nVersion = 4 + Use tromp's solver to regenerate miner tests + Update tests for new genesis blocks + Enforce standard transaction rules on testnet + Update sighash tests for new consensus rule + Fix RPC test + +Jay Graber (7): + Rm bitcoin dev keys from gitian-downloader, add zcash dev keys + Rm bips.md + Update files.md for zcash + Update dnsseed-policy.md + Developer notes still relevant + Document RPC interface security assumptions in security-warnings.md + Update RPC interfaces warnings language + +Patrick Strateman (1): + CDataStream::ignore Throw exception instead of assert on negative nSize. + +Pieter Wuille (4): + Introduce constant for maximum CScript length + Treat overly long scriptPubKeys as unspendable + Fix OOM bug: UTXO entries with invalid script length + Add tests for CCoins deserialization + +Simon (17): + Fixes CID 1147436 uninitialized scalar field. + Fixes CID 1352706 uninitialized scalar field. + Fixes CID 1352698 uninitialized scalar field. + Fixes CID 1352687 uninitialized scalar field. + Fixes CID 1352715 uninitialized scalar field. + Fixes CID 1352686 uninitialized scalar variable. + Fixes CID 1352599 unitialized scalar variable + Fixes CID 1352727 uninitialized scalar variable. + Fixes CID 1352714 uninitialized scalar variable. + Add security warning about logging of z_* calls. + Add debug option "zrpcunsafe" to be used when logging more sensitive information such as the memo field of a note. + Closes #1583 by setting up the datadir for the wallet gtest. + Fix issue where z_sendmany is too strict and does not allow integer based amount e.g. 1 which is the same as 1.0 + Update test to use integer amount as well as decimal amount when calling z_sendmany + Fix build problem with coins_tests + Workaround g++ 5.x bug with brace enclosed initializer. + Patch backport of upstream 1588 as we don't (yet) use the NetMsgType namespace + +Wladimir J. van der Laan (1): + net: Ignore `notfound` P2P messages + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-rc3.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc3.md new file mode 100644 index 000000000..863df2000 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc3.md @@ -0,0 +1,51 @@ +Chirag Davé (1): + fReopenDebugLog and fRequestShutdown should be type sig_atomic_t + +Daira Hopwood (9): + Refactor README docs to avoid duplication. + Fix licensing to comply with OpenSSL and Berkeley DB licenses. + Changes to upgrade bdb to 6.2.23 + util: Update tinyformat + Tweak descriptions of mining parameters for example zcash.conf. + Update dnsseeds for mainnet. closes #1369 + Minor update to release process. + Remove the override of nMaxTipAge that effectively disables it on testnet. + Update version numbers for rc3. + +Jack Grigg (2): + Disable metrics screen in performance-measurements.sh + Link to #826 in doc/security-warnings.md, link to new Security website page + +Joe Turgeon (2): + Fixing floating point exception caused by metrics. Using default column width unless in a TTY. + Adding handling for ioctl failure. Updates from code review in PR #1615. + +Kevin Gallagher (2): + Prefer sha256sum but fall back to shasum if not available + Adds libgomp1 to Debian package depends + +Louis Nyffenegger (1): + Fix typo in README.md + +Paige Peterson (3): + add zcash.config + fix per Jack's mod suggestions + fix per Daira's suggestions + +Pieter Wuille (3): + Include signal.h for sig_atomic_t in WIN32 + Revert "Include signal.h for sig_atomic_t in WIN32" + Use std::atomic for fRequestShutdown and fReopenDebugLog + +Sean Bowe (1): + Add manpages for zcashd and zcash-cli binaries for debian. + +Simon (4): + Fix incorrect error message in z_sendmany + Add z_sendmany rule that when sending coinbase utxos to a zaddr they must be consumed entirely, without any change, since there is currently no way to specify a change address in z_sendmany. + Add assert to AsyncRPCOperation_sendmany + Bump version number in sendalert.cpp + +bitcartel (1): + Update payment-api.md + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0-rc4.md b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc4.md new file mode 100644 index 000000000..0a51dfb92 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0-rc4.md @@ -0,0 +1,14 @@ +Daira Hopwood (3): + Update pchMessageStart for mainnet and testnet. + Update version numbers for 1.0.0-rc4. + Add release notes for 1.0.0-rc4. + +Jack Grigg (4): + Integrate production Founders' Reward keys + Remove Founders' Reward override from #1398 + Regenerate mainnet and testnet genesis blocks for nMaxTipAge change + Update tests for new genesis blocks + +Sean Bowe (1): + Zcash zk-SNARK public parameters for 1.0 "Sprout". + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.0.md b/depend/zcash/doc/release-notes/release-notes-1.0.0.md new file mode 100644 index 000000000..f95d53d4e --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.0.md @@ -0,0 +1,18 @@ +Jack Grigg (8): + Rework zcutil/build-debian-package.sh to place files correctly + Add lintian check to zcutil/build-debian-package.sh + Fix DEBIAN/control errors raised by lintian + Build libsnark with -march=x86-64 instead of -march=native + Disable the metrics screen on regtest + Add the Zcash genesis blocks + Update tests for new genesis blocks + Update version strings to 1.0.0 + +Kevin Gallagher (6): + Use fakeroot to build Debian package + Update Debian package maintainer scripts + Fixes executable mode of maintainer scripts + Add DEBIAN/rules file (required by policy) + Adds zcash.examples and zcash.manpages + Run Lintian after built package is copied to $SRC_PATH + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.1.md b/depend/zcash/doc/release-notes/release-notes-1.0.1.md new file mode 100644 index 000000000..8ee772bf7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.1.md @@ -0,0 +1,34 @@ +Cameron Boehmer (1): + point "where do i begin?" readme link to 1.0 guide + +Jack Grigg (15): + Track mined blocks to detect and report orphans and mining revenue + Refresh mining status to detect setgenerate changes + Add network stats to metrics screen + Show mining info once the node has finished loading + Improve locking in metrics + Adjust consensus rule to accept genesis block without height in coinbase + Fix previous commit + Ensure that no tracked blocks are skipped during orphan detection + Add build scripts and fetch-params.sh to "make install" and "make dist" + Use uint64_t for AtomicCounter + Fix gtest issue introduced into master + Fix whitespace in Makefile.gtest.include + Initialise walletdb system in a temp dir for all gtests + Revert "Initialise walletdb system in a temp dir for all gtests" + Change execution order of gtests to avoid bug + +Kevin Gallagher (1): + Improves usability of fetch-params.sh + +Sean Bowe (6): + Properly account for joinsplit value when deciding if a transaction should be placed in a mined block. + Add checkpoint at block 2500. + Throw more descriptive exceptions when the constraint system is violated. + Test that a pure joinsplit will mine if other transactions are in the mempool. + 1.0.1 release. + Update man pages. + +Simon (1): + Closes #1746. Add rpc call z_validateaddress to validate zaddrs. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.10-1.md b/depend/zcash/doc/release-notes/release-notes-1.0.10-1.md new file mode 100644 index 000000000..fea2f5156 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.10-1.md @@ -0,0 +1,11 @@ +Jack Grigg (1): + Disable building Proton in Gitian + +Sean Bowe (2): + Revert "Remove an unneeded version workaround as per @str4d's review comment." + Revert "Delete old protocol version constants and simplify code that used them." + +Simon Liu (2): + make-release.py: Versioning changes for 1.0.10-1. + make-release.py: Updated manpages for 1.0.10-1. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.10.md b/depend/zcash/doc/release-notes/release-notes-1.0.10.md new file mode 100644 index 000000000..16d2a62ba --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.10.md @@ -0,0 +1,79 @@ +Notable changes +=============== + +Signature validation using libsecp256k1 +--------------------------------------- + +ECDSA signatures inside Zcash transactions now use validation using +[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. + +Depending on the platform, this means a significant speedup for raw signature +validation speed. The advantage is largest on x86_64, where validation is over +five times faster. In practice, this translates to a raw reindexing and new +block validation times that are less than half of what it was before. + +Libsecp256k1 has undergone very extensive testing and validation upstream. + +A side effect of this change is that libconsensus no longer depends on OpenSSL. + +Changelog +========= + +Boris Hajduk (1): + documentatin z_validateaddress was missing param + +Daira Hopwood (8): + Delete old protocol version constants and simplify code that used them. fixes #2244 + Remove an unneeded version workaround as per @str4d's review comment. + Remove unneeded lax ECDSA signature verification. + Strict DER signatures are always enforced; remove the flag and code that used it. + Repair tests for strict DER signatures. While we're at it, repair a similar test for CLTV, and make the repaired RPC tests run by default. + Make transaction test failures print the comments preceding the test JSON. + Fix a comment that was made stale before launch by #1016 (commit 542da61). + Delete test that is redundant and inapplicable to Zcash. + +Jack Grigg (20): + Fix incorrect locking in CCryptoKeyStore + Use AtomicTimer for metrics screen thread count + Revert "Fix secp256k1 test compilation" + Squashed 'src/secp256k1/' changes from 22f60a6..84973d3 + Fix potential overflows in ECDSA DER parsers + Rename FALLBACK_DOWNLOAD_PATH to PRIORITY_DOWNLOAD_PATH + Add test for incorrect consensus logic + Correct consensus logic in ContextualCheckInputs + Add comments + Update Debian copyright list + Specify ECDSA constant sizes as constants + Remove redundant `= 0` initialisations + Ensure that ECDSA constant sizes are correctly-sized + Add test for -mempooltxinputlimit + Hold an ECCVerifyHandle in zcash-gtest + Additional testing of -mempooltxinputlimit + Fix comment + Use sendfrom for both t-addr calls + make-release.py: Versioning changes for 1.0.10. + make-release.py: Updated manpages for 1.0.10. + +Kevin Pan (1): + "getblocktemplate" could work without wallet + +Pieter Wuille (2): + Update key.cpp to new secp256k1 API + Switch to libsecp256k1-based validation for ECDSA + +Simon Liu (5): + Fix intermediate vpub_new leakage in multi joinsplit tx (#1360) + Add option 'mempooltxinputlimit' so the mempool can reject a transaction based on the number of transparent inputs. + Check mempooltxinputlimit when creating a transaction to avoid local mempool rejection. + Partial revert & fix for commit 9e84b5a ; code block in wrong location. + Fix #b1eb4f2 so test checks sendfrom as originally intended. + +Wladimir J. van der Laan (2): + Use real number of cores for default -par, ignore virtual cores + Remove ChainParams::DefaultMinerThreads + +kozyilmaz (3): + [macOS] system linker does not support “--version†option but only “-v†+ option to disable building libraries (zcutil/build.sh) + support per platform filename and hash setting for dependencies + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.11-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.11-rc1.md new file mode 100644 index 000000000..4542a448c --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.11-rc1.md @@ -0,0 +1,44 @@ +Changelog +========= + +Ariel Gabizon (2): + make-release.py: Versioning changes for 1.0.11-rc1. + make-release.py: Updated manpages for 1.0.11-rc1. + +Daira Hopwood (7): + Clean up imports to be pyflakes-checkable. fixes #2450 + For unused variables reported by pyflakes, either remove the variable, suppress the warning, or fix a bug (if the wrong variable was used). refs #2450 + Cosmetics (trailing whitespace, comment conventions, etc.) + Alert 1004 (version 1.0.10 only) + Remove UPnP support. fixes #2500 + Change wording in Security Warnings section of README.md. + Document our criteria for adding CI workers. closes #2499 + +Jack Grigg (15): + Pull in temporary release notes during the release process + Ansible playbook for installing Zcash dependencies and Buildbot worker + Variable overrides for Debian, Ubuntu and Fedora + Variable overrides for FreeBSD + Simplify Python installation, inform user if they need to manually configure + Add test for issue #2444 + Add Buildbot worker setup to Ansible playbook + Add steps for setting up a latent worker on Amazon EC2 + Add pyblake2 to required Python modules + Remove Buildbot version from host file + Add a separate Buildbot host info template for EC2 + Add pyflakes to required Python modules + Add block download progress to metrics UI + Correct and extend EstimateNetHeightInner tests + Improve network height estimation + +Simon Liu (3): + Closes #2446 by adding generated field to listunspent. + Fixes #2519. When sending from a zaddr, minconf cannot be zero. + Fixes #2480. Null entry in map was dereferenced leading to a segfault. + +Wladimir J. van der Laan (1): + rpc: Add WWW-Authenticate header to 401 response + +practicalswift (1): + Net: Fix resource leak in ReadBinaryFile(...) + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.11.md b/depend/zcash/doc/release-notes/release-notes-1.0.11.md new file mode 100644 index 000000000..d5a12a222 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.11.md @@ -0,0 +1,47 @@ +Changelog +========= + +Ariel Gabizon (3): + make-release.py: Versioning changes for 1.0.11-rc1. + make-release.py: Updated manpages for 1.0.11-rc1. + make-release.py: Updated release notes and changelog for 1.0.11-rc1. + +Daira Hopwood (7): + Clean up imports to be pyflakes-checkable. fixes #2450 + For unused variables reported by pyflakes, either remove the variable, suppress the warning, or fix a bug (if the wrong variable was used). refs #2450 + Cosmetics (trailing whitespace, comment conventions, etc.) + Alert 1004 (version 1.0.10 only) + Remove UPnP support. fixes #2500 + Change wording in Security Warnings section of README.md. + Document our criteria for adding CI workers. closes #2499 + +Jack Grigg (17): + Pull in temporary release notes during the release process + Ansible playbook for installing Zcash dependencies and Buildbot worker + Variable overrides for Debian, Ubuntu and Fedora + Variable overrides for FreeBSD + Simplify Python installation, inform user if they need to manually configure + Add test for issue #2444 + Add Buildbot worker setup to Ansible playbook + Add steps for setting up a latent worker on Amazon EC2 + Add pyblake2 to required Python modules + Remove Buildbot version from host file + Add a separate Buildbot host info template for EC2 + Add pyflakes to required Python modules + Add block download progress to metrics UI + Correct and extend EstimateNetHeightInner tests + Improve network height estimation + make-release.py: Versioning changes for 1.0.11. + make-release.py: Updated manpages for 1.0.11. + +Simon Liu (3): + Closes #2446 by adding generated field to listunspent. + Fixes #2519. When sending from a zaddr, minconf cannot be zero. + Fixes #2480. Null entry in map was dereferenced leading to a segfault. + +Wladimir J. van der Laan (1): + rpc: Add WWW-Authenticate header to 401 response + +practicalswift (1): + Net: Fix resource leak in ReadBinaryFile(...) + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.12-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.12-rc1.md new file mode 100644 index 000000000..27d36b7e7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.12-rc1.md @@ -0,0 +1,57 @@ +Changelog +========= + +Ariel (1): + add examples to z_getoperationresult + +Ariel Gabizon (1): + add load-wallet benchmark + +Bjorn Hjortsberg (2): + Do not warn on built in declaration mismatch + Remove deprecated exception specification + +Jack Grigg (20): + ci-workers: Enable pipelining, and use root to set admin and host details + Variable overrides for Arch Linux + Rationalize currency unit to "ZEC" + ci-workers: Fail if Python is not version 2.7 + ci-workers: Variable overrides and process tweaks for CentOS 7 + Add build progress to the release script if progressbar module is available + Add hotfix support to release script + Document the hotfix release process + Enforce sequential hotfix versioning + Benchmark time to call sendtoaddress with many UTXOs + Fix bug in benchmark data generation script + Adjust instructions for UTXO dataset creation + Add GitHub release notes to release process + Clarify branching and force-building operations in hotfix process + Update user guide translations as part of release process + make-release.py: Send stderr to stdout + List dependencies for release script in release process doc + Additional test cases for importprivkey RPC test + make-release.py: Versioning changes for 1.0.12-rc1. + make-release.py: Updated manpages for 1.0.12-rc1. + +Jason Davies (1): + Fix deprecation policy comment. + +Nathan Wilcox (5): + key_import_export rpc-test: verify that UTXO view co-evolves for nodes sharing a key. + Add a new rpc-test-specified requirement: `importprivkey` outputs the associated address. (Test fails.) + [tests pass] Output address on new key import. + Add a new requirement that `importprivkey` API is idempotent. + [tests pass] Ensure `importprivkey` outputs the address in case key is already imported. + +Ross Nicoll (1): + Rationalize currency unit to "BTC" + +Simon Liu (3): + Closes #2583. Exclude watch-only utxos from z_sendmany coin selection. + Set up a clean chain. Delete redundant method wait_until_miner_sees() via use of sync_all(). + Implement RPC shield_coinbase #2448. + +kpcyrd (2): + Fetch params from ipfs if possible + Prefer wget over ipfs + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.12.md b/depend/zcash/doc/release-notes/release-notes-1.0.12.md new file mode 100644 index 000000000..6aa6cd651 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.12.md @@ -0,0 +1,65 @@ +Changelog +========= + +Ariel (1): + add examples to z_getoperationresult + +Ariel Gabizon (1): + add load-wallet benchmark + +Bjorn Hjortsberg (2): + Do not warn on built in declaration mismatch + Remove deprecated exception specification + +Jack Grigg (26): + ci-workers: Enable pipelining, and use root to set admin and host details + Variable overrides for Arch Linux + Rationalize currency unit to "ZEC" + ci-workers: Fail if Python is not version 2.7 + ci-workers: Variable overrides and process tweaks for CentOS 7 + Add build progress to the release script if progressbar module is available + Add hotfix support to release script + Document the hotfix release process + Enforce sequential hotfix versioning + Benchmark time to call sendtoaddress with many UTXOs + Fix bug in benchmark data generation script + Adjust instructions for UTXO dataset creation + Add GitHub release notes to release process + Clarify branching and force-building operations in hotfix process + Update user guide translations as part of release process + make-release.py: Send stderr to stdout + List dependencies for release script in release process doc + Additional test cases for importprivkey RPC test + make-release.py: Versioning changes for 1.0.12-rc1. + make-release.py: Updated manpages for 1.0.12-rc1. + make-release.py: Updated release notes and changelog for 1.0.12-rc1. + Fix pyflakes warnings in RPC tests + Individualise performance-measurements.sh errors for debugging + Fix incorrect failure in memory benchmark + make-release.py: Versioning changes for 1.0.12. + make-release.py: Updated manpages for 1.0.12. + +Jason Davies (1): + Fix deprecation policy comment. + +Nathan Wilcox (5): + key_import_export rpc-test: verify that UTXO view co-evolves for nodes sharing a key. + Add a new rpc-test-specified requirement: `importprivkey` outputs the associated address. (Test fails.) + [tests pass] Output address on new key import. + Add a new requirement that `importprivkey` API is idempotent. + [tests pass] Ensure `importprivkey` outputs the address in case key is already imported. + +Ross Nicoll (1): + Rationalize currency unit to "BTC" + +Simon Liu (5): + Closes #2583. Exclude watch-only utxos from z_sendmany coin selection. + Set up a clean chain. Delete redundant method wait_until_miner_sees() via use of sync_all(). + Implement RPC shield_coinbase #2448. + Update which lock to synchronize on when calling GetBestAnchor(). + Closes #2637. Make z_shieldcoinbase an experimental feature where it can be enabled with: zcashd -experimentalfeatures -zshieldcoinbase. + +kpcyrd (2): + Fetch params from ipfs if possible + Prefer wget over ipfs + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.13-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.13-rc1.md new file mode 100644 index 000000000..4d8a37a7c --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.13-rc1.md @@ -0,0 +1,88 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (37): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.13-rc2.md b/depend/zcash/doc/release-notes/release-notes-1.0.13-rc2.md new file mode 100644 index 000000000..6ade7d922 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.13-rc2.md @@ -0,0 +1,95 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (44): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + make-release.py: Updated release notes and changelog for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + Move libsnark from DIST_SUBDIRS into EXTRA_DIST + Pass correct dependencies path to libsnark from both Gitian and build.sh + Mark libsnark includes as library includes + Add the tar-pax option to automake + make-release.py: Versioning changes for 1.0.13-rc2. + make-release.py: Updated manpages for 1.0.13-rc2. + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.13.md b/depend/zcash/doc/release-notes/release-notes-1.0.13.md new file mode 100644 index 000000000..3a1a950a9 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.13.md @@ -0,0 +1,98 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (47): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + make-release.py: Updated release notes and changelog for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + Move libsnark from DIST_SUBDIRS into EXTRA_DIST + Pass correct dependencies path to libsnark from both Gitian and build.sh + Mark libsnark includes as library includes + Add the tar-pax option to automake + make-release.py: Versioning changes for 1.0.13-rc2. + make-release.py: Updated manpages for 1.0.13-rc2. + make-release.py: Updated release notes and changelog for 1.0.13-rc2. + make-release.py: Versioning changes for 1.0.13. + make-release.py: Updated manpages for 1.0.13. + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.14-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.14-rc1.md new file mode 100644 index 000000000..1654bf483 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.14-rc1.md @@ -0,0 +1,156 @@ +Notable changes +=============== + +Incoming viewing keys +--------------------- + +Support for incoming viewing keys, as described in +[the Zcash protocol spec](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf), +has been added to the wallet. + +Use the `z_exportviewingkey` RPC method to obtain the incoming viewing key for a +z-address in a node's wallet. For Sprout z-addresses, these always begin with +"ZiVK" (or "ZiVt" for testnet z-addresses). Use `z_importviewingkey` to import +these into another node. + +A node that possesses an incoming viewing key for a z-address can view all past +transactions received by that address, as well as all future transactions sent +to it, by using `z_listreceivedbyaddress`. They cannot spend any funds from the +address. This is similar to the behaviour of "watch-only" t-addresses. + +`z_gettotalbalance` now has an additional boolean parameter for including the +balance of "watch-only" addresses (both transparent and shielded), which is set +to `false` by default. `z_getbalance` has also been updated to work with +watch-only addresses. + +- **Caution:** for z-addresses, these balances will **not** be accurate if any + funds have been sent from the address. This is because incoming viewing keys + cannot detect spends, and so the "balance" is just the sum of all received + notes, including ones that have been spent. Some future use-cases for incoming + viewing keys will include synchronization data to keep their balances accurate + (e.g. [#2542](https://github.com/zcash/zcash/issues/2542)). + +Changelog +========= + +Anthony Towns (1): + Add configure check for -latomic + +Cory Fields (12): + c++11: don't throw from the reverselock destructor + c++11: CAccountingEntry must be defined before use in a list + c++11: fix libbdb build against libc++ in c++11 mode + depends: use c++11 + depends: bump OSX toolchain + build: Split hardening/fPIE options out + build: define base filenames for use elsewhere in the buildsystem + build: quiet annoying warnings without adding new ones + build: fix Windows builds without pkg-config + build: force a c++ standard to be specified + build: warn about variable length arrays + build: add --enable-werror option + +Jack Grigg (36): + Squashed 'src/secp256k1/' changes from 84973d3..6ad5cdb + Use g-prefixed coreutils commands if they are available + Replace hard-coded defaults for HOST and BUILD with config.guess + Remove manual -std=c++11 flag + Replace "install -D" with "mkdir -p && install" + Check if OpenMP is available before using it + [libsnark] Use POSIX-compliant ar arguments + Include endian-ness compatibility layer in Equihash implementation + build: Split hardening/fPIE options out in Zcash-specific binaries + Change --enable-werror to apply to all warnings, use it in build.sh + Move Zcash flags into configure.ac + ViewingKey -> ReceivingKey per zcash/zips#117 + Implement viewing key storage in the keystore + Factor out common logic from CZCPaymentAddress and CZCSpendingKey + Track net value entering and exiting the Sprout circuit + Add Sprout value pool to getblock and getblockchaininfo + Apply -fstack-protector-all to libsnark + Add Rust and Proton to configure options printout + Clarify operator precedence in serialization of nSproutValue + Remove nSproutValue TODO from CDiskBlockIndex + Add Base58 encoding of viewing keys + Implement viewing key storage in the wallet + Add RPC methods for exporting/importing viewing keys + Update wallet logic to account for viewing keys + Add watch-only support to Zcash RPC methods + Modify zcrawkeygen RPC method to set "zcviewingkey" to the viewing key + Cleanup: Add braces for clarity + Add cautions to z_getbalance and z_gettotalbalance help text about viewing keys + Add release notes for incoming viewing keys + Create release notes starting from the previous non-beta non-RC release + release-notes.py: Remove unnecessary parameter + Regenerate previous release notes to conform to new format + Exclude beta and RC release notes from author tallies + Fix pyflakes warnings in zkey_import_export RPC test + make-release.py: Versioning changes for 1.0.14-rc1. + make-release.py: Updated manpages for 1.0.14-rc1. + +Jay Graber (3): + Add cli and rpc examples for z_sendmany + Fix cli help result for z_shieldcoinbase + Add rpc test that exercises z_importkey + +Jonas Schnelli (1): + Add compile and link options echo to configure + +Luke Dashjr (4): + depends: Use curl for fetching on Linux + Travis: Use curl rather than wget for Mac SDK + Bugfix: depends/Travis: Use --location (follow redirects) and --fail [on HTTP error response] with curl + Travis: Use Blue Box VMs for IPv6 loopback support + +MarcoFalke (2): + Fix url in .travis.yml + [depends] builders: No need to set -L and --location for curl + +Per Grön (2): + Deduplicate test utility method wait_and_assert_operationid_status + Print result of RPC call in test only when PYTHON_DEBUG is set + +René Nyffenegger (1): + Use AC_ARG_VAR to set ARFLAGS. + +Simon Liu (5): + RPC dumpwallet and z_exportwallet updated to no longer allow overwriting an existing file. + Add documentation for shielding coinbase utxos. + Add documentation for payment disclosure. + Closes #2759. Fixes broken pipe error with QA test wallet.py. + Closes #2746. Payment disclosure blobs now use 'zpd:' prefix. + +Wladimir J. van der Laan (6): + build: Enable C++11 build, require C++11 compiler + build: update ax_cxx_compile_stdcxx to serial 4 + test: Remove java comparison tool + build: Remove check for `openssl/ec.h` + devtools: Check for high-entropy ASLR in 64-bit PE executables + build: supply `-Wl,--high-entropy-va` + +daniel (1): + add powerpc build support for openssl lib + +fanquake (3): + [build-aux] Update Boost & check macros to latest serials + [depends] Add -stdlib=libc++ to darwin CXX flags + [depends] Set OSX_MIN_VERSION to 10.8 + +kozyilmaz (1): + empty spaces in PATH variable cause build failure + +syd (13): + Upgrade googletest to 1.8.0 + Get the sec-hard tests to run correctly. + Update libsodium from 1.0.11 to 1.0.15 + Remove Boost conditional compilation. + Update to address @daira comments wrt fixing configure.ac + Get rid of consensus.fPowAllowMinDifficultyBlocks. + Don't compile libgtest.a when building libsnark. + Add gtests to .gitignore + Get rid of fp3 from libsnark, it is not used. + InitGoogleMock instead of InitGoogleTest per CR + Get rid of underscore prefixes for include guards. + Rename bash completion files so that they refer to zcash and not bitcoin. + Fix libsnark test failure. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.14.md b/depend/zcash/doc/release-notes/release-notes-1.0.14.md new file mode 100644 index 000000000..4b9cd0810 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.14.md @@ -0,0 +1,160 @@ +Notable changes +=============== + +Incoming viewing keys +--------------------- + +Support for incoming viewing keys, as described in +[the Zcash protocol spec](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf), +has been added to the wallet. + +Use the `z_exportviewingkey` RPC method to obtain the incoming viewing key for a +z-address in a node's wallet. For Sprout z-addresses, these always begin with +"ZiVK" (or "ZiVt" for testnet z-addresses). Use `z_importviewingkey` to import +these into another node. + +A node that possesses an incoming viewing key for a z-address can view all past +transactions received by that address, as well as all future transactions sent +to it, by using `z_listreceivedbyaddress`. They cannot spend any funds from the +address. This is similar to the behaviour of "watch-only" t-addresses. + +`z_gettotalbalance` now has an additional boolean parameter for including the +balance of "watch-only" addresses (both transparent and shielded), which is set +to `false` by default. `z_getbalance` has also been updated to work with +watch-only addresses. + +- **Caution:** for z-addresses, these balances will **not** be accurate if any + funds have been sent from the address. This is because incoming viewing keys + cannot detect spends, and so the "balance" is just the sum of all received + notes, including ones that have been spent. Some future use-cases for incoming + viewing keys will include synchronization data to keep their balances accurate + (e.g. [#2542](https://github.com/zcash/zcash/issues/2542)). + +Changelog +========= + +Anthony Towns (1): + Add configure check for -latomic + +Cory Fields (12): + c++11: don't throw from the reverselock destructor + c++11: CAccountingEntry must be defined before use in a list + c++11: fix libbdb build against libc++ in c++11 mode + depends: use c++11 + depends: bump OSX toolchain + build: Split hardening/fPIE options out + build: define base filenames for use elsewhere in the buildsystem + build: quiet annoying warnings without adding new ones + build: fix Windows builds without pkg-config + build: force a c++ standard to be specified + build: warn about variable length arrays + build: add --enable-werror option + +Jack Grigg (40): + Squashed 'src/secp256k1/' changes from 84973d3..6ad5cdb + Use g-prefixed coreutils commands if they are available + Replace hard-coded defaults for HOST and BUILD with config.guess + Remove manual -std=c++11 flag + Replace "install -D" with "mkdir -p && install" + Check if OpenMP is available before using it + [libsnark] Use POSIX-compliant ar arguments + Include endian-ness compatibility layer in Equihash implementation + build: Split hardening/fPIE options out in Zcash-specific binaries + Change --enable-werror to apply to all warnings, use it in build.sh + Move Zcash flags into configure.ac + ViewingKey -> ReceivingKey per zcash/zips#117 + Implement viewing key storage in the keystore + Factor out common logic from CZCPaymentAddress and CZCSpendingKey + Track net value entering and exiting the Sprout circuit + Add Sprout value pool to getblock and getblockchaininfo + Apply -fstack-protector-all to libsnark + Add Rust and Proton to configure options printout + Clarify operator precedence in serialization of nSproutValue + Remove nSproutValue TODO from CDiskBlockIndex + Add Base58 encoding of viewing keys + Implement viewing key storage in the wallet + Add RPC methods for exporting/importing viewing keys + Update wallet logic to account for viewing keys + Add watch-only support to Zcash RPC methods + Modify zcrawkeygen RPC method to set "zcviewingkey" to the viewing key + Cleanup: Add braces for clarity + Add cautions to z_getbalance and z_gettotalbalance help text about viewing keys + Add release notes for incoming viewing keys + Create release notes starting from the previous non-beta non-RC release + release-notes.py: Remove unnecessary parameter + Regenerate previous release notes to conform to new format + Exclude beta and RC release notes from author tallies + Fix pyflakes warnings in zkey_import_export RPC test + make-release.py: Versioning changes for 1.0.14-rc1. + make-release.py: Updated manpages for 1.0.14-rc1. + make-release.py: Updated release notes and changelog for 1.0.14-rc1. + Update release process + make-release.py: Versioning changes for 1.0.14. + make-release.py: Updated manpages for 1.0.14. + +Jay Graber (3): + Add cli and rpc examples for z_sendmany + Fix cli help result for z_shieldcoinbase + Add rpc test that exercises z_importkey + +Jonas Schnelli (1): + Add compile and link options echo to configure + +Luke Dashjr (4): + depends: Use curl for fetching on Linux + Travis: Use curl rather than wget for Mac SDK + Bugfix: depends/Travis: Use --location (follow redirects) and --fail [on HTTP error response] with curl + Travis: Use Blue Box VMs for IPv6 loopback support + +MarcoFalke (2): + Fix url in .travis.yml + [depends] builders: No need to set -L and --location for curl + +Per Grön (2): + Deduplicate test utility method wait_and_assert_operationid_status + Print result of RPC call in test only when PYTHON_DEBUG is set + +René Nyffenegger (1): + Use AC_ARG_VAR to set ARFLAGS. + +Simon Liu (5): + RPC dumpwallet and z_exportwallet updated to no longer allow overwriting an existing file. + Add documentation for shielding coinbase utxos. + Add documentation for payment disclosure. + Closes #2759. Fixes broken pipe error with QA test wallet.py. + Closes #2746. Payment disclosure blobs now use 'zpd:' prefix. + +Wladimir J. van der Laan (6): + build: Enable C++11 build, require C++11 compiler + build: update ax_cxx_compile_stdcxx to serial 4 + test: Remove java comparison tool + build: Remove check for `openssl/ec.h` + devtools: Check for high-entropy ASLR in 64-bit PE executables + build: supply `-Wl,--high-entropy-va` + +daniel (1): + add powerpc build support for openssl lib + +fanquake (3): + [build-aux] Update Boost & check macros to latest serials + [depends] Add -stdlib=libc++ to darwin CXX flags + [depends] Set OSX_MIN_VERSION to 10.8 + +kozyilmaz (1): + empty spaces in PATH variable cause build failure + +syd (13): + Upgrade googletest to 1.8.0 + Get the sec-hard tests to run correctly. + Update libsodium from 1.0.11 to 1.0.15 + Remove Boost conditional compilation. + Update to address @daira comments wrt fixing configure.ac + Get rid of consensus.fPowAllowMinDifficultyBlocks. + Don't compile libgtest.a when building libsnark. + Add gtests to .gitignore + Get rid of fp3 from libsnark, it is not used. + InitGoogleMock instead of InitGoogleTest per CR + Get rid of underscore prefixes for include guards. + Rename bash completion files so that they refer to zcash and not bitcoin. + Fix libsnark test failure. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.15-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.0.15-rc1.md new file mode 100644 index 000000000..b4b0b2f0a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.15-rc1.md @@ -0,0 +1,165 @@ +Notable changes +=============== + +UTXO and note merging +--------------------- + +In order to simplify the process of combining many small UTXOs and notes into a +few larger ones, a new RPC method `z_mergetoaddress` has been added. It merges +funds from t-addresses, z-addresses, or both, and sends them to a single +t-address or z-address. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +UTXO memory accounting +---------------------- + +The default -dbcache has been changed in this release to 450MiB. Users can set -dbcache to a higher value (e.g. to keep the UTXO set more fully cached in memory). Users on low-memory systems (such as systems with 1GB or less) should consider specifying a lower value for this parameter. + +Additional information relating to running on low-memory systems can be found here: [reducing-memory-usage.md](https://github.com/zcash/zcash/blob/master/doc/reducing-memory-usage.md). + +Changelog +========= + +21E14 (1): + Remove obsolete reference to CValidationState from UpdateCoins. + +Alex Morcos (1): + Implement helper class for CTxMemPoolEntry constructor + +Ariel (2): + add blake2b writer + update SignatureHash according to Overwinter spec + +Ashley Holman (1): + TxMemPool: Change mapTx to a boost::multi_index_container + +Cory Fields (2): + chainparams: move CCheckpointData into chainparams.h + chainparams: don't use std namespace + +Daniel Kraft (1): + Clean up chainparams some more. + +Jack Grigg (38): + Scope the ECDSA constant sizes to CPubKey / CKey classes + Enable Bash completion for -exportdir + Check chainValueZat when checking value pool monitoring + Add missing namespace for boost::get + Add viewing key prefix to regtest parameters + zkey_import_export: Synchronize mempools before mining + Use JoinSplitTestingSetup for Boost sighash tests + Network upgrade activation mechanism + Allow changing network upgrade parameters on regtest + Test network upgrade logic + Adjust rewind logic to use the network upgrade mechanism + Add Overwinter to upgrade list + Add method for fetching the next activation height after a given block height + Use a boost::optional for nCachedBranchId + Change UI/log status message for block rewinding + Update quote from ZIP 200 + Update SignatureHash tests for transaction format changes + Implement roll-back limit for reorganisation + Add rollback limit to block index rewinding + Remove mempool transactions which commit to an unmineable branch ID + Remove P2WPKH and P2WSH from signing logic + Add consensus branch ID parameter to SignatureHash, remove SigVersion parameter + Cleanup: Wrap function arguments + Regenerate SignatureHash tests + Make number of inputs configurable in validatelargetx test + Use v3 transactions with caching for validatelargetx benchmark + Extend CWallet::GetFilteredNotes to enable filtering on a set of addresses + Add branch IDs for current and next block to getblockchaininfo + Check Equihash solution when loading block index + Implement z_mergetoaddress for combining UTXOs and notes + Gate z_mergetoaddress as an experimental feature + Add z_mergetoaddress to release notes + Check upgrade status in wallet_overwintertx RPC test + Document that consensus.chaintip != consensus.nextblock just before an upgrade + Regenerate sighash tests + wallet_mergetoaddress: Add additional syncs to prevent race conditions + make-release.py: Versioning changes for 1.0.15-rc1. + make-release.py: Updated manpages for 1.0.15-rc1. + +Jay Graber (8): + Add getdeprecationinfo rpc call to return current version and deprecation block height. + Make applicable only on mainnet + Add upgrades field to RPC call getblockchaininfo + Implement transaction expiry for Overwinter + Add -txexpirydelta cli option + Add mempool_tx_expiry.py test + Add expiry to z_mergetoaddress + Change rpc_tests to 21 + +Jonas Nick (1): + Reduce unnecessary hashing in signrawtransaction + +Jorge Timón (3): + Chainparams: Introduce CreateGenesisBlock() static function + Chainparams: CTestNetParams and CRegTestParams extend directly from CChainParams + Mempool: Use Consensus::CheckTxInputs direclty over main::CheckInputs + +Marius Kjærstad (1): + Changed http:// to https:// on some links + +Mark Friedenbach (1): + Explicitly set tx.nVersion for the genesis block and mining tests + +Matt Corallo (5): + Add failing test checking timelocked-txn removal during reorg + Fix removal of time-locked transactions during reorg + Fix comment in removeForReorg + Make indentation in ActivateBestChainStep readable + removeForReorg calls once-per-disconnect-> once-per-reorg + +Maxwell Gubler (1): + Fix syntax examples for z_importwallet and export + +Nicolas DORIER (1): + Unit test for sighash caching + +Pavel Vasin (1): + remove unused NOBLKS_VERSION_{START,END} constants + +Pieter Wuille (8): + Add rewind logic to deal with post-fork software updates + Support -checkmempool=N, which runs checks on average once every N transactions + Report non-mandatory script failures correctly + Refactor script validation to observe amounts + BIP143: Verification logic + BIP143: Signing logic + Precompute sighashes + Rename to PrecomputedTransactionData + +Simon Liu (11): + Fixes #2793. Backport commit f33afd3 to increase dbcache default. + Add documentation about dbcache. + Add note about dbcache to 1.0.15 release notes. + Remove redundant service flag NODE_GETUTXO meant for Bitcoin XT. + Implementation of Overwinter transaction format ZIP 202. + Add test to check malformed v1 transaction against Overwinter tx parser + Closes #2964. z_sendmany once again makes v1 tx for taddr to taddr. + Closes #2954 and #2959. Fixes Overwinter issues in sighash_tests. + Add field nProtocolVersion to struct NetworkUpgrade. + Overwinter peer management and network handshaking. + Add python qa test overwinter_peer_management. + +Suhas Daftuar (3): + Track coinbase spends in CTxMemPoolEntry + Don't call removeForReorg if DisconnectTip fails + Fix removeForReorg to use MedianTimePast + +jc (1): + read hashReserved from disk block index + +syd (2): + Fix libsnark dependency build. + Remove OSX and Windows files from Makefile + share directory. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.15.md b/depend/zcash/doc/release-notes/release-notes-1.0.15.md new file mode 100644 index 000000000..3195c955a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.15.md @@ -0,0 +1,209 @@ +Notable changes +=============== + +Overwinter network upgrade +-------------------------- + +The code preparations for the Overwinter network upgrade, as described in [ZIP +200](https://github.com/zcash/zips/blob/master/zip-0200.rst), [ZIP +201](https://github.com/zcash/zips/blob/master/zip-0201.rst), [ZIP +202](https://github.com/zcash/zips/blob/master/zip-0202.rst), [ZIP +203](https://github.com/zcash/zips/blob/master/zip-0203.rst), and [ZIP +143](https://github.com/zcash/zips/blob/master/zip-0143.rst) are +finished and included in this release. Overwinter will activate on testnet at +height 207500, and can also be activated at a specific height in regtest mode +by setting the config option `-nuparams=5ba81b19:HEIGHT`. + +However, because the Overwinter activation height is not yet specified for +mainnet, version 1.0.15 will behave similarly as other pre-Overwinter releases +even after a future activation of Overwinter on the network. Upgrading from +1.0.15 will be required in order to follow the Overwinter network upgrade on +mainnet. + +Overwinter transaction format +----------------------------- + +Once Overwinter has activated, transactions must use the new v3 format +(including coinbase transactions). All RPC methods that create new transactions +(such as `createrawtransaction` and `getblocktemplate`) will create v3 +transactions once the Overwinter activation height has been reached. + +Overwinter transaction expiry +----------------------------- + +Overwinter transactions created by `zcashd` will also have a default expiry +height set (the block height after which the transaction becomes invalid) of 20 +blocks after the height of the next block. This can be configured with the +config option `-txexpirydelta`. + +UTXO and note merging +--------------------- + +In order to simplify the process of combining many small UTXOs and notes into a +few larger ones, a new RPC method `z_mergetoaddress` has been added. It merges +funds from t-addresses, z-addresses, or both, and sends them to a single +t-address or z-address. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +UTXO memory accounting +---------------------- + +The default `-dbcache` has been changed in this release to 450MiB. Users can set +`-dbcache` to a higher value (e.g. to keep the UTXO set more fully cached in +memory). Users on low-memory systems (such as systems with 1GB or less) should +consider specifying a lower value for this parameter. + +Additional information relating to running on low-memory systems can be found +here: [reducing-memory-usage.md](https://github.com/zcash/zcash/blob/master/doc/reducing-memory-usage.md). + +Changelog +========= + +21E14 (1): + Remove obsolete reference to CValidationState from UpdateCoins. + +Alex Morcos (1): + Implement helper class for CTxMemPoolEntry constructor + +Ariel (2): + add blake2b writer + update SignatureHash according to Overwinter spec + +Ashley Holman (1): + TxMemPool: Change mapTx to a boost::multi_index_container + +Cory Fields (2): + chainparams: move CCheckpointData into chainparams.h + chainparams: don't use std namespace + +Daniel Kraft (1): + Clean up chainparams some more. + +Jack Grigg (43): + Scope the ECDSA constant sizes to CPubKey / CKey classes + Enable Bash completion for -exportdir + Check chainValueZat when checking value pool monitoring + Add missing namespace for boost::get + Add viewing key prefix to regtest parameters + zkey_import_export: Synchronize mempools before mining + Use JoinSplitTestingSetup for Boost sighash tests + Network upgrade activation mechanism + Allow changing network upgrade parameters on regtest + Test network upgrade logic + Adjust rewind logic to use the network upgrade mechanism + Add Overwinter to upgrade list + Add method for fetching the next activation height after a given block height + Use a boost::optional for nCachedBranchId + Change UI/log status message for block rewinding + Update quote from ZIP 200 + Update SignatureHash tests for transaction format changes + Implement roll-back limit for reorganisation + Add rollback limit to block index rewinding + Remove mempool transactions which commit to an unmineable branch ID + Remove P2WPKH and P2WSH from signing logic + Add consensus branch ID parameter to SignatureHash, remove SigVersion parameter + Cleanup: Wrap function arguments + Regenerate SignatureHash tests + Make number of inputs configurable in validatelargetx test + Use v3 transactions with caching for validatelargetx benchmark + Extend CWallet::GetFilteredNotes to enable filtering on a set of addresses + Add branch IDs for current and next block to getblockchaininfo + Check Equihash solution when loading block index + Implement z_mergetoaddress for combining UTXOs and notes + Gate z_mergetoaddress as an experimental feature + Add z_mergetoaddress to release notes + Check upgrade status in wallet_overwintertx RPC test + Document that consensus.chaintip != consensus.nextblock just before an upgrade + Regenerate sighash tests + wallet_mergetoaddress: Add additional syncs to prevent race conditions + make-release.py: Versioning changes for 1.0.15-rc1. + make-release.py: Updated manpages for 1.0.15-rc1. + make-release.py: Updated release notes and changelog for 1.0.15-rc1. + Use block hash comparison for consistency check when loading block index + Overwinter release notes and testnet activation height + make-release.py: Versioning changes for 1.0.15. + make-release.py: Updated manpages for 1.0.15. + +Jay Graber (8): + Add getdeprecationinfo rpc call to return current version and deprecation block height. + Make applicable only on mainnet + Add upgrades field to RPC call getblockchaininfo + Implement transaction expiry for Overwinter + Add -txexpirydelta cli option + Add mempool_tx_expiry.py test + Add expiry to z_mergetoaddress + Change rpc_tests to 21 + +Jonas Nick (1): + Reduce unnecessary hashing in signrawtransaction + +Jorge Timón (3): + Chainparams: Introduce CreateGenesisBlock() static function + Chainparams: CTestNetParams and CRegTestParams extend directly from CChainParams + Mempool: Use Consensus::CheckTxInputs direclty over main::CheckInputs + +Marius Kjærstad (1): + Changed http:// to https:// on some links + +Mark Friedenbach (1): + Explicitly set tx.nVersion for the genesis block and mining tests + +Matt Corallo (5): + Add failing test checking timelocked-txn removal during reorg + Fix removal of time-locked transactions during reorg + Fix comment in removeForReorg + Make indentation in ActivateBestChainStep readable + removeForReorg calls once-per-disconnect-> once-per-reorg + +Maxwell Gubler (1): + Fix syntax examples for z_importwallet and export + +Nicolas DORIER (1): + Unit test for sighash caching + +Pavel Vasin (1): + remove unused NOBLKS_VERSION_{START,END} constants + +Pieter Wuille (8): + Add rewind logic to deal with post-fork software updates + Support -checkmempool=N, which runs checks on average once every N transactions + Report non-mandatory script failures correctly + Refactor script validation to observe amounts + BIP143: Verification logic + BIP143: Signing logic + Precompute sighashes + Rename to PrecomputedTransactionData + +Simon Liu (11): + Fixes #2793. Backport commit f33afd3 to increase dbcache default. + Add documentation about dbcache. + Add note about dbcache to 1.0.15 release notes. + Remove redundant service flag NODE_GETUTXO meant for Bitcoin XT. + Implementation of Overwinter transaction format ZIP 202. + Add test to check malformed v1 transaction against Overwinter tx parser + Closes #2964. z_sendmany once again makes v1 tx for taddr to taddr. + Closes #2954 and #2959. Fixes Overwinter issues in sighash_tests. + Add field nProtocolVersion to struct NetworkUpgrade. + Overwinter peer management and network handshaking. + Add python qa test overwinter_peer_management. + +Suhas Daftuar (3): + Track coinbase spends in CTxMemPoolEntry + Don't call removeForReorg if DisconnectTip fails + Fix removeForReorg to use MedianTimePast + +jc (1): + read hashReserved from disk block index + +syd (2): + Fix libsnark dependency build. + Remove OSX and Windows files from Makefile + share directory. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.2.md b/depend/zcash/doc/release-notes/release-notes-1.0.2.md new file mode 100644 index 000000000..2625cb909 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.2.md @@ -0,0 +1,16 @@ +ITH4Coinomia (2): + Update security-warnings.md + Update init.cpp + +S. Matthew English (1): + enforcing consistency 'tor' to 'Tor' + +Sean Bowe (1): + Write R1CS output to file in GenerateParams. + +Simon (4): + Fixes #1762 segfault when miner is interrupted. + Fixes #1779 so that sending to multiple zaddrs no longer fails. + Add GenIdentity, an identity function for MappedShuffle. + Add transaction size and zaddr output limit checks to z_sendmany. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.3.md b/depend/zcash/doc/release-notes/release-notes-1.0.3.md new file mode 100644 index 000000000..ae4e25b25 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.3.md @@ -0,0 +1,35 @@ +Jack Grigg (5): + Add --disable-tests flag to zcutils/build.sh + Correctly set CNoteData::witnessHeight when decrementing witness caches + Copy over CNoteData::witnessHeight when updating wallet tx + Add code comments about CNoteData::witnessHeight + Clear witnessHeight and nWitnessCacheSize in ClearNoteWitnessCache + +Jay Graber (4): + Document z_sendmany error code messages in payment-api.md + s/Bitcoin/Zcash in JSONRPCError + Change format of z_sendmany error code documentation. + Release-notes.py script to generate release notes and add contributors to authors.md + +Sean Bowe (7): + Regression test for constraint system violation. + Improve accuracy of constraint system violation diagnostics. + Add tests for witness `element` and tree `last` methods. Strengthen testing by inserting a different commitment into the tree at each step. + Initialize after profiling messages are suppressed. + Process verification keys to perform online verification. + Add test that `last` and `element` will throw exception when the tree is blank. + Anchors and nullifiers should always be inherited from the parent cache. + +Simon (8): + Closes #1833. Format currency amounts in z_sendmany error message. + Closes #1680, temporary fix for rpc deadlock inherited from upstream. + Set default minrelaytxfee to 1000 zatoshis to match upstream. + Mempool will accept tx with joinsplits and the default z_sendmany fee. + Track the correct change witness across chained joinsplits + Closes #1854. z_sendmany selects more utxos to avoid dust change output. + Partial revert of bd87e8c: file release-notes-1.0.2.md to 343b0d6. + Fix threading issue when initializing public params. + +ayleph (1): + Correct spelling error in z_sendmany error output + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.4.md b/depend/zcash/doc/release-notes/release-notes-1.0.4.md new file mode 100644 index 000000000..1cb73c393 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.4.md @@ -0,0 +1,75 @@ +Bitcoin Error Log (1): + Edit for grammar: "block chain" + +Christian von Roques (1): + bash-completion: Adapt for 0.12 and 0.13 + +Jack Grigg (32): + Add getlocalsolps and getnetworksolps RPC calls, show them in getmininginfo + Add benchmark for attempting decryption of notes + Add benchmark for incrementing note witnesses + Add -metricsui flag to toggle between persistent screen and rolling metrics + Add -metricsrefreshtime option + Only show metrics by default if stdout is a TTY + Document metrics screen options + Clarify that metrics options are only useful without -daemon and -printtoconsole + Increase length of metrics divider + Write witness caches when writing the best block + Apply miniupnpc patches to enable compilation on Solaris 11 + Add an upstream miniupnpc patch revision + Address review comments, tweak strings + Change function names to not clash with Bitcoin, apply to correct binaries + Add bash completion files to Debian package + Always bash-complete the default account + Add Zcash RPC commands to CLI argument completion + Document behaviour of CWallet::SetBestChain + Fix indentation + Generate JS for trydecryptnotes, make number of addresses a variable + Add JS to second block to ensure witnesses are incremented + Skip JoinSplit verification before the last checkpoint + Add a reindex test that fails because of a bug in decrementing witness caches + Make the test pass by fixing the bug! + Only check cache validity for witnesses being incremented or decremented + Fix bug in wallet tests + Extract block-generation wallet test code into a function + Rewrite reindex test to check beyond the max witness cache size + Fix bug in IncrementNoteWitness() + Update payment API docs to recommend -rescan for fixing witness errors + Update version to 1.0.4 + Update man pages + +Jay Graber (2): + Replace bitcoin with zcash in rpcprotocol.cpp + Gather release notes from previous release to HEAD + +Jeffrey Walton (1): + Add porter dev overrides for CC, CXX, MAKE, BUILD, HOST + +Scott (1): + Metrics - Don't exclaim unless > 1 + +Sean Bowe (8): + Isolate verification to a `ProofVerifier` context object that allows verification behavior to be tuned by the caller. + Regression test. + Ensure cache contains valid entry when anchor is popped. + Ensure ProofVerifier cannot be accidentally copied. + Rename Dummy to Disabled. + Add more tests for ProofVerifier. + ASSERT_TRUE -> ASSERT_FALSE + Check that E' points are actually in G2 by ensuring they are of order r. + +Simon Liu (8): + Fix stale comment referencing upstream block interval + Add checkpoint at block height 15000 + Closes #1857. Fixes bug where tx spending only notes had priority of 0. + Closes #1901. Increase default settings for the max block size when mining and the amount of space available for priority transactions. + Closes #1903. Add fee parameter to z_sendmany. + Fixes #1823. Witness anchors for input notes no longer cross block boundaries. + Increase timeout as laptops on battery power have cpu throttling. + WitnessAnchorData only needs to store one witness per JSOutPoint. + +lpescher (3): + Make command line option to show all debugging consistent with similar options + Update documentation to match the #4219 change + Update help message to match the #4219 change + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.5.md b/depend/zcash/doc/release-notes/release-notes-1.0.5.md new file mode 100644 index 000000000..7e2c6e1c8 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.5.md @@ -0,0 +1,58 @@ +Eran Tromer (1): + CreateJoinSplit: add start_profiling() call + +Jack Grigg (22): + Extend createjoinsplit to benchmark parallel JoinSplits + Add total number of commitments to getblockchaininfo + Only enable getblocktemplate when wallet is enabled + Only run wallet tests when wallet is enabled + Add a tool for profiling the creation of JoinSplits + Exclude test binaries from make install + Scan the whole chain whenever a z-key is imported + Instruct users to run zcash-fetch-params if network params aren't available + Trigger metrics UI refresh on new messages + Strip out the SECURE flag in metrics UI so message style is detected + Handle newlines in UI messages + Suggest ./zcutil/fetch-params.sh as well + Update debug categories + Rename build-aux/m4/bitcoin_find_bdb48.m4 to remove version + Throw an error if zcash.conf is missing + Show a friendly message explaining why zcashd needs a zcash.conf + Fix gtest ordering broken by #1949 + Debian package lint + Generate Debian control file to fix shlibs lint + Create empty zcash.conf during performance measurements + Create empty zcash.conf during coverage checks + Coverage build system tweaks + +Jay Graber (1): + Update release process to check in with users who opened resolved issues + +Paige Peterson (2): + Create ISSUE_TEMPLATE.md + move template to subdirectory, fix typo, include prompt under describing issue section, include uploading file directly to github ticket as option for sharing logs + +Sean Bowe (4): + Add test for IncrementalMerkleTree::size(). + Add 'CreateJoinSplit' standalone utility to gitignore. + Add test for z_importkey rescanning from beginning of chain. + Bump version to 1.0.5. + +Simon Liu (13): + Fixes #1964 to catch general exception in z_sendmany and catch exceptions as reference-to-const. + Fixes #1967 by adding age of note to z_sendmany logging. + Fixes a bug where the unsigned transaction was logged by z_sendmany after a successful sign and send, meaning that the logged hash fragment would be different from the txid logged by "AddToWallet". This issue occured when sending from transparent addresses, as utxo inputs must be signed. It did not occur when sending from shielded addresses. + Bump COPYRIGHT_YEAR from 2016 to 2017. + Closes #1780. Result of z_getoperationstatus now sorted by creation time of operation + Remove UTF-8 BOM efbbbf from zcash.conf to avoid problems with command line tools + Closes #1097 so zcash-cli now displays license info like zcashd. + Fixes #1497 ZCA-009 by restricting data exporting to user defined folder. + Closes #1957 by adding tx serialization size to listtransactions output. + Fixes #1960: z_getoperationstatus/result now includes operation details. + Update walletbackup.py qa test to use -exportdir option + Add missing header required by std::accumulate + Increase timeout for z_sendmany transaction in wallet.py qa test + +Wladimir J. van der Laan (1): + rpc: Implement random-cookie based authentication + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.6.md b/depend/zcash/doc/release-notes/release-notes-1.0.6.md new file mode 100644 index 000000000..c1ae03605 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.6.md @@ -0,0 +1,148 @@ +Cory Fields (4): + Depends: Add ZeroMQ package + travis: install a recent libzmq and pyzmq for tests + build: Make use of ZMQ_CFLAGS + build: match upstream build change + +Daira Hopwood (2): + Better error reporting for the !ENABLE_WALLET && ENABLE_MINING case. + Address @str4d's comment about the case where -gen is not set. Also avoid shadowing mineToLocalWallet variable. + +Daniel Cousens (3): + init: amend ZMQ flag names + init: add zmq to debug categories + zmq: prepend zmq to debug messages + +Jack Grigg (33): + Update comment + Remove OpenSSL PRNG reseeding + Address review comments + Fix linking error in CreateJoinSplit + Add compile flag to disable compilation of mining code + Upgrade OpenSSL to 1.1.0d + Show all JoinSplit components in getrawtransaction and decoderawtransaction + Use a more specific exception class for note decryption failure + Switch miner to P2PKH, add -mineraddress option + Update help text for mining options + Correct #ifdef nesting of miner headers and helper functions + Add ZMQ libs to zcash-gtest + Fix python syntax in ZMQ RPC test + [qa] py2: Unfiddle strings into bytes explicitly in ZMQ RPC test + Bitcoin -> Zcash in ZMQ docs + Add ZeroMQ license to contrib/debian/copyright + [depends] ZeroMQ 4.2.1 + Clarify that user only needs libzmq if not using depends system + Bump suggested ZMQ Debian package to 4.1 series + Add -minetolocalwallet flag, enforced on -mineraddress + Add test to check for presence of vpub_old & vpub_new in getrawtransaction + Add a flag for enabling experimental features + Require -experimentalmode for wallet encryption + Migrate Zcash-specific code to UniValue + Manually iterate over UniValue arrays in tests + Remove JSON Spirit from contrib/debian/copyright + unsigned int -> size_t for comparing with UniValue.size() + [cleanup] Remove unused import + [cleanup] Simplify test code + Squashed 'src/univalue/' content from commit 9ef5b78 + Update UniValue includes in Zcash-specific code + UniValue::getValues const reference + Get rid of fPlus argument to FormatMoney in Zcash-specific code + +Jeff Garzik (4): + Add ZeroMQ support. Notify blocks and transactions via ZeroMQ + UniValue: prefer .size() to .count(), to harmonize w/ existing tree + UniValue: export NullUniValue global constant + Convert tree to using univalue. Eliminate all json_spirit uses. + +Johnathan Corgan (5): + zmq: require version 4.x or newer of libzmq + zmq: update and cleanup build-unix, release-notes, and zmq docs + autotools: move checking for zmq library to common area in configure.ac + zmq: update docs to reflect feature is compiled in automatically if possible + zmq: point API link to 4.0 as that is what we are conforming to [Trivial] + +Jonas Schnelli (24): + QA: Add ZeroMQ RPC test + depends: fix platform specific packages variable + [travis] add zmq python module + use CBlockIndex* insted of uint256 for UpdatedBlockTip signal + [ZMQ] refactor message string + [ZMQ] append a message sequence number to every ZMQ notification + fix rpc-tests.sh + extend conversion to UniValue + expicit set UniValue type to avoid empty values + special threatment for null,true,false because they are non valid json + univalue: add support for real, fix percision and make it json_spirit compatible + univalue: correct bool support + fix rpc unit test, plain numbers are not JSON compatible object + remove JSON Spirit UniValue wrapper + Remove JSON Spirit wrapper, remove JSON Spirit leftovers + fix rpc batching univalue issue + fix missing univalue types during constructing + fix univalue json parse tests + univalue: add type check unit tests + fix util_tests.cpp clang warnings + fix rpcmining/getblocktemplate univalue transition logic error + remove univalue, prepare for subtree + [Univalue] add univalue over subtree + remove $(@F) and subdirs from univalue make + +João Barbosa (2): + Add UpdatedBlockTip signal to CMainSignals and CValidationInterface + Fix ZMQ Notification initialization and shutdown + +Paragon Initiative Enterprises, LLC (1): + Use libsodium's CSPRNG instead of OpenSSL's + +Scott (1): + Update random.h + +Sean Bowe (3): + Bump protocol version in release process if necessary. + Fix use after free in transaction_tests. + Update libsnark. + +Simon Liu (16): + Closes #2057 by adding extra zrpcunsafe logging + Update z_sendmany logging + Add test to verify z_sendmany logging + Update test to verify order of zrpcunsafe log messages + Closes #2045 by allowing z_sendmany with 0 fee + Closes #2024 by documenting and testing method field in z_getoperationstatus + Add parameter interaction, where zrpcunsafe implies zrpc + Update zrpc vs zrpcunsafe logging in z_sendmany operation + Add test for z_sendmany with fee of 0 + Update test to check for more joinsplit related fields in getrawtransaction + Add comment about fix for #2026. + Update test to check for updated error messages in AmountFromValue(). + Bump version to 1.0.6 as part of release process + Debian man pages updated as part of release process + Update release notes as part of release process + Update debian changelog as part of release process + +Wladimir J. van der Laan (10): + Simplify RPCclient, adapt json_parse_error test + util: Add ParseInt64 and ParseDouble functions + univalue: add strict type checking + Don't go through double in AmountFromValue and ValueFromAmount + Get rid of fPlus argument to FormatMoney + Changes necessary now that zero values accepted in AmountFromValue + rpc: Accept scientific notation for monetary amounts in JSON + rpc: Make ValueFromAmount always return 8 decimals + univalue: Avoid unnecessary roundtrip through double for numbers + util: use locale-independent parsing in ParseDouble + +fanquake (3): + [depends] zeromq 4.0.7 + [depends] ZeroMQ 4.1.4 + [depends] ZeroMQ 4.1.5 + +isle2983 (1): + [copyright] add MIT License copyright header to zmq_sub.py + +mrbandrews (1): + Fixes ZMQ startup with bad arguments. + +paveljanik (1): + [Trivial] start the help texts with lowercase + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.7-1.md b/depend/zcash/doc/release-notes/release-notes-1.0.7-1.md new file mode 100644 index 000000000..6474eb628 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.7-1.md @@ -0,0 +1,4 @@ +Jay Graber (3): + Add -t to git fetch for release-notes.py + Update version to 1.0.7-1 + Update auto-generated manpages to 1.0.7-1 diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.7.md b/depend/zcash/doc/release-notes/release-notes-1.0.7.md new file mode 100644 index 000000000..94681f0d8 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.7.md @@ -0,0 +1,165 @@ +Adam Weiss (1): + Buffer log messages and explicitly open logs + +Alex van der Peet (1): + New RPC command disconnectnode + +Allan Niemerg (1): + Pause mining during joinsplit creation + +Casey Rodarmor (1): + Don't share objects between TestInstances + +Cory Fields (2): + locking: teach Clang's -Wthread-safety to cope with our scoped lock macros + locking: add a quick example of GUARDED_BY + +Daira Hopwood (1): + Don't assume sizes of unsigned short and unsigned int in GetSizeOfCompactSize and WriteCompactSize. Fixes #2137 + +Daniel Kraft (1): + Fix univalue handling of \u0000 characters. + +Florian Schmaus (1): + Add BITCOIND_SIGTERM_TIMEOUT to OpenRC init scripts + +Forrest Voight (1): + When processing RPC commands during warmup phase, parse the request object before returning an error so that id value can be used in the response. + +Gavin Andresen (2): + configure --enable-debug changes + Testing infrastructure: mocktime fixes + +Jack Grigg (11): + Remove reference to -reindex-chainstate + Treat metrics screen as non-interactive for now + Adjust gen-manpages.sh for Zcash, use in Debian builds + Regenerate and collate Zcash manpages, delete Bitcoin ones + Update release process with gen-manpages.sh + Adjust blockheaderToJSON() for Zcash block header + Adjust fundrawtransaction RPC test for Zcash + Re-encode t-addrs in disablewallet.py with Zcash prefixes + BTC -> ZEC in paytxfee RPC docs + Update default RPC port in help strings + Fix typo in listbanned RPC keys + +Jay Graber (4): + Add rpc test for prioritisetransaction + Inc num of txs in test mempool + Update release to 1.0.7, generate manpages + Add 1.0.7 release notes and update authors.md + +Jonas Schnelli (23): + [net] extend core functionallity for ban/unban/listban + [RPC] add setban/listbanned/clearbanned RPC commands + [QA] add setban/listbanned/clearbanned tests + [net] remove unused return type bool from CNode::Ban() + [RPC] extend setban to allow subnets + rename json field "bannedtill" to "banned_until" + setban: rewrite to UniValue, allow absolute bantime + fix CSubNet comparison operator + setban: add RPCErrorCode + add RPC tests for setban & disconnectnode + fix missing lock in CNode::ClearBanned() + setban: add IPv6 tests + fix lock issue for QT node diconnect and RPC disconnectnode + fundrawtransaction tests + UniValue: don't escape solidus, keep espacing of reverse solidus + [REST] add JSON support for /rest/headers/ + [QA] fix possible reorg issue in rawtransaction.py/fundrawtransaction.py RPC test + [QA] remove rawtransactions.py from the extended test list + [QA] add testcases for parsing strings as values + [bitcoin-cli] improve error output + fix and extend CBitcoinExtKeyBase template + extend bip32 tests to cover Base58c/CExtKey decode + don't try to decode invalid encoded ext keys + +Jorge Timón (1): + Consensus: Refactor: Separate Consensus::CheckTxInputs and GetSpendHeight in CheckInputs + +Leo Arias (1): + Fix the path to the example configuration + +Luke Dashjr (1): + Fix various warnings + +Matt Corallo (4): + Small tweaks to CCoinControl for fundrawtransaction + Add FundTransaction method to wallet + Add fundrawtransaction RPC method + Assert on probable deadlocks if the second lock isnt try_lock + +Murilo Santana (1): + Fix sha256sum on busybox by using -c instead of --check + +Paul Georgiou (1): + Update Linearize tool to support Windows paths + +Pavel Vasin (1): + remove unused inv from ConnectTip() + +Peter Todd (2): + Add getblockheader RPC call + Improve comment explaining purpose of MAX_MONEY constant + +Philip Kaufmann (3): + use const references where appropriate + [init] add -blockversion help and extend -upnp help + make CAddrMan::size() return the correct type of size_t + +Pieter Wuille (3): + Do not ask a UI question from bitcoind + Add DummySignatureCreator which just creates zeroed sigs + Reduce checkpoints' effect on consensus. + +Simon Liu (14): + Alert 1000 + Alert 1001 + Add assert to check alert message length is valid + Fix bug where test was generating but not saving keys to wallet on disk. + Update founders reward addresses for testnet + Keep first three original testnet fr addresses so existing coinbase transactions on testnet remain valid during upgrade. New addresses will be used starting from block 53127. + Closes #2083 and #2088. Update release process documentation + Closes #2084. Fix incorrect year in timestamp. + Closes #2112 where z_getoperationresult could return stale status. + Add mainnet checkpoint at block 67500 + Add testnet checkpoint at block 38000 + Closes #1969. Default fee now sufficient for large shielded tx. + Part of #1969. Changing min fee calculation also changes the dust threshold. + Part of #1969. Update tests to avoid error 'absurdly high fee' from change in min fee calc. + +Stephen (1): + Add paytxfee to getwalletinfo, warnings to getnetworkinfo + +Wladimir J. van der Laan (10): + rpc: make `gettxoutsettinfo` run lock-free + test: Move reindex test to standard tests + rpc: Remove chain-specific RequireRPCPassword + univalue: Avoid unnecessary roundtrip through double for numbers + rpc: Accept strings in AmountFromValue + Fix crash in validateaddress with -disablewallet + Improve proxy initialization + tests: Extend RPC proxy tests + build: Remove -DBOOST_SPIRIT_THREADSAFE + tests: Fix bitcoin-tx signing testcase + +dexX7 (1): + Return all available information via validateaddress + +mruddy (1): + add tests for the decodescript rpc. add mention of the rpc regression tests to the testing seciton of the main readme. + +nomnombtc (9): + add script to generate manpages with help2man + add gen-manpages.sh description to README.md + add autogenerated manpages by help2man + add doc/man/Makefile.am to include manpages + add doc/man to subdir if configure flag --enable-man is set + add conditional for --enable-man, default is yes + change help string --enable-man to --disable-man + regenerated all manpages with commit tag stripped, also add bitcoin-tx + improved gen-manpages.sh, includes bitcoin-tx and strips commit tag, now also runs binaries from build dir by default, added variables for more control + +zathras-crypto (1): + Exempt unspendable transaction outputs from dust checks + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.8-1.md b/depend/zcash/doc/release-notes/release-notes-1.0.8-1.md new file mode 100644 index 000000000..4650f552c --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.8-1.md @@ -0,0 +1,16 @@ +Daira Hopwood (3): + Don't rely on a finite upper bound on fee rate or priority. + Simplify JoinSplit priority calculation. refs 1896 + Add check for JoinSplit priority as calculated by CCoinsViewCache::GetPriority. + +Jack Grigg (1): + Use a larger -rpcclienttimeout for slow performance measurements + +Nathan Wilcox (2): + Bump version numbers for v1.0.8-1. + Commit the changes from gen-manpages.sh, except manually tweak the version strings. + +str4d (2): + Update tests to check actual infinity as well as INF_FEERATE + Add unit test for security issue 2017-04-11.a + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.8.md b/depend/zcash/doc/release-notes/release-notes-1.0.8.md new file mode 100644 index 000000000..7d6460c88 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.8.md @@ -0,0 +1,170 @@ +Adam Brown (1): + [doc] Update port in tor.md + +Bob McElrath (1): + Add explicit shared_ptr constructor due to C++11 error + +Cory Fields (2): + libevent: add depends + libevent: Windows reuseaddr workaround in depends + +Daira Hopwood (15): + Remove src/qt. + License updates for removal of src/qt. + Correct license text for LGPL. + Remove QT gunk from Makefiles. + Remove some more QT-related stragglers. + Update documentation for QT removal. + Update which libraries are allowed to be linked to zcashd by symbol-check.py. + Remove NO_QT make option. + .gitignore cache/ and venv-mnf/ + Remove unused packages and patches. + Delete -rootcertificates from bash completion script. + Line-wrap privacy notice. Use <> around URL and end sentence with '.'. Include privacy notice in help text for zcashd -help. + Update version numbers. + Improvement to release process doc. + Generate man pages. + +Daniel Cousens (1): + torcontrol: only output disconnect if -debug=tor + +Gregory Maxwell (3): + Avoid a compile error on hosts with libevent too old for EVENT_LOG_WARN. + Do not absolutely protect local peers from eviction. + Decide eviction group ties based on time. + +Ian Kelling (1): + Docs: add details to -rpcclienttimeout doc + +Jack Gavigan (2): + Removed markdown from COPYING + Updated the Bitcoin Core copyright statement + +Jack Grigg (25): + Add anchor to output of getblock + Migrate IncrementalMerkleTree memory usage calls + Add tests for getmempoolinfo + Usability improvements for z_importkey + Implement an AtomicTimer + Use AtomicTimer for more accurate local solution rate + Metrics: Move local solution rate into stats + Metrics: Improve mining status + Expand on reasons for mining being paused + Simplify z_importkey by making rescan a string + Revert "Closes #1680, temporary fix for rpc deadlock inherited from upstream." + Add libevent to zcash-gtest + [depends] libevent 2.1.8 + Test boolean fallback in z_importkey + Require that z_importkey height parameter be in valid range + Update LocalSolPS test + Add AtomicTimer tests + Revert "Revert "rpc-tests: re-enable rpc-tests for Windows"" + Wrap error string + Fix typo + torcontrol: Improve comments + torcontrol: Add unit tests for Tor reply parsers + torcontrol: Fix ParseTorReplyMapping + torcontrol: Check for reading errors in ReadBinaryFile + torcontrol: Log invalid parameters in Tor reply strings where meaningful + +Jay Graber (5): + Document returned results of submitblock + Edit release-process.md for clarity + Add security warning to zcash-cli --help and --version message output + Add security warning to zcashd metrics display + Add security message to license text, rm url from translation string + +Jonas Schnelli (1): + Fix torcontrol.cpp unused private field warning + +Karl-Johan Alm (4): + Added std::unique_ptr<> wrappers with deleters for libevent modules. + Switched bitcoin-cli.cpp to use RAII unique pointers with deleters. + Added some simple tests for the RAII-style events. + Added EVENT_CFLAGS to test makefile to explicitly include libevent headers. + +Luke Dashjr (1): + Skip RAII event tests if libevent is built without event_set_mem_functions + +MarcoFalke (2): + [doc] [tor] Clarify when to use bind + torcontrol debug: Change to a blanket message that covers both cases + +Matt Quinn (1): + Consolidate individual references to the current maximum peer connection value of 125 into a single constant declaration. + +Nathaniel Mahieu (1): + Clarify documentation for running a tor node + +Patrick Strateman (1): + Remove vfReachable and modify IsReachable to only use vfLimited. + +Pavel Janík (3): + Implement REST mempool API, add test and documentation. + Prevent -Wshadow warnings with gcc versions 4.8.5, 5.3.1 and 6.2.1. + Make some global variables less-global (static) + +Peter Todd (2): + Better error message if Tor version too old + Connect to Tor hidden services by default + +Pieter Wuille (3): + Implement accurate memory accounting for mempool + Separate core memory usage computation in core_memusage.h + Fix interrupted HTTP RPC connection workaround for Python 3.5+ + +Sean Bowe (2): + Introduce librustzcash and Rust to depends system. + Allow Rust-language related assets to be disabled with `--disable-rust`. + +Simon Liu (4): + Remove stale Qt comments and dead code + Remove QT translation support files + Remove redundant gui options from build scripts + Closes #2186. RPC getblock now accepts height or hash. + +Wladimir J. van der Laan (28): + doc: remove documentation for rpcssl + qa: Remove -rpckeepalive tests from httpbasics + Remove rpc_boostasiotocnetaddr test + build: build-system changes for libevent + tests: GET requests cannot have request body, use POST in rest.py + evhttpd implementation + Implement RPCTimerHandler for Qt RPC console + Document options for new HTTP/RPC server in --help + Fix race condition between starting HTTP server thread and setting EventBase() + Move windows socket init to utility function + Revert "rpc-tests: re-enable rpc-tests for Windows" + init: Ignore SIGPIPE + http: Disable libevent debug logging, if not explicitly enabled + rpc: Split option -rpctimeout into -rpcservertimeout and -rpcclienttimeout + Make RPC tests cope with server-side timeout between requests + chain: define enum used as bit field as uint32_t + auto_ptr → unique_ptr + bitcoin-cli: More detailed error reporting + depends: Add libevent compatibility patch for windows + bitcoin-cli: Make error message less confusing + test: Avoid ConnectionResetErrors during RPC tests + net: Automatically create hidden service, listen on Tor + torcontrol improvements and fixes + doc: update docs for Tor listening + tests: Disable Tor interaction + Fix memleak in TorController [rework] + tor: Change auth order to only use HASHEDPASSWORD if -torpassword + torcontrol: Explicitly request RSA1024 private key + +calebogden (1): + Fixing typos on security-check.py and torcontrol.cpp + +fanquake (1): + [depends] libevent 2.1.7rc + +instagibbs (1): + Add common failure cases for rpc server connection failure + +paveljanik (1): + [TRIVIAL] Fix typo: exactmath -> exactmatch + +unsystemizer (1): + Clarify `listenonion` + diff --git a/depend/zcash/doc/release-notes/release-notes-1.0.9.md b/depend/zcash/doc/release-notes/release-notes-1.0.9.md new file mode 100644 index 000000000..a1335ec97 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.0.9.md @@ -0,0 +1,90 @@ +Amgad Abdelhafez (2): + Update timedata.cpp + Update timedata.cpp + +Daira Hopwood (4): + Fix an error reporting bug due to BrokenPipeError and ConnectionResetError not existing in Python 2. refs #2263 + Alert 1002 (versions 1.0.0-1.0.2 inclusive). + Alert 1003 (versions 1.0.3-1.0.8 inclusive). + Disable building Proton by default. + +Jack Grigg (14): + Fix prioritisetransaction RPC test + torcontrol: Handle escapes in Tor QuotedStrings + torcontrol: Add missing copyright header + Convert Zcash versions to Debian format + [manpage] Handle build numbers in versions + Address Daira's comments + Address Daira's further comments + Correctly handle three-digit octals with leading digit 4-7 + Check that >3-digit octals are truncated. + Implement automatic shutdown of deprecated Zcash versions + Wrap messages nicely on metrics screen + Regenerate miner tests + Add a benchmark for calling ConnectBlock on a block with many inputs + Remove additional sources of determinism from benchmark archive + +Jay Graber (2): + Change help text examples to use Zcash addresses + Poll on getblocktemplate result rather than use bare sleep to avoid race condition. + +Nathan Wilcox (39): + [Direct master commit] Fix a release snafu in debian version string. + Show toolchain versions in build.sh. + Start on a make-release.py script; currently just arg parsing and unittests [unittests fail]. + Update version spec by altering test; also update regex to pass single 0 digits in major/minor/patch. + Add another case from debian-style versions. + Add all of the zcash release tags in my current repo as positive test vector. + Add support for beta/rc release versions. + Add version sorting, assert that RELEASE_PREV is the most recent release. + Make SystemExit errors less redundant in output; verify clean git status on master. + Always run unittests prior to actual runs. + Make --help output clean by not running self-test. + Add an option to run against a different repo directory. + Make sure to pull the latest master. + Exit instead of raising an unexpected exception, since it's already logged. + Implement `PathPatcher` abstraction, `clientversion.h` rewrite, and build numbering w/ unittests. + Implement the IS_RELEASE rule for betas. + Generalize buildnum patching for both `clientversion.h` and `configure.ac`. + Modify the `APPROX_RELEASE_HEIGHT`. + Remove portions of `./doc/release-process.md` now implemented in `make-release.py`. + Switch from `sh_out_logged` to `sh_log`. + Shorten the arg log line. + Commit the version changes and build. + Generate manpages; commit that; improve error output in sh_log. + Polish logging a bit more. + Tidy up / systematize logging output a bit more. + First full-release-branch version of script; rewrite large swatch of release-process.md. [Manually tested.] + Enable set -u mode. + Fix a variable name typo. + Reuse zcash_rpc. + Do not use `-rpcwait` on all `zcash_rpc` invocations, only block when starting zcashd. + Fix `release-process.md` doc usage for `make-release.py` to have correct arguments and order. + Include release version in commit comments. + Examine all future versions which are assumed to follow the same Version parser schema. + Consider both beta and rc versions to be `IS_RELEASE == false`. + Add a few more version strings to positive parser test. + Define the deprecation policy for 1.0.9. + Clarify that the feature is automated *shutdown*. + make-release.py: Versioning changes for 1.0.9. + make-release.py: Updated manpages for 1.0.9. + +Paige Peterson (4): + wallet backup instructions + typo and rewording edits + str4d and Ariel's suggestions + specify exportdir being within homedirectory + +Sean Bowe (1): + Check that pairings work properly when the G1 point is at infinity. + +Simon Liu (5): + Add AMQP 1.0 support via Apache Qpid Proton C++ API 0.17.0 + Add --disable-proton flag to build.sh. Proton has build/linker issues with gcc 4.9.2 and requires gcc 5.x. + Fix proton build issue with debian jessie, as used on CI servers. + Change regtest port to 18344. Closes #2269. + Patch to build Proton with minimal dependencies. + +emilrus (1): + Replace bitcoind with zcashd + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.1.0-rc1.md new file mode 100644 index 000000000..a769b97cf --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.0-rc1.md @@ -0,0 +1,180 @@ +Notable changes +=============== + +`-mempooltxinputlimit` deprecation +---------------------------------- + +The configuration option `-mempooltxinputlimit` was added in release 1.0.10 as a +short-term fix for the quadratic hashing problem inherited from Bitcoin. At the +time, transactions with many inputs were causing performance issues for miners. +Since then, several performance improvements have been merged from the Bitcoin +Core codebase that significantly reduce these issues. + +The Overwinter network upgrade includes changes that solve the quadratic hashing +problem, and so `-mempooltxinputlimit` will no longer be needed - a transaction +with 1000 inputs will take just as long to validate as 10 transactions with 100 +inputs each. Starting from this release, `-mempooltxinputlimit` will be enforced +before the Overwinter activation height is reached, but will be ignored once +Overwinter activates. The option will be removed entirely in a future release +after Overwinter has activated. + +`NODE_BLOOM` service bit +------------------------ + +Support for the `NODE_BLOOM` service bit, as described in [BIP +111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been +added to the P2P protocol code. + +BIP 111 defines a service bit to allow peers to advertise that they support +Bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol +version to allow peers to identify old nodes which allow Bloom filtering of the +connection despite lacking the new service bit. + +In this version, it is only enforced for peers that send protocol versions +`>=170004`. For the next major version it is planned that this restriction will be +removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` +service bit for nodes that report version 170004 or newer. + +Changelog +========= + +Brad Miller (2): + Clean up + Implement note locking for z_mergetoaddress + +Charlie O'Keefe (1): + Add filename and sha256 hash for windows rust package + +Daira Hopwood (5): + Squashed commit of the following: + pyflakes cleanups to RPC tests after Overwinter PRs. + Add support for Overwinter v3 transactions to mininode framework. + Test that receiving an expired transaction does not increase the peer's ban score. + Don't increase banscore if the transaction only just expired. + +Daniel Kraft (1): + trivial: use constants for db keys + +Jack Grigg (43): + Add environment variable for setting ./configure flags in zcutil/build.sh + Add configure flags for enabling ASan/UBSan and TSan + Split declaration and definition of SPROUT_BRANCH_ID constant + Add link to Overwinter info page + Notify users about auto-senescence via -alertnotify + test: Move wait_and_assert_operationid_status debug output before asserts + Don't require RELRO and BIND_NOW for Darwin + Only set multicore flags if OpenMP is available + Revert "remove -mt suffix from boost libraries built by depends" + Use correct Boost::System linker flag for libzcash + depends: Remove -mt suffix from Boost libraries + snark: Remove -mt suffix from Boost library + cleanup: Ensure code is pyflakes-clean for CI + Ignore -mempooltxinputlimit once Overwinter activates + depends: Explicitly download and vendor Rust dependencies + Make Rust compilation mandatory + Optimise serialization of MerklePath, avoiding ambiguity of std::vector + Use uint64_t instead of size_t for serialized indices into tx.vjoinsplit + Move explicit instantiation of IncrementalMerkleTree::emptyroots into header + libsnark: Don't set -static on Darwin + Set PLATFORM flag when compiling libsnark + Add base case to CurrentEpoch() + Cast ZCIncrementalMerkleTree::size() to uint64_t before passing to UniValue + rpcwallet.cpp: Cast size_t to uint64_t before passing to UniValue + wallet: Cast size_t to uint64_t before passing to UniValue + Test calling z_mergetoaddress to merge notes while a note merge is ongoing + depends: Fix regex bugs in cargo-checksum.sh + Fix z_importviewingkey startHeight parameter + Add RPC test of RewindBlockIndex + When rewinding, remove insufficiently-validated blocks + Adjust deprecation message to work in both UI and -alertnotify + Refactor Zcash changes to CCoinsViewDB + Update blockchain.py RPC test for Zcash + Update CBlockTreeDB::EraseBatchSync for dbwrapper refactor + Fix typo + test: Check return value of snprintf + test: Add missing Overwinter fields to mininode's CTransaction + Add RPC test for -enforcenodebloom + Fix NODE_BLOOM documentation errors + Move bloom filter filtering logic back into command "switch" + Update -enforcenodebloom RPC test with filterclear vs filteradd + make-release.py: Versioning changes for 1.1.0-rc1. + make-release.py: Updated manpages for 1.1.0-rc1. + +James O'Beirne (3): + Refactor leveldbwrapper + Minor bugfixes + Add tests for gettxoutsetinfo, CLevelDBBatch, CLevelDBIterator + +Jason Davies (1): + Fix typo in comment: should link to issue #1359. + +Jay Graber (1): + Set ban score for expired txs to 0 + +Jeff Garzik (3): + leveldbwrapper: Remove unused .Prev(), .SeekToLast() methods + leveldbwrapper symbol rename: Remove "Level" from class, etc. names + leveldbwrapper file rename to dbwrapper.* + +Jonathan "Duke" Leto (7): + Fix references to Bitcoin in RPC tests readme + This library seems to not be used at all and all comments mentioning it are ghosts + Update awkward wording about blocks as per @daira + Regtest mining does have a founders reward, a single address t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg + Fix outdated comment about starting balance of nodes + Return JoinSplit and JoinSplitOutput indexes in z_listreceivedbyaddress + Add tests for new JoinSplit keys returned by z_listreceivedbyaddress + +Lauda (1): + [Trivial] Grammar and typo correction + +Matt Corallo (3): + Add test for dbwrapper iterators with same-prefix keys. + Add NODE_BLOOM service bit and bump protocol version + Don't do mempool lookups for "mempool" command without a filter + +Patick Strateman (3): + Move bloom filter filtering logic outside of command "switch" (giant if/else). + Add enforcenodebloom option. + Document both the peerbloomfilters and enforcenodebloom options. + +Pavel Janík (1): + Do not shadow members in dbwrapper + +Pieter Wuille (2): + Encapsulate CLevelDB iterators cleanly + Fix chainstate serialized_size computation + +R E Broadley (1): + Allow filterclear messages for enabling TX relay only. + +Simon Liu (13): + Code clean up. Remove use of X macro. + Enable mempool logging in tx expiry QA test. + Closes #3084. Log txid when removing expired txs from mempool. + Add qa test for cache invalidation bug found in v1.0.0 to v1.0.3. + Remove local function wait_and_assert_operationid_status which is now defined in the test framework for shared usage. + Update boost to 1.66.0 + Part of #2966, extending Sprout tests to other epochs. + Update boost package URL to match official download url on boost.org + Closes #3110. Ensure user can see error message about absurdly high fees. + Closes #2910. Add z_listunspent RPC call. + Upgrade OpenSSL to 1.1.0h + Use range based for loop + Bump MIT Licence copyright header. + +Wladimir J. van der Laan (6): + dbwrapper: Pass parent CDBWrapper into CDBBatch and CDBIterator + dbwrapper: Move `HandleError` to `dbwrapper_private` + chain: Add assertion in case of missing records in index db + test: Add more thorough test for dbwrapper iterators + test: Replace remaining sprintf with snprintf + doc: update release-notes and bips.md for BIP111 + +kozyilmaz (1): + Fix test/gtest bugs caught by latest macOS clang + +rofl0r (2): + fix build error due to usage of obsolete boost_system-mt + remove -mt suffix from boost libraries built by depends + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.0.md b/depend/zcash/doc/release-notes/release-notes-1.1.0.md new file mode 100644 index 000000000..37f803e6f --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.0.md @@ -0,0 +1,193 @@ +Notable changes +=============== + +Overwinter network upgrade +-------------------------- + +The activation height for the Overwinter network upgrade on mainnet is included +in this release. Overwinter will activate on mainnet at height 347500, which is +expected to be mined on the 25th of June 2018. Please upgrade to this release, +or any subsequent release, in order to follow the Overwinter network upgrade. + +`-mempooltxinputlimit` deprecation +---------------------------------- + +The configuration option `-mempooltxinputlimit` was added in release 1.0.10 as a +short-term fix for the quadratic hashing problem inherited from Bitcoin. At the +time, transactions with many inputs were causing performance issues for miners. +Since then, several performance improvements have been merged from the Bitcoin +Core codebase that significantly reduce these issues. + +The Overwinter network upgrade includes changes that solve the quadratic hashing +problem, and so `-mempooltxinputlimit` will no longer be needed - a transaction +with 1000 inputs will take just as long to validate as 10 transactions with 100 +inputs each. Starting from this release, `-mempooltxinputlimit` will be enforced +before the Overwinter activation height is reached, but will be ignored once +Overwinter activates. The option will be removed entirely in a future release +after Overwinter has activated. + +`NODE_BLOOM` service bit +------------------------ + +Support for the `NODE_BLOOM` service bit, as described in [BIP +111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been +added to the P2P protocol code. + +BIP 111 defines a service bit to allow peers to advertise that they support +Bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol +version to allow peers to identify old nodes which allow Bloom filtering of the +connection despite lacking the new service bit. + +In this version, it is only enforced for peers that send protocol versions +`>=170004`. For the next major version it is planned that this restriction will be +removed. It is recommended to update SPV clients to check for the `NODE_BLOOM` +service bit for nodes that report version 170004 or newer. + +Changelog +========= + +Brad Miller (2): + Clean up + Implement note locking for z_mergetoaddress + +Charlie O'Keefe (1): + Add filename and sha256 hash for windows rust package + +Daira Hopwood (5): + Squashed commit of the following: + pyflakes cleanups to RPC tests after Overwinter PRs. + Add support for Overwinter v3 transactions to mininode framework. + Test that receiving an expired transaction does not increase the peer's ban score. + Don't increase banscore if the transaction only just expired. + +Daniel Kraft (1): + trivial: use constants for db keys + +Jack Grigg (47): + Add environment variable for setting ./configure flags in zcutil/build.sh + Add configure flags for enabling ASan/UBSan and TSan + Split declaration and definition of SPROUT_BRANCH_ID constant + Add link to Overwinter info page + Notify users about auto-senescence via -alertnotify + test: Move wait_and_assert_operationid_status debug output before asserts + Don't require RELRO and BIND_NOW for Darwin + Only set multicore flags if OpenMP is available + Revert "remove -mt suffix from boost libraries built by depends" + Use correct Boost::System linker flag for libzcash + depends: Remove -mt suffix from Boost libraries + snark: Remove -mt suffix from Boost library + cleanup: Ensure code is pyflakes-clean for CI + Ignore -mempooltxinputlimit once Overwinter activates + depends: Explicitly download and vendor Rust dependencies + Make Rust compilation mandatory + Optimise serialization of MerklePath, avoiding ambiguity of std::vector + Use uint64_t instead of size_t for serialized indices into tx.vjoinsplit + Move explicit instantiation of IncrementalMerkleTree::emptyroots into header + libsnark: Don't set -static on Darwin + Set PLATFORM flag when compiling libsnark + Add base case to CurrentEpoch() + Cast ZCIncrementalMerkleTree::size() to uint64_t before passing to UniValue + rpcwallet.cpp: Cast size_t to uint64_t before passing to UniValue + wallet: Cast size_t to uint64_t before passing to UniValue + Test calling z_mergetoaddress to merge notes while a note merge is ongoing + depends: Fix regex bugs in cargo-checksum.sh + Fix z_importviewingkey startHeight parameter + Add RPC test of RewindBlockIndex + When rewinding, remove insufficiently-validated blocks + Adjust deprecation message to work in both UI and -alertnotify + Refactor Zcash changes to CCoinsViewDB + Update blockchain.py RPC test for Zcash + Update CBlockTreeDB::EraseBatchSync for dbwrapper refactor + Fix typo + test: Check return value of snprintf + test: Add missing Overwinter fields to mininode's CTransaction + Add RPC test for -enforcenodebloom + Fix NODE_BLOOM documentation errors + Move bloom filter filtering logic back into command "switch" + Update -enforcenodebloom RPC test with filterclear vs filteradd + make-release.py: Versioning changes for 1.1.0-rc1. + make-release.py: Updated manpages for 1.1.0-rc1. + make-release.py: Updated release notes and changelog for 1.1.0-rc1. + Set Overwinter protocol version to 170005 + make-release.py: Versioning changes for 1.1.0. + make-release.py: Updated manpages for 1.1.0. + +James O'Beirne (3): + Refactor leveldbwrapper + Minor bugfixes + Add tests for gettxoutsetinfo, CLevelDBBatch, CLevelDBIterator + +Jason Davies (1): + Fix typo in comment: should link to issue #1359. + +Jay Graber (1): + Set ban score for expired txs to 0 + +Jeff Garzik (3): + leveldbwrapper: Remove unused .Prev(), .SeekToLast() methods + leveldbwrapper symbol rename: Remove "Level" from class, etc. names + leveldbwrapper file rename to dbwrapper.* + +Jonathan "Duke" Leto (7): + Fix references to Bitcoin in RPC tests readme + This library seems to not be used at all and all comments mentioning it are ghosts + Update awkward wording about blocks as per @daira + Regtest mining does have a founders reward, a single address t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg + Fix outdated comment about starting balance of nodes + Return JoinSplit and JoinSplitOutput indexes in z_listreceivedbyaddress + Add tests for new JoinSplit keys returned by z_listreceivedbyaddress + +Lauda (1): + [Trivial] Grammar and typo correction + +Matt Corallo (3): + Add test for dbwrapper iterators with same-prefix keys. + Add NODE_BLOOM service bit and bump protocol version + Don't do mempool lookups for "mempool" command without a filter + +Patick Strateman (3): + Move bloom filter filtering logic outside of command "switch" (giant if/else). + Add enforcenodebloom option. + Document both the peerbloomfilters and enforcenodebloom options. + +Pavel Janík (1): + Do not shadow members in dbwrapper + +Pieter Wuille (2): + Encapsulate CLevelDB iterators cleanly + Fix chainstate serialized_size computation + +R E Broadley (1): + Allow filterclear messages for enabling TX relay only. + +Simon Liu (14): + Code clean up. Remove use of X macro. + Enable mempool logging in tx expiry QA test. + Closes #3084. Log txid when removing expired txs from mempool. + Add qa test for cache invalidation bug found in v1.0.0 to v1.0.3. + Remove local function wait_and_assert_operationid_status which is now defined in the test framework for shared usage. + Update boost to 1.66.0 + Part of #2966, extending Sprout tests to other epochs. + Update boost package URL to match official download url on boost.org + Closes #3110. Ensure user can see error message about absurdly high fees. + Closes #2910. Add z_listunspent RPC call. + Upgrade OpenSSL to 1.1.0h + Use range based for loop + Bump MIT Licence copyright header. + Fix test to check for sanitized string from alertnotify. + +Wladimir J. van der Laan (6): + dbwrapper: Pass parent CDBWrapper into CDBBatch and CDBIterator + dbwrapper: Move `HandleError` to `dbwrapper_private` + chain: Add assertion in case of missing records in index db + test: Add more thorough test for dbwrapper iterators + test: Replace remaining sprintf with snprintf + doc: update release-notes and bips.md for BIP111 + +kozyilmaz (1): + Fix test/gtest bugs caught by latest macOS clang + +rofl0r (2): + fix build error due to usage of obsolete boost_system-mt + remove -mt suffix from boost libraries built by depends + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.1-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.1.1-rc1.md new file mode 100644 index 000000000..bc209efc7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.1-rc1.md @@ -0,0 +1,286 @@ +Notable changes +=============== + +zcash-cli: arguments privacy +---------------------------- + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ src/zcash-cli -stdin walletpassphrase + mysecretcode + 120 + ^D (Ctrl-D) + +It is recommended to use this for sensitive information such as private keys, as +command-line arguments can usually be read from the process table by any user on +the system. + +Asm representations of scriptSig signatures now contain SIGHASH type decodes +---------------------------------------------------------------------------- + +The `asm` property of each scriptSig now contains the decoded signature hash +type for each signature that provides a valid defined hash type. + +The following items contain assembly representations of scriptSig signatures +and are affected by this change: + +- RPC `getrawtransaction` +- RPC `decoderawtransaction` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `zcash-tx -json` + +For example, the `scriptSig.asm` property of a transaction input that +previously showed an assembly representation of: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 + +now shows as: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] + +Note that the output of the RPC `decodescript` did not change because it is +configured specifically to process scriptPubKey and not scriptSig scripts. + +Changelog +========= + +Cory Fields (4): + serialization: teach serializers variadics + build: univalue subdir build fixups + don't throw std::bad_alloc when out of memory. Instead, terminate immediately + prevector: assert successful allocation + +Daira Hopwood (1): + Use https: for BDB backup download URL. + +David Llop (1): + Update Payment API + +Eirik Ogilvie-Wigley (7): + Clarify help text of dumpprivkey + Add sapling nullifier set + Add enum for nullifier type + Add sapling nullifiers to db and mempool + Rename nullifier caches and maps to indicate sprout nullifiers + Make sure transactions have non-empty outputs + Coinbase transactions can not have shielded spend or output + +Jack Grigg (50): + Disable building libzcashconsensus by default + depends: Upgrade Rust to 1.26.0-beta.3 + depends: Add support for unpackaged Rust crates + depends: Update to latest librustzcash with sapling-crypto dependencies + Add Sapling to upgrade list + Add static asserts to ensure CONTINUE_EXECUTION doesn't collide + [Bitcoin-Tx] Adjust util-test test cases for Zcash + Handle usage of prevector for CScript in Zcash-specific code + GetSerializeSize changes in Zcash-specific code + Remove nType and nVersion from Zcash-specific code + Adjust consensus rules to require v4 transactions from Sapling activation + Implement basic Sapling v4 transaction parser + Add Sapling v4 transactions to IsStandard + Pass transaction header into correct SignatureHash serialization level + Remove now-unshadowed serialization lines that do nothing + Implement SpendDescription and OutputDescription datastructures + Add a constant for Overwinter's transaction version + Return result of boost::apply_visitor + Improve best-effort logging before termination on OOM + Attempt to log before terminating if prevector allocation fails + Fix -Wstring-plus-int warning on clang + Update mempool_nu_activation RPC test to exercise both Overwinter and Sapling + Use CBitcoinAddress wrappers in Zcash-specific code + Change JSOutPoint constructor to have js argument be uint64_t + Update CreateNewContextualCMutableTransaction to create Sapling transactions + Expire Overwinter transactions before the Sapling activation height + Remove obsolete CreateJoinSplit and GenerateParams binaries + Add missing include guard + Raise 100kB transaction size limit from Sapling activation + Benchmark the largest valid Sapling transaction in validatelargetx + Rename MAX_TX_SIZE to MAX_TX_SIZE_AFTER_SAPLING + Rework z_sendmany z-address recipient limit + Add test of Sapling transaction size boundary + Update tests for CreateNewContextualCMutableTransaction changes + wallet: Change IsLockedNote to take a JSOutPoint + wallet: Make some arguments const that can be + Implement Sapling signature hash (ZIP 243) + Update sighash tests + Introduce wrappers around CZCPaymentAddress + Introduce wrappers around CZCSpendingKey + Introduce wrappers around CZCViewingKey + Implement {Encode,Decode}PaymentAddress etc. without CZCEncoding + Add key_io includes to Zcash-specific code + Add valueBalance to value balances, and enforce its consensus rules + Track net value entering and exiting the Sapling circuit + Add contextual comment for GetValueOut() and GetShieldedValueIn() + Use boost::variant to represent shielded addresses and keys + Correctly serialize Groth16 JSDescription for verifyjoinsplit benchmark + make-release.py: Versioning changes for 1.1.1-rc1. + make-release.py: Updated manpages for 1.1.1-rc1. + +Jay Graber (1): + Add test for dependent txs to mempool_tx_expiry.py + +Jeremy Rubin (1): + Fix subscript[0] in base58.cpp + +Jonas Schnelli (4): + [RPC] createrawtransaction: add option to set the sequence number per input + [bitcoin-tx] allow to set nSequence number over the in= command + [Bitcoin-Tx] Add tests for sequence number support + add bip32 pubkey serialization + +João Barbosa (1): + Remove unused GetKeyID and IsScript methods from CBitcoinAddress + +Karl-Johan Alm (1): + Removed using namespace std from bitcoin-cli/-tx and added std:: in appropriate places. + +Kaz Wesley (1): + CBase58Data::SetString: cleanse the full vector + +Larry Ruane (1): + fix qa/zcash/full_test_suite.py pathname + +MarcoFalke (3): + [uacomment] Sanitize per BIP-0014 + [rpcwallet] Don't use floating point + [test] Remove unused code + +Matt Corallo (1): + Add COMPACTSIZE wrapper similar to VARINT for serialization + +Pavel Janík (1): + [WIP] Remove unused statement in serialization + +Pavol Rusnak (2): + implement uacomment config parameter which can add comments to user agent as per BIP-0014 + limit total length of user agent comments + +Pedro Branco (1): + Prevent multiple calls to ExtractDestination + +Per Grön (1): + Make some globals static that can be + +Peter Pratscher (1): + Backported Bitcoin PR #8704 to optionally return full tx details in the getblock rpc call + +Pieter Wuille (22): + Prevector type + Remove unused ReadVersion and WriteVersion + Make streams' read and write return void + Make nType and nVersion private and sometimes const + Make GetSerializeSize a wrapper on top of CSizeComputer + Get rid of nType and nVersion + Avoid -Wshadow errors + Make CSerAction's ForRead() constexpr + Add optimized CSizeComputer serializers + Use fixed preallocation instead of costly GetSerializeSize + Add serialization for unique_ptr and shared_ptr + Add deserializing constructors to CTransaction and CMutableTransaction + Avoid unaligned access in crypto i/o + Fix some empty vector references + Introduce wrappers around CBitcoinAddress + Move CBitcoinAddress to base58.cpp + Implement {Encode,Decode}Destination without CBitcoinAddress + Import Bech32 C++ reference code & tests + Convert base58_tests from type/payload to scriptPubKey comparison + Replace CBitcoinSecret with {Encode,Decode}Secret + Stop using CBase58Data for ext keys + Split key_io (address/key encodings) off from base58 + +Puru (1): + bitcoin-cli.cpp: Use symbolic constant for exit code + +Sean Bowe (49): + Switch to latest librustzcash + Invoke the merkle_hash API in librustzcash via test suite. + Link with -ldl + Update librustzcash hash + Load Sapling testnet parameters into memory. + Update librustzcash hash + Check that duplicate Sapling nullifiers don't exist within a transaction. + Abstract `uncommitted` and depth personalization for IncrementalMerkleTree. + Add implementation of Sapling merkle tree + Add regression tests and test vectors for Sapling merkle tree + Rename NullifierType to ShieldedType. + Specifically describe anchors as Sprout anchors. + Rename hashAnchor to hashSproutAnchor. + Rename hashReserved to hashSaplingAnchorEnd. + Add primitive implementation of GetSaplingAnchorEnd. + Rename DB_ANCHOR to DB_SPROUT_ANCHOR. + Rename GetAnchorAt to GetSproutAnchorAt. + Rename PushAnchor to PushSproutAnchor. + Introduce support for GetBestAnchor(SAPLING). + Generalize the PopAnchor implementation behavior. + Generalize the PushAnchor implementation behavior. + Remove underscores from gtest test names. + Rename hashSaplingAnchorEnd to hashFinalSaplingRoot to match spec. + Rename hashSproutAnchorEnd to hashFinalSproutRoot to be consistent. + Add support for Sapling anchors in coins/txdb. + Add support for PopAnchor(.., SPROUT/SAPLING) + Add `PushSaplingAnchor` + Add consensus support for Sapling merkle trees. + Add support for Sapling anchor checks in mempool consistency checks. + Calculate the correct hashFinalSaplingRoot in the miner. + Adjust tests to handle Sapling anchor cache + Evict transactions with obsolete anchors from the mempool + Fix outdated comment + Fix broken error messages. + Fix miner tests + Update sapling-crypto and librustzcash + Swap bit endianness of test vectors + Remove unnecessary IsCoinbase() check. Coinbases are guaranteed to have empty vjoinsplit. + Refactor so that dataToBeSigned can be used later in the function for other purposes. + Update to latest librustzcash + Check Sapling Spend/Output proofs and signatures. + Integrate Groth16 verification and proving. + Update librustzcash again + Adjust tests and benchmarks + Switch Rust to 1.26 Stable. + Update librustzcash + Update Sapling testnet parameters + Update merkle tree and pedersen hash tests to account for new encoding + Change txdb prefixes for sapling and avoid writing unnecessary information. + +Simon Liu (14): + Part of #2966, extending Sprout tests to other epochs. + Closes #3134 - Least Authority Issue E + Refactoring: libzcash::Note is now a subclass of libzcash::BaseNote. + Refactoring: Rename class libzcash::Note to libzcash::SproutNote. + Refactoring: SproutNote member variable value moved to BaseNote. + Add virtual destructor to SproutNote and BaseNote + Remove unused SproutNote variables. + Refactoring: rename NotePlaintext --> SproutNotePlaintext + Create class hierarchy for SproutNotePlaintext. + Move memo member varible from SproutNotePlaintext to BaseNotePlaintext. + Tweaks to d0a1d83 to complete backport of Bitcoin PR #8704 + Closes #3178 by adding verbosity level improvements to getblock RPC. + Fix undefined behaviour, calling memcpy with NULL pointer. + Closes #3250. Memo getter should return by reference, not by value. + +Tom Harding (1): + Add optional locktime to createrawtransaction + +UdjinM6 (2): + Fix exit codes: + Every main()/exit() should return/use one of EXIT_ codes instead of magic numbers + +Wladimir J. van der Laan (2): + rpc: Input-from-stdin mode for bitcoin-cli + doc: mention bitcoin-cli -stdin in release notes + +ca333 (2): + [fix] proton download path + update proton.mk + +kozyilmaz (2): + [macOS] added curl method for param download + [macOS] use shlock instead of flock in fetch-params + +mruddy (1): + Resolve issue bitcoin/bitcoin#3166. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.1-rc2.md b/depend/zcash/doc/release-notes/release-notes-1.1.1-rc2.md new file mode 100644 index 000000000..5d10ede47 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.1-rc2.md @@ -0,0 +1,290 @@ +Notable changes +=============== + +zcash-cli: arguments privacy +---------------------------- + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ src/zcash-cli -stdin walletpassphrase + mysecretcode + 120 + ^D (Ctrl-D) + +It is recommended to use this for sensitive information such as private keys, as +command-line arguments can usually be read from the process table by any user on +the system. + +Asm representations of scriptSig signatures now contain SIGHASH type decodes +---------------------------------------------------------------------------- + +The `asm` property of each scriptSig now contains the decoded signature hash +type for each signature that provides a valid defined hash type. + +The following items contain assembly representations of scriptSig signatures +and are affected by this change: + +- RPC `getrawtransaction` +- RPC `decoderawtransaction` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `zcash-tx -json` + +For example, the `scriptSig.asm` property of a transaction input that +previously showed an assembly representation of: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 + +now shows as: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] + +Note that the output of the RPC `decodescript` did not change because it is +configured specifically to process scriptPubKey and not scriptSig scripts. + +Changelog +========= + +Cory Fields (4): + serialization: teach serializers variadics + build: univalue subdir build fixups + don't throw std::bad_alloc when out of memory. Instead, terminate immediately + prevector: assert successful allocation + +Daira Hopwood (1): + Use https: for BDB backup download URL. + +David Llop (1): + Update Payment API + +Eirik Ogilvie-Wigley (7): + Clarify help text of dumpprivkey + Add sapling nullifier set + Add enum for nullifier type + Add sapling nullifiers to db and mempool + Rename nullifier caches and maps to indicate sprout nullifiers + Make sure transactions have non-empty outputs + Coinbase transactions can not have shielded spend or output + +Jack Grigg (52): + Disable building libzcashconsensus by default + depends: Upgrade Rust to 1.26.0-beta.3 + depends: Add support for unpackaged Rust crates + depends: Update to latest librustzcash with sapling-crypto dependencies + Add Sapling to upgrade list + Add static asserts to ensure CONTINUE_EXECUTION doesn't collide + [Bitcoin-Tx] Adjust util-test test cases for Zcash + Handle usage of prevector for CScript in Zcash-specific code + GetSerializeSize changes in Zcash-specific code + Remove nType and nVersion from Zcash-specific code + Adjust consensus rules to require v4 transactions from Sapling activation + Implement basic Sapling v4 transaction parser + Add Sapling v4 transactions to IsStandard + Pass transaction header into correct SignatureHash serialization level + Remove now-unshadowed serialization lines that do nothing + Implement SpendDescription and OutputDescription datastructures + Add a constant for Overwinter's transaction version + Return result of boost::apply_visitor + Improve best-effort logging before termination on OOM + Attempt to log before terminating if prevector allocation fails + Fix -Wstring-plus-int warning on clang + Update mempool_nu_activation RPC test to exercise both Overwinter and Sapling + Use CBitcoinAddress wrappers in Zcash-specific code + Change JSOutPoint constructor to have js argument be uint64_t + Update CreateNewContextualCMutableTransaction to create Sapling transactions + Expire Overwinter transactions before the Sapling activation height + Remove obsolete CreateJoinSplit and GenerateParams binaries + Add missing include guard + Raise 100kB transaction size limit from Sapling activation + Benchmark the largest valid Sapling transaction in validatelargetx + Rename MAX_TX_SIZE to MAX_TX_SIZE_AFTER_SAPLING + Rework z_sendmany z-address recipient limit + Add test of Sapling transaction size boundary + Update tests for CreateNewContextualCMutableTransaction changes + wallet: Change IsLockedNote to take a JSOutPoint + wallet: Make some arguments const that can be + Implement Sapling signature hash (ZIP 243) + Update sighash tests + Introduce wrappers around CZCPaymentAddress + Introduce wrappers around CZCSpendingKey + Introduce wrappers around CZCViewingKey + Implement {Encode,Decode}PaymentAddress etc. without CZCEncoding + Add key_io includes to Zcash-specific code + Add valueBalance to value balances, and enforce its consensus rules + Track net value entering and exiting the Sapling circuit + Add contextual comment for GetValueOut() and GetShieldedValueIn() + Use boost::variant to represent shielded addresses and keys + Correctly serialize Groth16 JSDescription for verifyjoinsplit benchmark + make-release.py: Versioning changes for 1.1.1-rc1. + make-release.py: Updated manpages for 1.1.1-rc1. + make-release.py: Updated release notes and changelog for 1.1.1-rc1. + Comment out Gitian library handling while we don't build any libraries + +Jay Graber (1): + Add test for dependent txs to mempool_tx_expiry.py + +Jeremy Rubin (1): + Fix subscript[0] in base58.cpp + +Jonas Schnelli (4): + [RPC] createrawtransaction: add option to set the sequence number per input + [bitcoin-tx] allow to set nSequence number over the in= command + [Bitcoin-Tx] Add tests for sequence number support + add bip32 pubkey serialization + +João Barbosa (1): + Remove unused GetKeyID and IsScript methods from CBitcoinAddress + +Karl-Johan Alm (1): + Removed using namespace std from bitcoin-cli/-tx and added std:: in appropriate places. + +Kaz Wesley (1): + CBase58Data::SetString: cleanse the full vector + +Larry Ruane (1): + fix qa/zcash/full_test_suite.py pathname + +MarcoFalke (3): + [uacomment] Sanitize per BIP-0014 + [rpcwallet] Don't use floating point + [test] Remove unused code + +Matt Corallo (1): + Add COMPACTSIZE wrapper similar to VARINT for serialization + +Pavel Janík (1): + [WIP] Remove unused statement in serialization + +Pavol Rusnak (2): + implement uacomment config parameter which can add comments to user agent as per BIP-0014 + limit total length of user agent comments + +Pedro Branco (1): + Prevent multiple calls to ExtractDestination + +Per Grön (1): + Make some globals static that can be + +Peter Pratscher (1): + Backported Bitcoin PR #8704 to optionally return full tx details in the getblock rpc call + +Pieter Wuille (22): + Prevector type + Remove unused ReadVersion and WriteVersion + Make streams' read and write return void + Make nType and nVersion private and sometimes const + Make GetSerializeSize a wrapper on top of CSizeComputer + Get rid of nType and nVersion + Avoid -Wshadow errors + Make CSerAction's ForRead() constexpr + Add optimized CSizeComputer serializers + Use fixed preallocation instead of costly GetSerializeSize + Add serialization for unique_ptr and shared_ptr + Add deserializing constructors to CTransaction and CMutableTransaction + Avoid unaligned access in crypto i/o + Fix some empty vector references + Introduce wrappers around CBitcoinAddress + Move CBitcoinAddress to base58.cpp + Implement {Encode,Decode}Destination without CBitcoinAddress + Import Bech32 C++ reference code & tests + Convert base58_tests from type/payload to scriptPubKey comparison + Replace CBitcoinSecret with {Encode,Decode}Secret + Stop using CBase58Data for ext keys + Split key_io (address/key encodings) off from base58 + +Puru (1): + bitcoin-cli.cpp: Use symbolic constant for exit code + +Sean Bowe (49): + Switch to latest librustzcash + Invoke the merkle_hash API in librustzcash via test suite. + Link with -ldl + Update librustzcash hash + Load Sapling testnet parameters into memory. + Update librustzcash hash + Check that duplicate Sapling nullifiers don't exist within a transaction. + Abstract `uncommitted` and depth personalization for IncrementalMerkleTree. + Add implementation of Sapling merkle tree + Add regression tests and test vectors for Sapling merkle tree + Rename NullifierType to ShieldedType. + Specifically describe anchors as Sprout anchors. + Rename hashAnchor to hashSproutAnchor. + Rename hashReserved to hashSaplingAnchorEnd. + Add primitive implementation of GetSaplingAnchorEnd. + Rename DB_ANCHOR to DB_SPROUT_ANCHOR. + Rename GetAnchorAt to GetSproutAnchorAt. + Rename PushAnchor to PushSproutAnchor. + Introduce support for GetBestAnchor(SAPLING). + Generalize the PopAnchor implementation behavior. + Generalize the PushAnchor implementation behavior. + Remove underscores from gtest test names. + Rename hashSaplingAnchorEnd to hashFinalSaplingRoot to match spec. + Rename hashSproutAnchorEnd to hashFinalSproutRoot to be consistent. + Add support for Sapling anchors in coins/txdb. + Add support for PopAnchor(.., SPROUT/SAPLING) + Add `PushSaplingAnchor` + Add consensus support for Sapling merkle trees. + Add support for Sapling anchor checks in mempool consistency checks. + Calculate the correct hashFinalSaplingRoot in the miner. + Adjust tests to handle Sapling anchor cache + Evict transactions with obsolete anchors from the mempool + Fix outdated comment + Fix broken error messages. + Fix miner tests + Update sapling-crypto and librustzcash + Swap bit endianness of test vectors + Remove unnecessary IsCoinbase() check. Coinbases are guaranteed to have empty vjoinsplit. + Refactor so that dataToBeSigned can be used later in the function for other purposes. + Update to latest librustzcash + Check Sapling Spend/Output proofs and signatures. + Integrate Groth16 verification and proving. + Update librustzcash again + Adjust tests and benchmarks + Switch Rust to 1.26 Stable. + Update librustzcash + Update Sapling testnet parameters + Update merkle tree and pedersen hash tests to account for new encoding + Change txdb prefixes for sapling and avoid writing unnecessary information. + +Simon Liu (16): + Part of #2966, extending Sprout tests to other epochs. + Closes #3134 - Least Authority Issue E + Refactoring: libzcash::Note is now a subclass of libzcash::BaseNote. + Refactoring: Rename class libzcash::Note to libzcash::SproutNote. + Refactoring: SproutNote member variable value moved to BaseNote. + Add virtual destructor to SproutNote and BaseNote + Remove unused SproutNote variables. + Refactoring: rename NotePlaintext --> SproutNotePlaintext + Create class hierarchy for SproutNotePlaintext. + Move memo member varible from SproutNotePlaintext to BaseNotePlaintext. + Tweaks to d0a1d83 to complete backport of Bitcoin PR #8704 + Closes #3178 by adding verbosity level improvements to getblock RPC. + Fix undefined behaviour, calling memcpy with NULL pointer. + Closes #3250. Memo getter should return by reference, not by value. + make-release.py: Versioning changes for 1.1.1-rc2. + make-release.py: Updated manpages for 1.1.1-rc2. + +Tom Harding (1): + Add optional locktime to createrawtransaction + +UdjinM6 (2): + Fix exit codes: + Every main()/exit() should return/use one of EXIT_ codes instead of magic numbers + +Wladimir J. van der Laan (2): + rpc: Input-from-stdin mode for bitcoin-cli + doc: mention bitcoin-cli -stdin in release notes + +ca333 (2): + [fix] proton download path + update proton.mk + +kozyilmaz (2): + [macOS] added curl method for param download + [macOS] use shlock instead of flock in fetch-params + +mruddy (1): + Resolve issue bitcoin/bitcoin#3166. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.1.md b/depend/zcash/doc/release-notes/release-notes-1.1.1.md new file mode 100644 index 000000000..90adec943 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.1.md @@ -0,0 +1,336 @@ +Notable changes +=============== + +Sapling network upgrade +----------------------- + +The consensus code preparations for the Sapling network upgrade, as described +in [ZIP 243](https://github.com/zcash/zips/blob/master/zip-0243.rst) and the +[Sapling spec](https://github.com/zcash/zips/blob/master/protocol/sapling.pdf) +are finished and included in this release. Sapling support in the wallet and +RPC is ongoing, and is expected to land in master over the next few weeks. + +The [Sapling MPC](https://blog.z.cash/announcing-the-sapling-mpc/) is currently +working on producing the final Sapling parameters. In the meantime, Sapling will +activate on testnet with dummy Sapling parameters at height 252500. This +activation will be temporary, and the testnet will be rolled back by version +2.0.0 so that both mainnet and testnet will be using the same parameters. +Users who want to continue testing Overwinter should continue to run version +1.1.0 on testnet, and then upgrade to 2.0.0 (which will be released after +Overwinter activates). + +Sapling can also be activated at a specific height in regtest mode by +setting the config options `-nuparams=5ba81b19:HEIGHT -nuparams=76b809bb:HEIGHT`. +These config options will change when the testnet is rolled back for 2.0.0 +(because the branch ID for Sapling will change, due to us following the safe +upgrade conventions we introduced in Overwinter). + +Users running testnet or regtest nodes will need to run +`./zcutil/fetch-params.sh --testnet` (for users building from source) or +`zcash-fetch-params --testnet` (for binary / Debian users). + +As a reminder, because the Sapling activation height is not yet specified for +mainnet, version 1.1.1 will behave similarly as other pre-Sapling releases even +after a future activation of Sapling on the network. Upgrading from 1.1.1 will +be required in order to follow the Sapling network upgrade on mainnet. + +Sapling transaction format +-------------------------- + +Once Sapling has activated, transactions must use the new v4 format (including +coinbase transactions). All RPC methods that create new transactions (such as +`createrawtransaction` and `getblocktemplate`) will create v4 transactions once +the Sapling activation height has been reached. + +zcash-cli: arguments privacy +---------------------------- + +The RPC command line client gained a new argument, `-stdin` +to read extra arguments from standard input, one per line until EOF/Ctrl-D. +For example: + + $ src/zcash-cli -stdin walletpassphrase + mysecretcode + 120 + ^D (Ctrl-D) + +It is recommended to use this for sensitive information such as private keys, as +command-line arguments can usually be read from the process table by any user on +the system. + +Asm representations of scriptSig signatures now contain SIGHASH type decodes +---------------------------------------------------------------------------- + +The `asm` property of each scriptSig now contains the decoded signature hash +type for each signature that provides a valid defined hash type. + +The following items contain assembly representations of scriptSig signatures +and are affected by this change: + +- RPC `getrawtransaction` +- RPC `decoderawtransaction` +- REST `/rest/tx/` (JSON format) +- REST `/rest/block/` (JSON format when including extended tx details) +- `zcash-tx -json` + +For example, the `scriptSig.asm` property of a transaction input that +previously showed an assembly representation of: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 + +now shows as: + + 304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] + +Note that the output of the RPC `decodescript` did not change because it is +configured specifically to process scriptPubKey and not scriptSig scripts. + +Changelog +========= + +Cory Fields (4): + serialization: teach serializers variadics + build: univalue subdir build fixups + don't throw std::bad_alloc when out of memory. Instead, terminate immediately + prevector: assert successful allocation + +Daira Hopwood (1): + Use https: for BDB backup download URL. + +David Llop (1): + Update Payment API + +Eirik Ogilvie-Wigley (7): + Clarify help text of dumpprivkey + Add sapling nullifier set + Add enum for nullifier type + Add sapling nullifiers to db and mempool + Rename nullifier caches and maps to indicate sprout nullifiers + Make sure transactions have non-empty outputs + Coinbase transactions can not have shielded spend or output + +Jack Grigg (55): + Disable building libzcashconsensus by default + depends: Upgrade Rust to 1.26.0-beta.3 + depends: Add support for unpackaged Rust crates + depends: Update to latest librustzcash with sapling-crypto dependencies + Add Sapling to upgrade list + Add static asserts to ensure CONTINUE_EXECUTION doesn't collide + [Bitcoin-Tx] Adjust util-test test cases for Zcash + Handle usage of prevector for CScript in Zcash-specific code + GetSerializeSize changes in Zcash-specific code + Remove nType and nVersion from Zcash-specific code + Adjust consensus rules to require v4 transactions from Sapling activation + Implement basic Sapling v4 transaction parser + Add Sapling v4 transactions to IsStandard + Pass transaction header into correct SignatureHash serialization level + Remove now-unshadowed serialization lines that do nothing + Implement SpendDescription and OutputDescription datastructures + Add a constant for Overwinter's transaction version + Return result of boost::apply_visitor + Improve best-effort logging before termination on OOM + Attempt to log before terminating if prevector allocation fails + Fix -Wstring-plus-int warning on clang + Update mempool_nu_activation RPC test to exercise both Overwinter and Sapling + Use CBitcoinAddress wrappers in Zcash-specific code + Change JSOutPoint constructor to have js argument be uint64_t + Update CreateNewContextualCMutableTransaction to create Sapling transactions + Expire Overwinter transactions before the Sapling activation height + Remove obsolete CreateJoinSplit and GenerateParams binaries + Add missing include guard + Raise 100kB transaction size limit from Sapling activation + Benchmark the largest valid Sapling transaction in validatelargetx + Rename MAX_TX_SIZE to MAX_TX_SIZE_AFTER_SAPLING + Rework z_sendmany z-address recipient limit + Add test of Sapling transaction size boundary + Update tests for CreateNewContextualCMutableTransaction changes + wallet: Change IsLockedNote to take a JSOutPoint + wallet: Make some arguments const that can be + Implement Sapling signature hash (ZIP 243) + Update sighash tests + Introduce wrappers around CZCPaymentAddress + Introduce wrappers around CZCSpendingKey + Introduce wrappers around CZCViewingKey + Implement {Encode,Decode}PaymentAddress etc. without CZCEncoding + Add key_io includes to Zcash-specific code + Add valueBalance to value balances, and enforce its consensus rules + Track net value entering and exiting the Sapling circuit + Add contextual comment for GetValueOut() and GetShieldedValueIn() + Use boost::variant to represent shielded addresses and keys + Correctly serialize Groth16 JSDescription for verifyjoinsplit benchmark + make-release.py: Versioning changes for 1.1.1-rc1. + make-release.py: Updated manpages for 1.1.1-rc1. + make-release.py: Updated release notes and changelog for 1.1.1-rc1. + Comment out Gitian library handling while we don't build any libraries + Add Sapling details to release notes + make-release.py: Versioning changes for 1.1.1. + make-release.py: Updated manpages for 1.1.1. + +Jay Graber (1): + Add test for dependent txs to mempool_tx_expiry.py + +Jeremy Rubin (1): + Fix subscript[0] in base58.cpp + +Jonas Schnelli (4): + [RPC] createrawtransaction: add option to set the sequence number per input + [bitcoin-tx] allow to set nSequence number over the in= command + [Bitcoin-Tx] Add tests for sequence number support + add bip32 pubkey serialization + +João Barbosa (1): + Remove unused GetKeyID and IsScript methods from CBitcoinAddress + +Karl-Johan Alm (1): + Removed using namespace std from bitcoin-cli/-tx and added std:: in appropriate places. + +Kaz Wesley (1): + CBase58Data::SetString: cleanse the full vector + +Larry Ruane (1): + fix qa/zcash/full_test_suite.py pathname + +MarcoFalke (3): + [uacomment] Sanitize per BIP-0014 + [rpcwallet] Don't use floating point + [test] Remove unused code + +Matt Corallo (1): + Add COMPACTSIZE wrapper similar to VARINT for serialization + +Pavel Janík (1): + [WIP] Remove unused statement in serialization + +Pavol Rusnak (2): + implement uacomment config parameter which can add comments to user agent as per BIP-0014 + limit total length of user agent comments + +Pedro Branco (1): + Prevent multiple calls to ExtractDestination + +Per Grön (1): + Make some globals static that can be + +Peter Pratscher (1): + Backported Bitcoin PR #8704 to optionally return full tx details in the getblock rpc call + +Pieter Wuille (22): + Prevector type + Remove unused ReadVersion and WriteVersion + Make streams' read and write return void + Make nType and nVersion private and sometimes const + Make GetSerializeSize a wrapper on top of CSizeComputer + Get rid of nType and nVersion + Avoid -Wshadow errors + Make CSerAction's ForRead() constexpr + Add optimized CSizeComputer serializers + Use fixed preallocation instead of costly GetSerializeSize + Add serialization for unique_ptr and shared_ptr + Add deserializing constructors to CTransaction and CMutableTransaction + Avoid unaligned access in crypto i/o + Fix some empty vector references + Introduce wrappers around CBitcoinAddress + Move CBitcoinAddress to base58.cpp + Implement {Encode,Decode}Destination without CBitcoinAddress + Import Bech32 C++ reference code & tests + Convert base58_tests from type/payload to scriptPubKey comparison + Replace CBitcoinSecret with {Encode,Decode}Secret + Stop using CBase58Data for ext keys + Split key_io (address/key encodings) off from base58 + +Puru (1): + bitcoin-cli.cpp: Use symbolic constant for exit code + +Sean Bowe (49): + Switch to latest librustzcash + Invoke the merkle_hash API in librustzcash via test suite. + Link with -ldl + Update librustzcash hash + Load Sapling testnet parameters into memory. + Update librustzcash hash + Check that duplicate Sapling nullifiers don't exist within a transaction. + Abstract `uncommitted` and depth personalization for IncrementalMerkleTree. + Add implementation of Sapling merkle tree + Add regression tests and test vectors for Sapling merkle tree + Rename NullifierType to ShieldedType. + Specifically describe anchors as Sprout anchors. + Rename hashAnchor to hashSproutAnchor. + Rename hashReserved to hashSaplingAnchorEnd. + Add primitive implementation of GetSaplingAnchorEnd. + Rename DB_ANCHOR to DB_SPROUT_ANCHOR. + Rename GetAnchorAt to GetSproutAnchorAt. + Rename PushAnchor to PushSproutAnchor. + Introduce support for GetBestAnchor(SAPLING). + Generalize the PopAnchor implementation behavior. + Generalize the PushAnchor implementation behavior. + Remove underscores from gtest test names. + Rename hashSaplingAnchorEnd to hashFinalSaplingRoot to match spec. + Rename hashSproutAnchorEnd to hashFinalSproutRoot to be consistent. + Add support for Sapling anchors in coins/txdb. + Add support for PopAnchor(.., SPROUT/SAPLING) + Add `PushSaplingAnchor` + Add consensus support for Sapling merkle trees. + Add support for Sapling anchor checks in mempool consistency checks. + Calculate the correct hashFinalSaplingRoot in the miner. + Adjust tests to handle Sapling anchor cache + Evict transactions with obsolete anchors from the mempool + Fix outdated comment + Fix broken error messages. + Fix miner tests + Update sapling-crypto and librustzcash + Swap bit endianness of test vectors + Remove unnecessary IsCoinbase() check. Coinbases are guaranteed to have empty vjoinsplit. + Refactor so that dataToBeSigned can be used later in the function for other purposes. + Update to latest librustzcash + Check Sapling Spend/Output proofs and signatures. + Integrate Groth16 verification and proving. + Update librustzcash again + Adjust tests and benchmarks + Switch Rust to 1.26 Stable. + Update librustzcash + Update Sapling testnet parameters + Update merkle tree and pedersen hash tests to account for new encoding + Change txdb prefixes for sapling and avoid writing unnecessary information. + +Simon Liu (18): + Part of #2966, extending Sprout tests to other epochs. + Closes #3134 - Least Authority Issue E + Refactoring: libzcash::Note is now a subclass of libzcash::BaseNote. + Refactoring: Rename class libzcash::Note to libzcash::SproutNote. + Refactoring: SproutNote member variable value moved to BaseNote. + Add virtual destructor to SproutNote and BaseNote + Remove unused SproutNote variables. + Refactoring: rename NotePlaintext --> SproutNotePlaintext + Create class hierarchy for SproutNotePlaintext. + Move memo member varible from SproutNotePlaintext to BaseNotePlaintext. + Tweaks to d0a1d83 to complete backport of Bitcoin PR #8704 + Closes #3178 by adding verbosity level improvements to getblock RPC. + Fix undefined behaviour, calling memcpy with NULL pointer. + Closes #3250. Memo getter should return by reference, not by value. + make-release.py: Versioning changes for 1.1.1-rc2. + make-release.py: Updated manpages for 1.1.1-rc2. + make-release.py: Updated release notes and changelog for 1.1.1-rc2. + Closes #3301. Non-void function should not have empty definition. + +Tom Harding (1): + Add optional locktime to createrawtransaction + +UdjinM6 (2): + Fix exit codes: + Every main()/exit() should return/use one of EXIT_ codes instead of magic numbers + +Wladimir J. van der Laan (2): + rpc: Input-from-stdin mode for bitcoin-cli + doc: mention bitcoin-cli -stdin in release notes + +ca333 (2): + [fix] proton download path + update proton.mk + +kozyilmaz (2): + [macOS] added curl method for param download + [macOS] use shlock instead of flock in fetch-params + +mruddy (1): + Resolve issue bitcoin/bitcoin#3166. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.2-rc1.md b/depend/zcash/doc/release-notes/release-notes-1.1.2-rc1.md new file mode 100644 index 000000000..91fdafd5a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.2-rc1.md @@ -0,0 +1,96 @@ +Notable changes +=============== + +`-disabledeprecation` removal +----------------------------- + +In release 1.0.9 we implemented automatic deprecation of `zcashd` software +versions made by the Zcash Company. The configuration option +`-disabledeprecation` was added as a way for users to specifically choose to +stay on a particular software version. However, it incorrectly implied that +deprecated releases would still be supported. + +This release removes the `-disabledeprecation` option, so that `zcashd` software +versions made by the Zcash Company will always shut down in accordance with the +defined deprecation policy (currently 16 weeks after release). Users who wish to +use a different policy must now specifically choose to either: + +- edit and compile the source code themselves, or +- obtain a software version from someone else who has done so (and obtain + support from them). + +Either way, it is much clearer that the software they are running is not +supported by the Zcash Company. + +Changelog +========= + +Ariel Gabizon (1): + Improve/Fix variable names + +Daira Hopwood (1): + Update code_of_conduct.md + +Eirik Ogilvie-Wigley (5): + Add tests for sapling anchors + Add hashFinalSaplingRoot to getblocktemplate + Fix parsing parameters in getnetworksolps + Add BOOST_TEST_CONTEXT to distinguish sprout v. sapling + Rename typename + +Jack Grigg (16): + Replace boost::array with std::array + Add MacOS support to no-dot-so test + Whitespace cleanup + chainparams: Add Sapling Bech32 HRPs + ConvertBits() - convert from one power-of-2 number base to another. + Fix bech32::Encode() error handling + Implement encoding and decoding of Sapling keys and addresses + Add Mach-O 64-bit detection to security-check.py + Fix cached_witnesses_empty_chain test failure on MacOS + Skip ELF-only sec-hard checks on non-ELF binaries + Remove config option -disabledeprecation + Add release notes for -disabledeprecation removal + Add comment about size calculations for converted serialized keys + Add examples of ConvertBits transformation + Use CChainParams::Bech32HRP() in zs_address_test + Add hashFinalSaplingRoot to getblockheader and getblock output + +Jay Graber (8): + Add Sapling key classes to wallet, with new librustzcash APIs + Change librustzcash dependency hash to work for new Sapling classes + Update librustzcash dependency, address comments + Minimal sapling key test + Fix default_address() + s/SaplingInViewingKey/SaplingIncomingViewingKey + Make diversifier functions return option + Add json test vectors for Sapling key components. + +Jonathan "Duke" Leto (1): + Clarify help that signmessage only works on taddrs + +Larry Ruane (1): + (rpc-test) accurately account for fee without rounding error + +Matthew King (2): + Use portable #! in python scripts (/usr/bin/env) + Favour python over python2 as per PR #7723 + +Paige Peterson (1): + include note about volunteers in CoC + +Pieter Wuille (2): + Generalize ConvertBits + Simplify Base32 and Base64 conversions + +Simon Liu (9): + Part of #3277. Add comment about deprecated txdb prefixes. + Remove now redundant Rust call to librustzcash_xor. + Add SaplingNote class and test_sapling_note unit test. + Refactor and replace factory method random() with constructor. + Return optional for Sapling commitments and nullifiers. + Closes #3328. Send alert to put non-Overwinter nodes into safe mode. + Fix pyflakes error in test zkey_import_export. + make-release.py: Versioning changes for 1.1.2-rc1. + make-release.py: Updated manpages for 1.1.2-rc1. + diff --git a/depend/zcash/doc/release-notes/release-notes-1.1.2.md b/depend/zcash/doc/release-notes/release-notes-1.1.2.md new file mode 100644 index 000000000..9041c1bb2 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-1.1.2.md @@ -0,0 +1,99 @@ +Notable changes +=============== + +`-disabledeprecation` removal +----------------------------- + +In release 1.0.9 we implemented automatic deprecation of `zcashd` software +versions made by the Zcash Company. The configuration option +`-disabledeprecation` was added as a way for users to specifically choose to +stay on a particular software version. However, it incorrectly implied that +deprecated releases would still be supported. + +This release removes the `-disabledeprecation` option, so that `zcashd` software +versions made by the Zcash Company will always shut down in accordance with the +defined deprecation policy (currently 16 weeks after release). Users who wish to +use a different policy must now specifically choose to either: + +- edit and compile the source code themselves, or +- obtain a software version from someone else who has done so (and obtain + support from them). + +Either way, it is much clearer that the software they are running is not +supported by the Zcash Company. + +Changelog +========= + +Ariel Gabizon (1): + Improve/Fix variable names + +Daira Hopwood (1): + Update code_of_conduct.md + +Eirik Ogilvie-Wigley (5): + Add tests for sapling anchors + Add hashFinalSaplingRoot to getblocktemplate + Fix parsing parameters in getnetworksolps + Add BOOST_TEST_CONTEXT to distinguish sprout v. sapling + Rename typename + +Jack Grigg (16): + Replace boost::array with std::array + Add MacOS support to no-dot-so test + Whitespace cleanup + chainparams: Add Sapling Bech32 HRPs + ConvertBits() - convert from one power-of-2 number base to another. + Fix bech32::Encode() error handling + Implement encoding and decoding of Sapling keys and addresses + Add Mach-O 64-bit detection to security-check.py + Fix cached_witnesses_empty_chain test failure on MacOS + Skip ELF-only sec-hard checks on non-ELF binaries + Remove config option -disabledeprecation + Add release notes for -disabledeprecation removal + Add comment about size calculations for converted serialized keys + Add examples of ConvertBits transformation + Use CChainParams::Bech32HRP() in zs_address_test + Add hashFinalSaplingRoot to getblockheader and getblock output + +Jay Graber (8): + Add Sapling key classes to wallet, with new librustzcash APIs + Change librustzcash dependency hash to work for new Sapling classes + Update librustzcash dependency, address comments + Minimal sapling key test + Fix default_address() + s/SaplingInViewingKey/SaplingIncomingViewingKey + Make diversifier functions return option + Add json test vectors for Sapling key components. + +Jonathan "Duke" Leto (1): + Clarify help that signmessage only works on taddrs + +Larry Ruane (1): + (rpc-test) accurately account for fee without rounding error + +Matthew King (2): + Use portable #! in python scripts (/usr/bin/env) + Favour python over python2 as per PR #7723 + +Paige Peterson (1): + include note about volunteers in CoC + +Pieter Wuille (2): + Generalize ConvertBits + Simplify Base32 and Base64 conversions + +Simon Liu (12): + Part of #3277. Add comment about deprecated txdb prefixes. + Remove now redundant Rust call to librustzcash_xor. + Add SaplingNote class and test_sapling_note unit test. + Refactor and replace factory method random() with constructor. + Return optional for Sapling commitments and nullifiers. + Closes #3328. Send alert to put non-Overwinter nodes into safe mode. + Fix pyflakes error in test zkey_import_export. + make-release.py: Versioning changes for 1.1.2-rc1. + make-release.py: Updated manpages for 1.1.2-rc1. + make-release.py: Updated release notes and changelog for 1.1.2-rc1. + make-release.py: Versioning changes for 1.1.2. + make-release.py: Updated manpages for 1.1.2. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.0-rc1.md new file mode 100644 index 000000000..9033a31a6 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.0-rc1.md @@ -0,0 +1,176 @@ +Changelog +========= + +Alex Morcos (1): + Output line to debug.log when IsInitialBlockDownload latches to false + +Ariel Gabizon (1): + Extend Joinsplit tests to Groth + +Charlie OKeefe (1): + Remove extra slash from lockfile path + +Cory Fields (1): + crypter: shuffle Makefile so that crypto can be used by the wallet + +Daira Hopwood (1): + Support testnet rollback. + +Daniel Cousens (2): + move rpc* to rpc/ + rpc: update inline comments to refer to new file paths + +Dimitris Apostolou (1): + Fix typos + +Duke Leto (3): + Fix absurd fee bug reported in #3281, with tests + Update comment as per @arielgabizon + Improve error message + +Eirik Ogilvie-Wigley (24): + Add more options when asserting in RPC tests + Add change indicator for notes + Fix test broken by change indicator + Rename note data to include sprout + Remove redundant curly braces + Consolidate for loops + Add out point for sapling note data + Add sapling note data and map + Decrement sapling note witnesses + Clear sapling witness cache + Extract method for copying previous witnesses + Extract methods for incrementing witnesses + Extract method for incrementing witness heights + Pass sapling merkle tree when incrementing witnesses + Increment sapling note witnesses + Rename sprout specific methods + Remove extra indentation + Add getter and setter for sapling note data and update tests + Add parameter for version in GetValidReceive + Rename Merkle Trees to include sprout or sapling + Rename Witnesses to include sprout or sapling + Rename test objects to include sprout or sapling + Only include the change field if we have a spending key + Fix assertion and comment + +Gregory Maxwell (2): + IBD check uses minimumchain work instead of checkpoints. + IsInitialBlockDownload no longer uses header-only timestamps. + +Jack Grigg (38): + Add some more checkpoints, up to the 1.1.0 release + Add Sapling support to z_validateaddress + Update payment-api.md with type field of z_validateaddress + Alter SaplingNote::nullifier() to take a SaplingFullViewingKey + Expose note position in IncrementalMerkleWitness + TransactionBuilder with support for creating Sapling-only transactions + TransactionBuilder: Check that all anchors in a transaction are identical + Formatting + test: Move ECC_Start() call into src/gtest/main.cpp + TransactionBuilder: Add support for transparent inputs and outputs + TransactionBuilder: Add change output to transaction + TransactionBuilder: Make fee configurable + Rename xsk to expsk + Implement CKeyStore::GetSaplingPaymentAddresses() + Raise the 90-character limit on Bech32 encodings + Add Sapling support to z_getnewaddress and z_listaddresses + Fix block hash for checkpoint at height 270000 + Formatting + test: Deduplicate logic in wallet_addresses RPC test + test: Another assert in wallet_zkeys_tests.store_and_load_sapling_zkeys + test: Fix permissions of wallet_addresses + test: Update rpc_wallet_z_importexport to account for Sapling changes + Rename DecryptSpendingKey -> DecryptSproutSpendingKey + Rename CryptedSpendingKeyMap -> CryptedSproutSpendingKeyMap + Add Sapling decryption check to CCryptoKeyStore::Unlock() + Check for unencrypted Sapling keys in CCryptoKeyStore::SetCrypted() + Remove outdated comment + Add CWallet::AddCryptedSaplingSpendingKey() hook + Pass SaplingPaymentAddress to store through the CKeyStore + Rename SpendingKeyMap -> SproutSpendingKeyMap + Rename Serialized*Size -> SerializedSprout*Size + Rename *ViewingKey* -> *SproutViewingKey* + Formatting nits + Rename *SpendingKey -> *SproutSpendingKey + chainparams: Add BIP 44 coin type (as registered in SLIP 44) + Upgrade Rust to 1.28.0 stable + Adjust Makefile so that common can be used by the wallet + Move RewindBlockIndex log message inside rewindLength check + +Jay Graber (13): + Add Sapling Add/Have/Get to keystore + Add SaplingIncomingViewingKeys map, SaplingFullViewingKey methods + Add StoreAndRetrieveSaplingSpendingKey test + Change default_address to return SaplingPaymentAddr and not boost::optional + Add crypted keystore sapling add key + Discard sk if ivk == 0 + Add Sapling support to z_exportkey + Add Sapling support to z_importkey + Add Sapling to rpc_wallet_z_importexport test + Refactor into visitors and throw errors for invalid key or address. + Take expiryheight as param to createrawtransaction + Add Sapling have/get sk crypter overrides + Add Sapling keys to CCryptoKeyStore::EncryptKeys + +Jonas Schnelli (2): + [RPC, Wallet] Move RPC dispatch table registration to wallet/ code + Fix test_bitcoin circular dependency issue + +Kaz Wesley (1): + IsInitialBlockDownload: usually avoid locking + +Larry Ruane (4): + Disable libsnark debug logging in Boost tests + add extra help how to enable experimental features + Add call to sync_all() after (z_sendmany, wait) + don't ban peers when loading pre-overwinter blocks + +Pejvan (2): + Update README.md + Update README.md + +Richard Littauer (1): + docs(LICENSE): update license year to 2018 + +Sean Bowe (18): + Update librustzcash + Implementation of Sapling in-band secret distribution. + Swap types in OutputDescription to use new NoteEncryption interfaces. + Prevent nonce reuse in Sapling note encryption API. + Add get_esk() function to Sapling note encryption. + Minor edits + Decryption and tests of note/outgoing encryption. + Update librustzcash and sapling-crypto. + Fix bug in return value. + Ensure sum of valueBalance and all vpub_new's does not exceed MAX_MONEY inside of CheckTransactionWithoutProofVerification. + Move `extern params` to beginning of `test_checktransaction`. + Relocate ECC_Start() to avoid test failures. + Don't call ECC_Start/ECC_Stop outside the test harness. + Make changes to gtest ECC behavior suggested by @str4d. + Check the hash of the (Sapling+) zk-SNARK parameters during initialization. + Switch to use the official Sapling parameters. + make-release.py: Versioning changes for 2.0.0-rc1. + make-release.py: Updated manpages for 2.0.0-rc1. + +Simon Liu (9): + Add encryption of SaplingNotePlaintext and SaplingOutgoingPlaintext classes. + Update and fix per review comments, the test for absurd fee. + Minor update to address nits in review. + Implement Sapling note decryption using full viewing key. + Rename AttemptSaplingEncDecryptionUsingFullViewingKey and use function overloading. + Only check for a valid Sapling anchor after Sapling activation. + Clean up for rebase: rename mapNoteData to mapSproutNoteData. + Clean up help messages for RPC createrawtransaction. + Add tests for expiryheight parameter of RPC createrawtransaction. + +Wladimir J. van der Laan (2): + Make max tip age an option instead of chainparam + rpc: Register calls where they are defined + +kozyilmaz (1): + Add -Wl,-pie linker option for macOS and use it instead of -pie + +mdr0id (1): + Fix minor references to auto-senescence in code + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.0.md b/depend/zcash/doc/release-notes/release-notes-2.0.0.md new file mode 100644 index 000000000..7dcbf5d6a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.0.md @@ -0,0 +1,199 @@ +Notable changes +=============== + +Sapling network upgrade +----------------------- + +The activation height for the Sapling network upgrade on mainnet is included +in this release. Sapling will activate on mainnet at height 419200, which is +expected to be mined on the 28th of October 2018. Please upgrade to this release, +or any subsequent release, in order to follow the Sapling network upgrade. + +The testnet is being rolled back in this release to Overwinter. Sapling will +activate on testnet at height 280000. Please update your testnet nodes before +then. + +Changelog +========= + +Alex Morcos (1): + Output line to debug.log when IsInitialBlockDownload latches to false + +Ariel Gabizon (1): + Extend Joinsplit tests to Groth + +Charlie OKeefe (1): + Remove extra slash from lockfile path + +Cory Fields (1): + crypter: shuffle Makefile so that crypto can be used by the wallet + +Daira Hopwood (1): + Support testnet rollback. + +Daniel Cousens (2): + move rpc* to rpc/ + rpc: update inline comments to refer to new file paths + +Dimitris Apostolou (1): + Fix typos + +Duke Leto (3): + Fix absurd fee bug reported in #3281, with tests + Update comment as per @arielgabizon + Improve error message + +Eirik Ogilvie-Wigley (24): + Add more options when asserting in RPC tests + Add change indicator for notes + Fix test broken by change indicator + Rename note data to include sprout + Remove redundant curly braces + Consolidate for loops + Add out point for sapling note data + Add sapling note data and map + Decrement sapling note witnesses + Clear sapling witness cache + Extract method for copying previous witnesses + Extract methods for incrementing witnesses + Extract method for incrementing witness heights + Pass sapling merkle tree when incrementing witnesses + Increment sapling note witnesses + Rename sprout specific methods + Remove extra indentation + Add getter and setter for sapling note data and update tests + Add parameter for version in GetValidReceive + Rename Merkle Trees to include sprout or sapling + Rename Witnesses to include sprout or sapling + Rename test objects to include sprout or sapling + Only include the change field if we have a spending key + Fix assertion and comment + +Gregory Maxwell (2): + IBD check uses minimumchain work instead of checkpoints. + IsInitialBlockDownload no longer uses header-only timestamps. + +Jack Grigg (41): + Add some more checkpoints, up to the 1.1.0 release + Add Sapling support to z_validateaddress + Update payment-api.md with type field of z_validateaddress + Alter SaplingNote::nullifier() to take a SaplingFullViewingKey + Expose note position in IncrementalMerkleWitness + TransactionBuilder with support for creating Sapling-only transactions + TransactionBuilder: Check that all anchors in a transaction are identical + Formatting + test: Move ECC_Start() call into src/gtest/main.cpp + TransactionBuilder: Add support for transparent inputs and outputs + TransactionBuilder: Add change output to transaction + TransactionBuilder: Make fee configurable + Rename xsk to expsk + Implement CKeyStore::GetSaplingPaymentAddresses() + Raise the 90-character limit on Bech32 encodings + Add Sapling support to z_getnewaddress and z_listaddresses + Fix block hash for checkpoint at height 270000 + Formatting + test: Deduplicate logic in wallet_addresses RPC test + test: Another assert in wallet_zkeys_tests.store_and_load_sapling_zkeys + test: Fix permissions of wallet_addresses + test: Update rpc_wallet_z_importexport to account for Sapling changes + Rename DecryptSpendingKey -> DecryptSproutSpendingKey + Rename CryptedSpendingKeyMap -> CryptedSproutSpendingKeyMap + Add Sapling decryption check to CCryptoKeyStore::Unlock() + Check for unencrypted Sapling keys in CCryptoKeyStore::SetCrypted() + Remove outdated comment + Add CWallet::AddCryptedSaplingSpendingKey() hook + Pass SaplingPaymentAddress to store through the CKeyStore + Rename SpendingKeyMap -> SproutSpendingKeyMap + Rename Serialized*Size -> SerializedSprout*Size + Rename *ViewingKey* -> *SproutViewingKey* + Formatting nits + Rename *SpendingKey -> *SproutSpendingKey + chainparams: Add BIP 44 coin type (as registered in SLIP 44) + Upgrade Rust to 1.28.0 stable + Adjust Makefile so that common can be used by the wallet + Move RewindBlockIndex log message inside rewindLength check + test: gtest for Sapling encoding and decoding + test: Use regtest in key_tests/zs_address_test + Disable Sapling features on mainnet + +Jay Graber (13): + Add Sapling Add/Have/Get to keystore + Add SaplingIncomingViewingKeys map, SaplingFullViewingKey methods + Add StoreAndRetrieveSaplingSpendingKey test + Change default_address to return SaplingPaymentAddr and not boost::optional + Add crypted keystore sapling add key + Discard sk if ivk == 0 + Add Sapling support to z_exportkey + Add Sapling support to z_importkey + Add Sapling to rpc_wallet_z_importexport test + Refactor into visitors and throw errors for invalid key or address. + Take expiryheight as param to createrawtransaction + Add Sapling have/get sk crypter overrides + Add Sapling keys to CCryptoKeyStore::EncryptKeys + +Jonas Schnelli (2): + [RPC, Wallet] Move RPC dispatch table registration to wallet/ code + Fix test_bitcoin circular dependency issue + +Kaz Wesley (1): + IsInitialBlockDownload: usually avoid locking + +Larry Ruane (4): + Disable libsnark debug logging in Boost tests + add extra help how to enable experimental features + Add call to sync_all() after (z_sendmany, wait) + don't ban peers when loading pre-overwinter blocks + +Pejvan (2): + Update README.md + Update README.md + +Richard Littauer (1): + docs(LICENSE): update license year to 2018 + +Sean Bowe (21): + Update librustzcash + Implementation of Sapling in-band secret distribution. + Swap types in OutputDescription to use new NoteEncryption interfaces. + Prevent nonce reuse in Sapling note encryption API. + Add get_esk() function to Sapling note encryption. + Minor edits + Decryption and tests of note/outgoing encryption. + Update librustzcash and sapling-crypto. + Fix bug in return value. + Ensure sum of valueBalance and all vpub_new's does not exceed MAX_MONEY inside of CheckTransactionWithoutProofVerification. + Move `extern params` to beginning of `test_checktransaction`. + Relocate ECC_Start() to avoid test failures. + Don't call ECC_Start/ECC_Stop outside the test harness. + Make changes to gtest ECC behavior suggested by @str4d. + Check the hash of the (Sapling+) zk-SNARK parameters during initialization. + Switch to use the official Sapling parameters. + make-release.py: Versioning changes for 2.0.0-rc1. + make-release.py: Updated manpages for 2.0.0-rc1. + make-release.py: Updated release notes and changelog for 2.0.0-rc1. + Always write the empty root down as the best root, since we may roll back. + Sapling mainnet activation height + +Simon Liu (11): + Add encryption of SaplingNotePlaintext and SaplingOutgoingPlaintext classes. + Update and fix per review comments, the test for absurd fee. + Minor update to address nits in review. + Implement Sapling note decryption using full viewing key. + Rename AttemptSaplingEncDecryptionUsingFullViewingKey and use function overloading. + Only check for a valid Sapling anchor after Sapling activation. + Clean up for rebase: rename mapNoteData to mapSproutNoteData. + Clean up help messages for RPC createrawtransaction. + Add tests for expiryheight parameter of RPC createrawtransaction. + make-release.py: Versioning changes for 2.0.0. + make-release.py: Updated manpages for 2.0.0. + +Wladimir J. van der Laan (2): + Make max tip age an option instead of chainparam + rpc: Register calls where they are defined + +kozyilmaz (1): + Add -Wl,-pie linker option for macOS and use it instead of -pie + +mdr0id (1): + Fix minor references to auto-senescence in code + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.1-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.1-rc1.md new file mode 100644 index 000000000..683d5ed22 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.1-rc1.md @@ -0,0 +1,244 @@ +Notable changes +=============== + +Hierarchical Deterministic Key Generation for Sapling +----------------------------------------------------- +All Sapling addresses will use hierarchical deterministic key generation +according to ZIP 32 (keypath m/32'/133'/k' on mainnet). Transparent and +Sprout addresses will still use traditional key generation. + +Backups of HD wallets, regardless of when they have been created, can +therefore be used to re-generate all possible Sapling private keys, even the +ones which haven't already been generated during the time of the backup. +Regular backups are still necessary, however, in order to ensure that +transparent and Sprout addresses are not lost. + +[Pull request](https://github.com/zcash/zcash/pull/3492), [ZIP 32](https://github.com/zcash/zips/blob/master/zip-0032.mediawiki) + +Changelog +========= + +David Mercer (2): + libsnark: convert long long and unsigned long to C++11 fixed-width types + libsnark: convert 0ul to UINT64_C(0) + +Eirik Ogilvie-Wigley (22): + Rename map to include sprout + Add sapling spending keys to z_exportwallet + Rename AddZKey to include sprout + Move AddSpendingKeyToWallet + Return more information when adding a spending key + Add sapling support to z_importwallet + Export comment on HDSeed and fingerprint with wallet + Export zip32 metadata with sapling keys + Don't export empty zip32 metadata + Allow more information to be returned when an async rpc fails + Use utility method to wait for async operations + Remove unneeded semicolons + Remove unused imports + Allow passing timeout parameter to wait_and_assert_operationid_status + Add test for signing raw transactions offline + Incorporate APPROX_RELEASE_HEIGHT when determining what consensus branch to sign with + Allow passing branchId when calling signrawtransaction + Remove unused import + Address need not be optional when adding sapling keys + Use max priority for all shielded transfers + Move FIXME comment to where the fix should happen + Add newly discovered sapling addresses to the wallet + +George Tankersley (2): + Refactor ContextualCheckBlock tests (#3187) + Refactor ContextualCheckBlock tests + +Jack Grigg (83): + [ci-workers] Install Python modules in a virtualenv + [ci-workers] Handle user home directories outside /home + [ci-workers] Handle ansible_processor being either a string or a list + [ci-workers] Add support for MacOSX + [ci-workers] Add a tag for updating dependencies + [ci-workers] Add curl and cmake to dependencies + [ci-workers] README cleanups + [ci-workers] Add pkg-config to general dependencies + depends: Correctly configure Rust when cross-compiling + depends: Configure librustzcash for cross-compiling + depends: Fix BDB naming issue when cross-compiling + zcutil/build.sh: Use $HOST to specify the depends prefix + configure: Don't require RELRO and BIND_NOW when cross-compiling + Measure Windows console size for metrics UI + Use -O1 for darwin and mingw32 release builds + Clean up libzcash CPPFLAGS, CXXFLAGS, and LDFLAGS + zcutil/build.sh: Use config.site to set default ./configure settings + zcutil/build.sh: Remove --enable-werror from default configuration + Pass correct compiler, linker, and flags into libsnark + Use boost::filesystem::path::string() instead of path::native() + Metrics UI: Enable virtual terminal sequence processing on Windows + Metrics UI: Tell Windows users how to stop zcashd + depends: Pass correct compiler, linker, and flags into googletest + configure: Don't add -ldl to RUST_LIBS for mingw32 + test: Fix comment in WalletTests.FindMySaplingNotes + Add Sapling support to GetFilteredNotes() and GetUnspentFilteredNotes() + Add Sapling support to z_getbalance and z_gettotalbalance + Metrics UI: Fall back to 80 cols if GetConsoleScreenBufferInfo() fails + libsnark: Adjust SHA256 K value type to match the constant + libsnark: Use mp_limb_t cast instead of uint64_t when masking bigint.data + libsnark: Fix stale comment + rpc: Clarify Sprout shielded addresses in help text + rpc: Clarify ivk balance issues in help text + Move GetSpendingKeyForPaymentAddress visitor into wallet.h + wallet: Add HaveSpendingKeyForPaymentAddress visitor + rpcwallet: Add TransactionBuilder argument to AsyncRPCOperation_sendmany + rpcwallet: Prevent use of both Sprout and Sapling addresses in z_sendmany + rpcwallet: Add Sapling support to z_sendmany + Define additional booleans for readability + Ensure SCOPED_TRACE falls out of scope when necessary + Revert NU activation heights in reverse order + Fix test after refactor to check bacd-cb-height rule on a genesis block + Rename GetFirstBlockTransaction() to GetFirstBlockCoinbaseTx() + libsnark: Force constants used in test comparisons to be unsigned + libsnark: Use format macro constants for printing fixed-width values + Rename z_inputs_ to z_sprout_inputs_ + Minor cleanups + Fix RPC test that checks exact wording of cleaned-up error message + Fix file permissions of wallet_sapling RPC test + Update librustzcash with ZIP 32 APIs + ZIP 32 Sapling structs + Store HDSeed in CBasicKeyStore + Store HDSeed in CCryptoKeyStore + wallet: Store HDSeed and chain data + wallet: Store Sapling key metadata indexed by ivk + wallet: Switch from SaplingSpendingKey to SaplingExtendedSpendingKey + init: Generate a new HD seed on startup + wallet: Comment out HDSeed and CHDChain persistence to disk + Add ZIP 32 usage to release notes + wallet: Don't allow an HDSeed to be overwritten + Bugfix: Use time instead of block height for Sapling key metadata + net: Check against the current epoch's version when rejecting nodes + Extract a helper method for finding the next epoch + net: Check against the next epoch's version when evicting peers + net: Check against the current epoch's version when disconnecting peers + qa: Test both Overwinter and Sapling peer management + Use ovk directly in the TransactionBuilder API instead of fvk + Generate an ovk to encrypt outCiphertext for t-addr senders + Revert "Disable Sapling features on mainnet" + Use the correct empty memo for Sapling outputs + Add Sapling support to z_shieldcoinbase + Revert "Get rid of consensus.fPowAllowMinDifficultyBlocks." + Revert "Remove testnet-only difficulty rules" + Allow minimum-difficulty blocks on testnet and regtest + Only enable min-difficulty blocks on testnet from a particular height + Update wallet_listreceived test for now-correct empty Sapling memos + Rename min-difficulty flag to remove off-by-one in the name + Explicitly check the min-difficulty flag against boost::none + Position PoW.MinDifficultyRules test after rule activates + Fix pyflakes warnings + Store ExtFVK with encrypted Sapling spending key instead of FVK + Persist Sapling payment address to IVK map + Ignore decoding errors during -zapwallettxes + +Jay Graber (5): + s/jsoutindex/outindex for sapling outputs + z_listunspent sapling support - needs refactor + Add rpc test for sprout txs z_listunspent + Modify comments + Modify GetNullifiersForAddresses for Sapling + +Jonas Schnelli (3): + [Wallet] extend CKeyMetadata with HD keypath Zcash: modified for zip32 + [Wallet] print hd masterkeyid in getwalletinfo Zcash: modified for zip32 + [Wallet] ensure CKeyMetadata.hdMasterKeyID will be cleared during SetNull() Zcash: modified for zip32 + +Larry Ruane (5): + generalize mininode.py protocol versioning + Test peer banning logic in both pre- and post-initial block download states + Sapling support for z_listreceivedbyaddress + z_listunspent rpc unit test: add testing for Sapling + fix z_listunspent includeWatchonly logic + +Marius Kjærstad (3): + Fix for license not being valid + Update debian package copyright license + Missing comma in debian package copyright license + +Sean Bowe (1): + Check commitment validity within the decryption API for Sapling note plaintexts. + +Simon Liu (59): + Rename FindMyNotes to FindMySproutNotes. + Rename GetNoteNullifier to GetSproutNoteNullifier. + Rename mapNullifiersToNotes to mapSproutNullifiersToNotes. + Rename CWallet::AddToSpends methods for clarity. + Rename mapTxNullifiers to mapTxSproutNullifiers. + Add ivk member variable and equality comparators to SaplingNoteData class. + Update CWallet::MarkAffectedTransactionsDirty() for Sapling. + Update CWallet::UpdatedNoteData() for Sapling. + Create CWallet::AddToSaplingSpends() to track Sapling nullifiers. + Update test to pass in required cm to SaplingNotePlaintext::decrypt(). + Create CWallet::FindMySaplingNotes() + Rename IsFromMe(nullifier) to IsSproutNullifierFromMe(nullifier). + Create CWallet::IsSaplingNullifierFromMe() + Remove dead code in CWalletTx::GetAmounts() as filed in issue #3434. + Cleanup CWalletTx::GetAmounts() for clarity. No-op. + Update CWalletTx::GetAmounts() to return COutputEntry for Sapling valueBalance. + Add caching and updating of Sapling note nullifier. + Update CWallet::IsSpent() to check Sapling nullifiers. + Clean up names of unit tests in gtest/test_wallet.cpp. + Add test for CWalletTx::SetSaplingNoteData() + Iterate over mapSaplingFullViewingKeys with ivk->fvk mapping (1:1). + Refactor IsSpent(nullifier) for Sprout and Sapling domain separation. + Fix code review nits. + Add two new wallet tests: FindMySaplingNotes, SaplingNullifierIsSpent. + Add new wallet test: NavigateFromSaplingNullifierToNote + Add new wallet test: UpdatedSaplingNoteData. + Add new wallet tests: SpentSaplingNoteIsFromMe. + Rename wallet tests for clarity between Sprout and Sapling. + Fix typo in variable name in test. + Fix inaccurate comments in test. + Fix typo in parameter name. + Update CWallet::GetConflicts for Sapling. + Add new wallet test: SetSaplingNoteAddrsInCWalletTx. + Add new wallet test: GetConflictedSaplingNotes + Add new wallet test: MarkAffectedSaplingTransactionsDirty + Update wallet unit tests to revert upgraded network parameters. + Clean up wallet unit tests: replace .value() with .get() for clarity. + Fix comment in CWallet::SyncMetaData. + Refactor: rename setLockedNotes -> setLockedSproutNotes + Refactor: rename UnlockAllNotes -> UnlockAllSproutNotes + Refactor: rename ListLockedNotes -> ListLockedSproutNotes + Add methods to store SaplingOutPoint in setLockedSaplingNotes + Add unit test SaplingNoteLocking + Update comment for test ContextualCheckBlockTest.BlockSproutRulesRejectOtherTx + Add Sapling fields to JSON RPC output using TxToJSON. + Update qa test to check for Sapling related JSON fields. + Closes #3534. Do not use APPROX_RELEASE_HEIGHT to get consensus branch id when in regtest mode. + For #3533. Replace asserts with JSON errors. + Update qa test as offline regtest nodes need branch id passed in. + Fix rebasing of CWallet::GetNullifiersForAddresses + Cleanup to address review comments. + Add test that Sapling shielded transactions have MAX_PRIORITY + Closes #3560. Update Sapling note data correctly when importing a key. + For #3546. Shielded tx with missing inputs are not treated as orphans. + For #3546. Improve estimated tx size for Sapling outputs. + Fix deadlock from calling CWallet::AddSaplingIncomingViewingKey instead of CBasicKeyStore::AddSaplingIncomingViewingKey + Fix file permissions of QA test wallet_persistence.py + Update wallet_persistence test to verify wallet txs are persisted across restarts. + Update wallet_persistence test to verify spending notes after restart. + +WO (4): + Fix a bug of Windows binary + Add an assert for num_bits function + long -> int64_t + The long data type is replaced with int64_t + +Za Wilcox (1): + Revise help output for z_sendmany + +mdr0id (8): + Resolve final edits for README + Revert "wallet: Comment out HDSeed and CHDChain persistence to disk" + Persist Sapling key material in the wallet to disk + Serialize Sapling data in CWalletTx + Adding in rpc wallet sap for test_bitcoin + Add gtest coverage of Sapling wallet persistence + make-release.py: Versioning changes for 2.0.1-rc1. + make-release.py: Updated manpages for 2.0.1-rc1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.1.md b/depend/zcash/doc/release-notes/release-notes-2.0.1.md new file mode 100644 index 000000000..b4dad7c25 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.1.md @@ -0,0 +1,276 @@ +Notable changes +=============== + +Enabled Sapling features for mainnet +------------------------------------ +This release adds significant support for Sapling to the wallet and RPC interface. Sapling will activate at block 419200, which is expected to be mined on the 28th of October 2018. Users running v2.0.0 nodes (which are consensus-compatible with Sapling) will follow the network upgrade, but must upgrade to v2.0.1 in order to send or receive Sapling shielded transactions. + +Minimum Difficulty Blocks allowed on testnet +-------------------------------------------- +Sapling activated on testnet at block 280000. Users running v2.0.0 nodes should upgrade to v2.0.1 which introduces a consensus rule change to allow minimum difficulty blocks to be mined from block 299188, thereby splitting the chain. In addition, users running v2.0.1 nodes no longer need to specify `-experimentalfeatures` and `-developersapling` to use Sapling functionality on testnet. + +[Pull request](https://github.com/zcash/zcash/pull/3559) + +Hierarchical Deterministic Key Generation for Sapling +----------------------------------------------------- +All Sapling addresses will use hierarchical deterministic key generation +according to ZIP 32 (keypath m/32'/133'/k' on mainnet). Transparent and +Sprout addresses will still use traditional key generation. + +Backups of HD wallets, regardless of when they have been created, can +therefore be used to re-generate all possible Sapling private keys, even the +ones which haven't already been generated during the time of the backup. +Regular backups are still necessary, however, in order to ensure that +transparent and Sprout addresses are not lost. + +[Pull request](https://github.com/zcash/zcash/pull/3492), [ZIP 32](https://github.com/zcash/zips/blob/master/zip-0032.mediawiki) + +Fix Signing Raw Transactions with Unsynced Offline Nodes +-------------------------------------------------------- +With v2.0.0, in `signrawtransaction` the consensus branch ID (which is used to construct the transaction) was estimated using the chain height. With v2.0.1 this has been improved by also considering the `APPROX_RELEASE_HEIGHT` of the release, and a new parameter to allow the caller to manually override the consensus branch ID that zcashd will use. + +[Pull request](https://github.com/zcash/zcash/pull/3520) + + +Changelog +========= + +David Mercer (2): + libsnark: convert long long and unsigned long to C++11 fixed-width types + libsnark: convert 0ul to UINT64_C(0) + +Eirik Ogilvie-Wigley (24): + Rename map to include sprout + Add sapling spending keys to z_exportwallet + Rename AddZKey to include sprout + Move AddSpendingKeyToWallet + Return more information when adding a spending key + Add sapling support to z_importwallet + Export comment on HDSeed and fingerprint with wallet + Export zip32 metadata with sapling keys + Don't export empty zip32 metadata + Allow more information to be returned when an async rpc fails + Use utility method to wait for async operations + Remove unneeded semicolons + Remove unused imports + Allow passing timeout parameter to wait_and_assert_operationid_status + Add test for signing raw transactions offline + Incorporate APPROX_RELEASE_HEIGHT when determining what consensus branch to sign with + Allow passing branchId when calling signrawtransaction + Remove unused import + Address need not be optional when adding sapling keys + Use max priority for all shielded transfers + Move FIXME comment to where the fix should happen + Add newly discovered sapling addresses to the wallet + Fix HDSeed comment + Better error message when sending to both sprout and sapling + +George Tankersley (2): + Refactor ContextualCheckBlock tests (#3187) + Refactor ContextualCheckBlock tests + +Jack Grigg (83): + [ci-workers] Install Python modules in a virtualenv + [ci-workers] Handle user home directories outside /home + [ci-workers] Handle ansible_processor being either a string or a list + [ci-workers] Add support for MacOSX + [ci-workers] Add a tag for updating dependencies + [ci-workers] Add curl and cmake to dependencies + [ci-workers] README cleanups + [ci-workers] Add pkg-config to general dependencies + depends: Correctly configure Rust when cross-compiling + depends: Configure librustzcash for cross-compiling + depends: Fix BDB naming issue when cross-compiling + zcutil/build.sh: Use $HOST to specify the depends prefix + configure: Don't require RELRO and BIND_NOW when cross-compiling + Measure Windows console size for metrics UI + Use -O1 for darwin and mingw32 release builds + Clean up libzcash CPPFLAGS, CXXFLAGS, and LDFLAGS + zcutil/build.sh: Use config.site to set default ./configure settings + zcutil/build.sh: Remove --enable-werror from default configuration + Pass correct compiler, linker, and flags into libsnark + Use boost::filesystem::path::string() instead of path::native() + Metrics UI: Enable virtual terminal sequence processing on Windows + Metrics UI: Tell Windows users how to stop zcashd + depends: Pass correct compiler, linker, and flags into googletest + configure: Don't add -ldl to RUST_LIBS for mingw32 + test: Fix comment in WalletTests.FindMySaplingNotes + Add Sapling support to GetFilteredNotes() and GetUnspentFilteredNotes() + Add Sapling support to z_getbalance and z_gettotalbalance + Metrics UI: Fall back to 80 cols if GetConsoleScreenBufferInfo() fails + libsnark: Adjust SHA256 K value type to match the constant + libsnark: Use mp_limb_t cast instead of uint64_t when masking bigint.data + libsnark: Fix stale comment + rpc: Clarify Sprout shielded addresses in help text + rpc: Clarify ivk balance issues in help text + Move GetSpendingKeyForPaymentAddress visitor into wallet.h + wallet: Add HaveSpendingKeyForPaymentAddress visitor + rpcwallet: Add TransactionBuilder argument to AsyncRPCOperation_sendmany + rpcwallet: Prevent use of both Sprout and Sapling addresses in z_sendmany + rpcwallet: Add Sapling support to z_sendmany + Define additional booleans for readability + Ensure SCOPED_TRACE falls out of scope when necessary + Revert NU activation heights in reverse order + Fix test after refactor to check bacd-cb-height rule on a genesis block + Rename GetFirstBlockTransaction() to GetFirstBlockCoinbaseTx() + libsnark: Force constants used in test comparisons to be unsigned + libsnark: Use format macro constants for printing fixed-width values + Rename z_inputs_ to z_sprout_inputs_ + Minor cleanups + Fix RPC test that checks exact wording of cleaned-up error message + Fix file permissions of wallet_sapling RPC test + Update librustzcash with ZIP 32 APIs + ZIP 32 Sapling structs + Store HDSeed in CBasicKeyStore + Store HDSeed in CCryptoKeyStore + wallet: Store HDSeed and chain data + wallet: Store Sapling key metadata indexed by ivk + wallet: Switch from SaplingSpendingKey to SaplingExtendedSpendingKey + init: Generate a new HD seed on startup + wallet: Comment out HDSeed and CHDChain persistence to disk + Add ZIP 32 usage to release notes + wallet: Don't allow an HDSeed to be overwritten + Bugfix: Use time instead of block height for Sapling key metadata + net: Check against the current epoch's version when rejecting nodes + Extract a helper method for finding the next epoch + net: Check against the next epoch's version when evicting peers + net: Check against the current epoch's version when disconnecting peers + qa: Test both Overwinter and Sapling peer management + Use ovk directly in the TransactionBuilder API instead of fvk + Generate an ovk to encrypt outCiphertext for t-addr senders + Revert "Disable Sapling features on mainnet" + Use the correct empty memo for Sapling outputs + Add Sapling support to z_shieldcoinbase + Revert "Get rid of consensus.fPowAllowMinDifficultyBlocks." + Revert "Remove testnet-only difficulty rules" + Allow minimum-difficulty blocks on testnet and regtest + Only enable min-difficulty blocks on testnet from a particular height + Update wallet_listreceived test for now-correct empty Sapling memos + Rename min-difficulty flag to remove off-by-one in the name + Explicitly check the min-difficulty flag against boost::none + Position PoW.MinDifficultyRules test after rule activates + Fix pyflakes warnings + Store ExtFVK with encrypted Sapling spending key instead of FVK + Persist Sapling payment address to IVK map + Ignore decoding errors during -zapwallettxes + +Jay Graber (5): + s/jsoutindex/outindex for sapling outputs + z_listunspent sapling support - needs refactor + Add rpc test for sprout txs z_listunspent + Modify comments + Modify GetNullifiersForAddresses for Sapling + +Jonas Schnelli (3): + [Wallet] extend CKeyMetadata with HD keypath Zcash: modified for zip32 + [Wallet] print hd masterkeyid in getwalletinfo Zcash: modified for zip32 + [Wallet] ensure CKeyMetadata.hdMasterKeyID will be cleared during SetNull() Zcash: modified for zip32 + +Jonathan "Duke" Leto (1): + Fix some typos in rpc-tests readme + +Larry Ruane (5): + generalize mininode.py protocol versioning + Test peer banning logic in both pre- and post-initial block download states + Sapling support for z_listreceivedbyaddress + z_listunspent rpc unit test: add testing for Sapling + fix z_listunspent includeWatchonly logic + +Marius Kjærstad (3): + Fix for license not being valid + Update debian package copyright license + Missing comma in debian package copyright license + +Sean Bowe (1): + Check commitment validity within the decryption API for Sapling note plaintexts. + +Simon Liu (68): + Rename FindMyNotes to FindMySproutNotes. + Rename GetNoteNullifier to GetSproutNoteNullifier. + Rename mapNullifiersToNotes to mapSproutNullifiersToNotes. + Rename CWallet::AddToSpends methods for clarity. + Rename mapTxNullifiers to mapTxSproutNullifiers. + Add ivk member variable and equality comparators to SaplingNoteData class. + Update CWallet::MarkAffectedTransactionsDirty() for Sapling. + Update CWallet::UpdatedNoteData() for Sapling. + Create CWallet::AddToSaplingSpends() to track Sapling nullifiers. + Update test to pass in required cm to SaplingNotePlaintext::decrypt(). + Create CWallet::FindMySaplingNotes() + Rename IsFromMe(nullifier) to IsSproutNullifierFromMe(nullifier). + Create CWallet::IsSaplingNullifierFromMe() + Remove dead code in CWalletTx::GetAmounts() as filed in issue #3434. + Cleanup CWalletTx::GetAmounts() for clarity. No-op. + Update CWalletTx::GetAmounts() to return COutputEntry for Sapling valueBalance. + Add caching and updating of Sapling note nullifier. + Update CWallet::IsSpent() to check Sapling nullifiers. + Clean up names of unit tests in gtest/test_wallet.cpp. + Add test for CWalletTx::SetSaplingNoteData() + Iterate over mapSaplingFullViewingKeys with ivk->fvk mapping (1:1). + Refactor IsSpent(nullifier) for Sprout and Sapling domain separation. + Fix code review nits. + Add two new wallet tests: FindMySaplingNotes, SaplingNullifierIsSpent. + Add new wallet test: NavigateFromSaplingNullifierToNote + Add new wallet test: UpdatedSaplingNoteData. + Add new wallet tests: SpentSaplingNoteIsFromMe. + Rename wallet tests for clarity between Sprout and Sapling. + Fix typo in variable name in test. + Fix inaccurate comments in test. + Fix typo in parameter name. + Update CWallet::GetConflicts for Sapling. + Add new wallet test: SetSaplingNoteAddrsInCWalletTx. + Add new wallet test: GetConflictedSaplingNotes + Add new wallet test: MarkAffectedSaplingTransactionsDirty + Update wallet unit tests to revert upgraded network parameters. + Clean up wallet unit tests: replace .value() with .get() for clarity. + Fix comment in CWallet::SyncMetaData. + Refactor: rename setLockedNotes -> setLockedSproutNotes + Refactor: rename UnlockAllNotes -> UnlockAllSproutNotes + Refactor: rename ListLockedNotes -> ListLockedSproutNotes + Add methods to store SaplingOutPoint in setLockedSaplingNotes + Add unit test SaplingNoteLocking + Update comment for test ContextualCheckBlockTest.BlockSproutRulesRejectOtherTx + Add Sapling fields to JSON RPC output using TxToJSON. + Update qa test to check for Sapling related JSON fields. + Closes #3534. Do not use APPROX_RELEASE_HEIGHT to get consensus branch id when in regtest mode. + For #3533. Replace asserts with JSON errors. + Update qa test as offline regtest nodes need branch id passed in. + Fix rebasing of CWallet::GetNullifiersForAddresses + Cleanup to address review comments. + Add test that Sapling shielded transactions have MAX_PRIORITY + Closes #3560. Update Sapling note data correctly when importing a key. + For #3546. Shielded tx with missing inputs are not treated as orphans. + For #3546. Improve estimated tx size for Sapling outputs. + Fix deadlock from calling CWallet::AddSaplingIncomingViewingKey instead of CBasicKeyStore::AddSaplingIncomingViewingKey + Fix file permissions of QA test wallet_persistence.py + Update wallet_persistence test to verify wallet txs are persisted across restarts. + Update wallet_persistence test to verify spending notes after restart. + Resolves Sapling nullifier persistence issue when importing a key. + Update test to verify Sapling nullifiers and witnesses persist correctly. + For #3359. RPCs transferring funds return error if Sapling addresses are used before Sapling activation. + For #3359. Return error if Sapling addresses passed to RPC z_mergetoaddress. + Update mainnet checkpoint for block 410100. + Update release notes for v2.0.1 + Update release-notes.md for clarity. + make-release.py: Versioning changes for 2.0.1. + make-release.py: Updated manpages for 2.0.1. + +WO (4): + Fix a bug of Windows binary + Add an assert for num_bits function + long -> int64_t + The long data type is replaced with int64_t + +Za Wilcox (1): + Revise help output for z_sendmany + +mdr0id (9): + Resolve final edits for README + Revert "wallet: Comment out HDSeed and CHDChain persistence to disk" + Persist Sapling key material in the wallet to disk + Serialize Sapling data in CWalletTx + Adding in rpc wallet sap for test_bitcoin + Add gtest coverage of Sapling wallet persistence + make-release.py: Versioning changes for 2.0.1-rc1. + make-release.py: Updated manpages for 2.0.1-rc1. + make-release.py: Updated release notes and changelog for 2.0.1-rc1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.2-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.2-rc1.md new file mode 100644 index 000000000..f79e0fd57 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.2-rc1.md @@ -0,0 +1,106 @@ +Notable changes +=============== + +Other issues +============ + +Revoked key error when upgrading on Debian +------------------------------------------ + +If you see the following error when updating to a new version of zcashd: + +`The following signatures were invalid: REVKEYSIG AEFD26F966E279CD` + +Remove the key marked as revoked: + +`sudo apt-key del AEFD26F966E279CD` + +Then retrieve the updated key: + +`wget -qO - https://apt.z.cash/zcash.asc | sudo apt-key add -` + +Then update the package lists: + +`sudo apt-get update` + +[Issue](https://github.com/zcash/zcash/issues/3612) + +Changelog +========= + +Charlie O'Keefe (2): + Save and restore current_path in TestingSetup constructor/destructor + Add a call to SetupNetworking in BasicTestingSetup + +Eirik Ogilvie-Wigley (17): + Rename GenerateNewZKey to include Sprout + GenerateNewSproutZKey can return a SproutPaymentAddress + Remove unnecessary call to IsValidPaymentAddress + Remove unspent note entry structs + Add functionality from GetUnspentFilteredNotes to GetFilteredNotes + Remove GetUnspentFilteredNotes + Wrap long line and update comments + Fix error message + Fix potentially misleading test failures + Fix z_mergetoaddress parameter tests + Add fail method to rpc test utils + Extend Sprout mergetoaddress rpc test to also work for Sapling + Add Sapling support to z_mergetoaddress + Add locking for Sapling notes + Better error messages when sending between Sprout and Sapling + Add additional z_mergetoaddress parameter tests + Adjust z_mergetoaddress assertions in Sapling rpc test + +Gareth Davies (2): + Add clarifying text for parameter size + Cleaning up RPC output + +Jack Grigg (7): + Update IncrementalMerkleTree test vectors to use valid commitments + Migrate to current librustzcash + Pass parameter paths as native strings to librustzcash + Build librustzcash package without changing directory + Set nSaplingValue in-memory when loading block index from disk + Comment in CDiskBlockIndex that LoadBlockIndexGuts also needs updating + Test Sapling value pool accounting + +Jonathan "Duke" Leto (2): + Clarify in sendmany/z_sendmany rpc docs that amounts are not floating point + Fix another instance of incorrectly saying amount is double precision, and s/ZC/ZEC/ + +Larry Ruane (3): + sapling z_sendmany default memo 0xf6 + zeros + update bug in wallet_listreceived.py, now it highlights the fix + don't ban peers when loading pre-sapling (and pre-blossom) blocks + +Simon Liu (14): + Add test to verify final sapling root in block header is updated. + Closes #3467. Add benchmarks for Sapling spends and outputs. + Closes #3616. Document revoked key error when upgrading on Debian. + Closes #3329. Send alert to put non-Sapling nodes into safe mode. + Closes #3597. TransactionBuilder checks tx version before adding Sapling spends and outputs. + Closes #3671 to make "sapling" the default for z_getnewaddress RPC. + Update rpc_wallet_tests for new "sapling" default for z_getnewaddress. + Update qa tests for new "sapling" default for z_getnewaddress. + Add support for "notfound" message to mininode. + For ZEC-013. Mitigate potential tx expiry height related DoS vector. + For ZEC-013. Don't propagate txs which are expiring soon in p2p messages. + For ZEC-013. RPC createrawtransaction returns error if tx expiring soon. + For ZEC-013. Update qa tests broken by expiring soon threshold. + For ZEC-013. RPC sendrawtransaction returns error if tx expiring soon. + +Suhas Daftuar (2): + Do not inv old or missing blocks when pruning + Enable block relay when pruning + +arielgabizon (2): + add test for sapling spend with transparent recipient + rename HaveJoinSplitRequirements for Sapling + +mdr0id (2): + make-release.py: Versioning changes for 2.0.2-rc1. + make-release.py: Updated manpages for 2.0.2-rc1. + +tpantin (1): + Updating copyright year from 2017 to 2018 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.2.md b/depend/zcash/doc/release-notes/release-notes-2.0.2.md new file mode 100644 index 000000000..f7f0f6599 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.2.md @@ -0,0 +1,110 @@ +Notable changes +=============== + +Other issues +============ + +Revoked key error when upgrading on Debian +------------------------------------------ + +If you see the following error when updating to a new version of zcashd: + +`The following signatures were invalid: REVKEYSIG AEFD26F966E279CD` + +Remove the key marked as revoked: + +`sudo apt-key del AEFD26F966E279CD` + +Then retrieve the updated key: + +`wget -qO - https://apt.z.cash/zcash.asc | sudo apt-key add -` + +Then update the package lists: + +`sudo apt-get update` + +[Issue](https://github.com/zcash/zcash/issues/3612) + +Changelog +========= + +Charlie O'Keefe (2): + Save and restore current_path in TestingSetup constructor/destructor + Add a call to SetupNetworking in BasicTestingSetup + +Eirik Ogilvie-Wigley (17): + Rename GenerateNewZKey to include Sprout + GenerateNewSproutZKey can return a SproutPaymentAddress + Remove unnecessary call to IsValidPaymentAddress + Remove unspent note entry structs + Add functionality from GetUnspentFilteredNotes to GetFilteredNotes + Remove GetUnspentFilteredNotes + Wrap long line and update comments + Fix error message + Fix potentially misleading test failures + Fix z_mergetoaddress parameter tests + Add fail method to rpc test utils + Extend Sprout mergetoaddress rpc test to also work for Sapling + Add Sapling support to z_mergetoaddress + Add locking for Sapling notes + Better error messages when sending between Sprout and Sapling + Add additional z_mergetoaddress parameter tests + Adjust z_mergetoaddress assertions in Sapling rpc test + +Gareth Davies (2): + Add clarifying text for parameter size + Cleaning up RPC output + +Jack Grigg (7): + Update IncrementalMerkleTree test vectors to use valid commitments + Migrate to current librustzcash + Pass parameter paths as native strings to librustzcash + Build librustzcash package without changing directory + Set nSaplingValue in-memory when loading block index from disk + Comment in CDiskBlockIndex that LoadBlockIndexGuts also needs updating + Test Sapling value pool accounting + +Jonathan "Duke" Leto (2): + Clarify in sendmany/z_sendmany rpc docs that amounts are not floating point + Fix another instance of incorrectly saying amount is double precision, and s/ZC/ZEC/ + +Larry Ruane (4): + sapling z_sendmany default memo 0xf6 + zeros + update bug in wallet_listreceived.py, now it highlights the fix + don't ban peers when loading pre-sapling (and pre-blossom) blocks + remove non-ascii characters from help text + +Simon Liu (14): + Add test to verify final sapling root in block header is updated. + Closes #3467. Add benchmarks for Sapling spends and outputs. + Closes #3616. Document revoked key error when upgrading on Debian. + Closes #3329. Send alert to put non-Sapling nodes into safe mode. + Closes #3597. TransactionBuilder checks tx version before adding Sapling spends and outputs. + Closes #3671 to make "sapling" the default for z_getnewaddress RPC. + Update rpc_wallet_tests for new "sapling" default for z_getnewaddress. + Update qa tests for new "sapling" default for z_getnewaddress. + Add support for "notfound" message to mininode. + For ZEC-013. Mitigate potential tx expiry height related DoS vector. + For ZEC-013. Don't propagate txs which are expiring soon in p2p messages. + For ZEC-013. RPC createrawtransaction returns error if tx expiring soon. + For ZEC-013. Update qa tests broken by expiring soon threshold. + For ZEC-013. RPC sendrawtransaction returns error if tx expiring soon. + +Suhas Daftuar (2): + Do not inv old or missing blocks when pruning + Enable block relay when pruning + +arielgabizon (2): + add test for sapling spend with transparent recipient + rename HaveJoinSplitRequirements for Sapling + +mdr0id (5): + make-release.py: Versioning changes for 2.0.2-rc1. + make-release.py: Updated manpages for 2.0.2-rc1. + make-release.py: Updated release notes and changelog for 2.0.2-rc1. + make-release.py: Versioning changes for 2.0.2. + make-release.py: Updated manpages for 2.0.2. + +tpantin (1): + Updating copyright year from 2017 to 2018 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.3-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.3-rc1.md new file mode 100644 index 000000000..4291bf77f --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.3-rc1.md @@ -0,0 +1,57 @@ +Changelog +========= + +Alex Morcos (3): + ModifyNewCoins saves database lookups + Make CCoinsViewTest behave like CCoinsViewDB + Add unit test for UpdateCoins + +Charlie O'Keefe (1): + initialize pCurrentParams in TransactionBuilder tests + +Dimitris Apostolou (1): + Update zmq to 4.3.1 + +Eirik Ogilvie-Wigley (11): + Remove --disable-libs flag from help output + Update z_mergetoaddress documentation + flake8 cleanup + Move common code to helper + Make variables local + Check entire contents of mempool + fail test if pong is not received + Extract helper methods + Strategically sync to prevent intermittent failures + Return more information when building a transaction fails + throw an exception rather than returning false when building invalid transactions + +George Tankersley (2): + zmq: add flag to publish all checked blocks + zmq: remove extraneous space from zmq_sub.py + +Jack Grigg (5): + Remove the testing of duplicate coinbase transactions + wallet: Skip transactions with no shielded data in CWallet::SetBestChain() + Use nullptr instead of NULL in wallet tests + Add Sapling test cases + Set Sprout note data in WalletTest.WriteWitnessCache + +Larry Ruane (1): + wait for miner threads to exit (join them) + +Pieter Wuille (3): + Make sigcache faster and more efficient + Evict sigcache entries that are seen in a block + Don't wipe the sigcache in TestBlockValidity + +Sean Bowe (1): + Allow user to ask server to save the Sprout R1CS out during startup. + +ca333 (1): + update libsodium dl-path + +mdr0id (3): + Make pythonisms consistent + make-release.py: Versioning changes for 2.0.3-rc1. + make-release.py: Updated manpages for 2.0.3-rc1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.3.md b/depend/zcash/doc/release-notes/release-notes-2.0.3.md new file mode 100644 index 000000000..9b59be0e3 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.3.md @@ -0,0 +1,61 @@ +Changelog +========= + +Alex Morcos (3): + ModifyNewCoins saves database lookups + Make CCoinsViewTest behave like CCoinsViewDB + Add unit test for UpdateCoins + +Charlie O'Keefe (1): + initialize pCurrentParams in TransactionBuilder tests + +Dimitris Apostolou (1): + Update zmq to 4.3.1 + +Eirik Ogilvie-Wigley (11): + Remove --disable-libs flag from help output + Update z_mergetoaddress documentation + flake8 cleanup + Move common code to helper + Make variables local + Check entire contents of mempool + fail test if pong is not received + Extract helper methods + Strategically sync to prevent intermittent failures + Return more information when building a transaction fails + throw an exception rather than returning false when building invalid transactions + +George Tankersley (2): + zmq: add flag to publish all checked blocks + zmq: remove extraneous space from zmq_sub.py + +Jack Grigg (5): + Remove the testing of duplicate coinbase transactions + wallet: Skip transactions with no shielded data in CWallet::SetBestChain() + Use nullptr instead of NULL in wallet tests + Add Sapling test cases + Set Sprout note data in WalletTest.WriteWitnessCache + +Larry Ruane (1): + wait for miner threads to exit (join them) + +Pieter Wuille (3): + Make sigcache faster and more efficient + Evict sigcache entries that are seen in a block + Don't wipe the sigcache in TestBlockValidity + +Sean Bowe (1): + Allow user to ask server to save the Sprout R1CS out during startup. + +ca333 (1): + update libsodium dl-path + +mdr0id (7): + Make pythonisms consistent + make-release.py: Versioning changes for 2.0.3-rc1. + make-release.py: Updated manpages for 2.0.3-rc1. + make-release.py: Updated release notes and changelog for 2.0.3-rc1. + Update nMinimumChainWork with information from the getblockchaininfo RPC + make-release.py: Versioning changes for 2.0.3. + make-release.py: Updated manpages for 2.0.3. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.4-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.4-rc1.md new file mode 100644 index 000000000..a6ce81aa4 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.4-rc1.md @@ -0,0 +1,132 @@ +Notable changes +=============== + +Sprout note validation bug fixed in wallet +------------------------------------------ +We include a fix for a bug in the Zcashd wallet which could result in Sprout +z-addresses displaying an incorrect balance. Sapling z-addresses are not +impacted by this issue. This would occur if someone sending funds to a Sprout +z-address intentionally sent a different amount in the note commitment of a +Sprout output than the value provided in the ciphertext (the encrypted message +from the sender). + +Users should install this update and then rescan the blockchain by invoking +“zcashd -rescanâ€. Sprout address balances shown by the zcashd wallet should +then be correct. + +Thank you to Alexis Enston for bringing this to our attention. + +[Security Announcement 2019-03-19](https://z.cash/support/security/announcements/security-announcement-2019-03-19/) + +[Pull request](https://github.com/zcash/zcash/pull/3897) + +Miner address selection behaviour fixed +--------------------------------------- +Zcash inherited a bug from upstream Bitcoin Core where both the internal miner +and RPC call `getblocktemplate` would use a fixed transparent address, until RPC +`getnewaddress` was called, instead of using a new transparent address for each +mined block. This was fixed in Bitcoin 0.12 and we have now merged the change. + +Miners who wish to use the same address for every mined block, should use the +`-mineraddress` option. + +[Mining Guide](https://zcash.readthedocs.io/en/latest/rtd_pages/zcash_mining_guide.html) + + +New consensus rule: Reject blocks that violate turnstile (Testnet only) +----------------------------------------------------------------------- +Testnet nodes will now enforce a consensus rule which marks blocks as invalid +if they would lead to a turnstile violation in the Sprout or Sapling value +pools. The motivations and deployment details can be found in the accompanying +[ZIP draft](https://github.com/zcash/zips/pull/210). + +The consensus rule will be enforced on mainnet in a future release. + +[Pull request](https://github.com/zcash/zcash/pull/3885) + + +Changelog +========= + +Eirik Ogilvie-Wigley (14): + Rename methods to include Sprout + Add benchmark for decrypting sapling notes + Move reusable Sapling test setup to utiltest + Move test SaplingNote creation to utiltest + Add test method for generating master Sapling extended spending keys + Include Sapling transactions in increment note witness benchmark + Prevent header from being included multiple times + benchmarks do not require updating network parameters + FakeCoinsViewDB can inherit directly from CCoinsView + Add a method for generating a test CKey + Change to t->z transaction and create separate benchmark for sapling + Renaming and other minor cleanup + Improve some error messages when building a transaction fails + Add missing author aliases + +Gareth Davies (1): + Correcting logo on README + +Jack Grigg (6): + Add Sapling benchmarks to benchmark runner + test: Fetch coinbase address from coinbase UTXOs + test: Make expected_utxos optional in get_coinbase_address() + Add comments + Move utiltest.cpp from wallet to common + Move payment disclosure code and tests into wallet + +Jonas Schnelli (4): + detach wallet from miner + fix GetScriptForMining() CReserveKey::keepKey() issue + add CReserveScript to allow modular script keeping/returning + miner: rename UpdateRequestCount signal to ResetRequestCount + +Jonathan "Duke" Leto (2): + Backport size_on_disk to RPC call getblockchaininfo. + Add size_on_disk test + +Marius Kjærstad (1): + Update COPYRIGHT_YEAR in clientversion.h to 2019 + +Paige Peterson (1): + redirect and update source documentation + +Pieter Wuille (1): + Simplify DisconnectBlock arguments/return value + +Sean Bowe (13): + (testnet) Fall back to hardcoded shielded pool balance to avoid reorgs. + (testnet) Reject blocks that result in turnstile violations + (testnet/regtest) Avoid mining transactions that would violate the turnstile. + Fix tallying for Sprout/Sapling value pools. + Consolidate logic to enable turnstile auditing for testnet/regtest/mainnet. + Use existing chainparams variable + Add newlines to turntile log messages for miner + Check blockhash of fallback block for Sprout value pool balance + Change SproutValuePoolCheckpointEnabled to ZIP209Activated + Only enforce Sapling turnstile if balance values have been populated. + Do not enable ZIP209 on regtest right now. + (minor) Remove added newline. + (wallet) Check that the commitment matches the note plaintext provided by the sender. + +Simon Liu (5): + Update nMinimumChainWork using block 497000. + Add checkpoint for block 497000. + Update release notes for 2.0.4 + make-release.py: Versioning changes for 2.0.4-rc1. + make-release.py: Updated manpages for 2.0.4-rc1. + +Taylor Hornby (5): + Update OpenSSL from 1.1.0h to 1.1.1a. #3786 + Update boost from v1.66.0 to v1.69.0. #3786 + Update Rust from v1.28.0 to v1.32.0. #3786 + Update Proton from 0.17.0 to 0.26.0. #3816, #3786 + Patch Proton for a minimal build. #3786 + +sandakersmann (1): + Update of copyright year to 2019 + +zebambam (2): + Added documentation warnings about DNS rebinding attacks, issue #3841 + Added responsible disclosure statement for issue #3869 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.4.md b/depend/zcash/doc/release-notes/release-notes-2.0.4.md new file mode 100644 index 000000000..272a038dc --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.4.md @@ -0,0 +1,139 @@ +Notable changes +=============== + +Sprout note validation bug fixed in wallet +------------------------------------------ +We include a fix for a bug in the Zcashd wallet which could result in Sprout +z-addresses displaying an incorrect balance. Sapling z-addresses are not +impacted by this issue. This would occur if someone sending funds to a Sprout +z-address intentionally sent a different amount in the note commitment of a +Sprout output than the value provided in the ciphertext (the encrypted message +from the sender). + +Users should install this update and then rescan the blockchain by invoking +“zcashd -rescanâ€. Sprout address balances shown by the zcashd wallet should +then be correct. + +Thank you to Alexis Enston for bringing this to our attention. + +[Security Announcement 2019-03-19](https://z.cash/support/security/announcements/security-announcement-2019-03-19/) + +[Pull request](https://github.com/zcash/zcash/pull/3897) + +Miner address selection behaviour fixed +--------------------------------------- +Zcash inherited a bug from upstream Bitcoin Core where both the internal miner +and RPC call `getblocktemplate` would use a fixed transparent address, until RPC +`getnewaddress` was called, instead of using a new transparent address for each +mined block. This was fixed in Bitcoin 0.12 and we have now merged the change. + +Miners who wish to use the same address for every mined block, should use the +`-mineraddress` option. + +[Mining Guide](https://zcash.readthedocs.io/en/latest/rtd_pages/zcash_mining_guide.html) + + +New consensus rule: Reject blocks that violate turnstile (Testnet only) +----------------------------------------------------------------------- +Testnet nodes will now enforce a consensus rule which marks blocks as invalid +if they would lead to a turnstile violation in the Sprout or Sapling value +pools. The motivations and deployment details can be found in the accompanying +[ZIP draft](https://github.com/zcash/zips/pull/210). + +The consensus rule will be enforced on mainnet in a future release. + +[Pull request](https://github.com/zcash/zcash/pull/3885) + + +Changelog +========= + +Eirik Ogilvie-Wigley (14): + Rename methods to include Sprout + Add benchmark for decrypting sapling notes + Move reusable Sapling test setup to utiltest + Move test SaplingNote creation to utiltest + Add test method for generating master Sapling extended spending keys + Include Sapling transactions in increment note witness benchmark + Prevent header from being included multiple times + benchmarks do not require updating network parameters + FakeCoinsViewDB can inherit directly from CCoinsView + Add a method for generating a test CKey + Change to t->z transaction and create separate benchmark for sapling + Renaming and other minor cleanup + Improve some error messages when building a transaction fails + Add missing author aliases + +Gareth Davies (1): + Correcting logo on README + +Jack Grigg (6): + Add Sapling benchmarks to benchmark runner + test: Fetch coinbase address from coinbase UTXOs + test: Make expected_utxos optional in get_coinbase_address() + Add comments + Move utiltest.cpp from wallet to common + Move payment disclosure code and tests into wallet + +Jonas Schnelli (4): + detach wallet from miner + fix GetScriptForMining() CReserveKey::keepKey() issue + add CReserveScript to allow modular script keeping/returning + miner: rename UpdateRequestCount signal to ResetRequestCount + +Jonathan "Duke" Leto (2): + Backport size_on_disk to RPC call getblockchaininfo. + Add size_on_disk test + +Marius Kjærstad (1): + Update COPYRIGHT_YEAR in clientversion.h to 2019 + +Paige Peterson (1): + redirect and update source documentation + +Pieter Wuille (1): + Simplify DisconnectBlock arguments/return value + +Sean Bowe (13): + (testnet) Fall back to hardcoded shielded pool balance to avoid reorgs. + (testnet) Reject blocks that result in turnstile violations + (testnet/regtest) Avoid mining transactions that would violate the turnstile. + Fix tallying for Sprout/Sapling value pools. + Consolidate logic to enable turnstile auditing for testnet/regtest/mainnet. + Use existing chainparams variable + Add newlines to turntile log messages for miner + Check blockhash of fallback block for Sprout value pool balance + Change SproutValuePoolCheckpointEnabled to ZIP209Activated + Only enforce Sapling turnstile if balance values have been populated. + Do not enable ZIP209 on regtest right now. + (minor) Remove added newline. + (wallet) Check that the commitment matches the note plaintext provided by the sender. + +Simon Liu (9): + Update nMinimumChainWork using block 497000. + Add checkpoint for block 497000. + Update release notes for 2.0.4 + make-release.py: Versioning changes for 2.0.4-rc1. + make-release.py: Updated manpages for 2.0.4-rc1. + make-release.py: Updated release notes and changelog for 2.0.4-rc1. + Fix typo in release notes. + make-release.py: Versioning changes for 2.0.4. + make-release.py: Updated manpages for 2.0.4. + +Taylor Hornby (8): + Update OpenSSL from 1.1.0h to 1.1.1a. #3786 + Update boost from v1.66.0 to v1.69.0. #3786 + Update Rust from v1.28.0 to v1.32.0. #3786 + Update Proton from 0.17.0 to 0.26.0. #3816, #3786 + Patch Proton for a minimal build. #3786 + Fix proton patch regression. #3916 + Fix OpenSSL reproducible build regression + Patch out proton::url deprecation as workaround for build warnings + +sandakersmann (1): + Update of copyright year to 2019 + +zebambam (2): + Added documentation warnings about DNS rebinding attacks, issue #3841 + Added responsible disclosure statement for issue #3869 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.5-1.md b/depend/zcash/doc/release-notes/release-notes-2.0.5-1.md new file mode 100644 index 000000000..ef02d80b5 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.5-1.md @@ -0,0 +1,68 @@ +Notable changes +=============== + +Sprout to Sapling Migration Tool +-------------------------------- +This release includes the addition of a tool that will enable users to migrate +shielded funds from the Sprout pool to the Sapling pool while minimizing +information leakage. + +The migration can be enabled using the RPC `z_setmigration` or by including +`-migration` in the `zcash.conf` file. Unless otherwise specified funds will be +migrated to the wallet's default Sapling address; it is also possible to set the +receiving Sapling address using the `-migrationdestaddress` option in `zcash.conf`. + +See [ZIP308](https://github.com/zcash/zips/blob/master/zip-0308.rst) for full details. + +Sprout to Sapling Migration Tool Fixes +-------------------------------------- +The 2.0.5-1 release includes fixes to the Sprout to Sapling Migration Tool +found in testing. We resolved an issue which would cause the zcash daemon to +crash if calling the RPC `z_getmigrationstatus` while a wallet's migration +transactions are in the mempool. + +New consensus rule: Reject blocks that violate turnstile +-------------------------------------------------------- +In the 2.0.4 release the consensus rules were changed on testnet to enforce a +consensus rule which marks blocks as invalid if they would lead to a turnstile +violation in the Sprout or Shielded value pools. +**This release enforces the consensus rule change on mainnet** + +The motivations and deployment details can be found in the accompanying +[ZIP draft](https://github.com/zcash/zips/pull/210) and +[PR 3968](https://github.com/zcash/zcash/pull/3968). + +Developers can use a new experimental feature `-developersetpoolsizezero` to test +Sprout and Sapling turnstile violations. See [PR 3964](https://github.com/zcash/zcash/pull/3964) for more details. + + +64-bit ARMv8 support +-------------------- +Added ARMv8 (AArch64) support. This enables users to build zcash on even more +devices. + +For information on how to build see the [User Guide](https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#build) + +Users on the Zcash forum have reported successes with both the Pine64 Rock64Pro +and Odroid C2 which contain 4GB and 2GB of RAM respectively. + +Just released, the Odroid N2 looks like a great solution with 4GB of RAM. The +newly released Jetson Nano Developer Kit from Nvidia (also 4GB of RAM) is also +worth a look. The NanoPC-T3 Plus is another option but for the simplest/best +experience choose a board with 4GB of RAM. Just make sure before purchase that +the CPU supports the 64-bit ARMv8 architecture. + +Changelog +========= + +Eirik0 (9): + Correctly account for migration transactions in the mempool + Store the migration operation id rather than the operation iteslf + Rename variable and add comment + Notable changes for v2.0.5-1 + Fix summing available funds + Add the amount migrated to the operation's result + coinsView is required when using TransactionBuilder if there may be Sprout change + make-release.py: Versioning changes for 2.0.5-1. + make-release.py: Updated manpages for 2.0.5-1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.5-2.md b/depend/zcash/doc/release-notes/release-notes-2.0.5-2.md new file mode 100644 index 000000000..8d7dc947a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.5-2.md @@ -0,0 +1,77 @@ +Notable changes +=============== + +Sprout to Sapling Migration Tool +-------------------------------- +This release includes the addition of a tool that will enable users to migrate +shielded funds from the Sprout pool to the Sapling pool while minimizing +information leakage. + +The migration can be enabled using the RPC `z_setmigration` or by including +`migration=1` in the `zcash.conf` file. Unless otherwise specified funds will be +migrated to the wallet's default Sapling address; it is also possible to set the +receiving Sapling address using the `migrationdestaddress=` option in +`zcash.conf`. + +See [ZIP308](https://github.com/zcash/zips/blob/master/zip-0308.rst) for full details. + +Sprout to Sapling Migration Tool Fixes +-------------------------------------- +The 2.0.5-1 and 2.0.5-2 releases include fixes to the Sprout to Sapling +Migration Tool found in testing. + +For a complete list of changes in 2.0.5, 2.0.5-1 and 2.0.5-2, see the [2.0.5 milestone](https://github.com/zcash/zcash/milestone/79?closed=1). + +New consensus rule: Reject blocks that violate turnstile +-------------------------------------------------------- +In the 2.0.4 release the consensus rules were changed on testnet to enforce a +consensus rule which marks blocks as invalid if they would lead to a turnstile +violation in the Sprout or Shielded value pools. +**This release enforces the consensus rule change on mainnet.** + +The motivations and deployment details can be found in +[ZIP209](https://github.com/zcash/zips/blob/master/zip-0209.rst) and +[PR 3968](https://github.com/zcash/zcash/pull/3968). + +Developers can use a new experimental feature `-developersetpoolsizezero` to test +Sprout and Sapling turnstile violations. See [PR 3964](https://github.com/zcash/zcash/pull/3964) for more details. + +64-bit ARMv8 support +-------------------- +Added ARMv8 (AArch64) support. This enables users to build zcash on even more +devices. + +For information on how to build see the [User Guide](https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#build). + +Users on the Zcash forum have reported successes with both the Pine64 Rock64Pro +and Odroid C2 which contain 4GB and 2GB of RAM respectively. + +Just released, the Odroid N2 looks like a great solution with 4GB of RAM. The +newly released Jetson Nano Developer Kit from Nvidia (also 4GB of RAM) is also +worth a look. The NanoPC-T3 Plus is another option but for the simplest/best +experience choose a board with 4GB of RAM. Just make sure before purchase that +the CPU supports the 64-bit ARMv8 architecture. + +Changelog +========= + +Daira Hopwood (5): + Generalize TransactionBuilder and CreateNewContextualCMutableTransaction to allow choosing the expiry delta. + Repair calls to TransactionBuilder from tests. + Change expiry delta for migration transactions to 450 blocks. + Test the expiry height of migration transactions. + Fix cosmetic spacing issue in z_setmigration help. + +Eirik0 (7): + Do not automatically remove async migration operations and return txids + Add logging for Sprout to Sapling migration transaction generation + Fix LogPrint statements + Notable changes for v2.0.5-2 + Release notes wording and punctuation + make-release.py: Versioning changes for 2.0.5-2. + make-release.py: Updated manpages for 2.0.5-2. + +Simon Liu (2): + Remove unused specifier from format string. + Don't allow migration when node is syncing at launch or after waking up. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.5-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.5-rc1.md new file mode 100644 index 000000000..08640b1f4 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.5-rc1.md @@ -0,0 +1,73 @@ +Changelog +========= + +Braydon Fuller (1): + tests: adds unit test for IsPayToPublicKeyHash method + +Dimitris Apostolou (1): + Electric Coin Company + +Eirik0 (22): + Split test in to multiple parts + Use a custom error type if creating joinsplit descriptions fails + Rename and update comment + Add rpc to enable and disable Sprout to Sapling migration + Move migration logic to ChainTip + Documentation cleanup + Additional locking and race condition prevention + Refactor wait_and_assert_operationid_status to allow returning the result + Set min depth when selecting notes to migrate + Check for full failure message in test case + Add migration options to conf file + Create method for getting HD seed in RPCs + Add rpc to get Sprout to Sapling migration status + Fix help message + Test migration using both the parameter and the default Sapling address + Fix typos and update documentation + use -valueBalance rather than vpub_new to calculate migrated amount + Do not look at vin/vout when determining migration txs and other cleanup + Calculate the number of confimations in the canonical way + Do not throw an exception if HD Seed is not found when exporting wallet + make-release.py: Versioning changes for 2.0.5-rc1. + make-release.py: Updated manpages for 2.0.5-rc1. + +Gareth Davies (1): + Adding addressindex.h to Makefile.am + +Jack Grigg (9): + Add Sprout support to TransactionBuilder + depends: Use full path to cargo binary + depends: Generalise the rust package cross-compilation functions + depends: Add rust-std hash for aarch64-unknown-linux-gnu + depends: Compile bdb with --disable-atomics on aarch64 + depends: Update .gitignore + configure: Guess -march for libsnark OPTFLAGS instead of hard-coding + Add Blossom to upgrade list + init: Fix new HD seed generation for previously-encrypted wallets + +Larry Ruane (6): + fix enable-debug build DB_COINS undefined + add -addressindex changes for bitcore insight block explorer + add -spentindex changes for bitcore insight block explorer + Update boost from v1.69.0 to v1.70.0. #3947 + add -timestampindex for bitcore insight block explorer + 3873 z_setmigration cli bool enable arg conversion + +Marius Kjærstad (1): + Update _COPYRIGHT_YEAR in configure.ac to 2019 + +Mary Moore-Simmons (1): + Creates checklist template for new PRs being opened and addresses Str4d's suggestion for using GitHub handles + +Simon Liu (4): + Add testnet and regtest experimental feature: -developersetpoolsizezero + Add qa test for experimental feature: -developersetpoolsizezero + Enable ZIP209 on mainnet and set fallback Sprout pool balance. + Enable experimental feature -developersetpoolsizezero on mainnet. + +Jack Grigg (1): + remove extra hyphen + +zebambam (1): + Minor speling changes + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.5.md b/depend/zcash/doc/release-notes/release-notes-2.0.5.md new file mode 100644 index 000000000..520060f17 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.5.md @@ -0,0 +1,130 @@ +Notable changes +=============== + +Sprout to Sapling Migration Tool +-------------------------------- +This release includes the addition of a tool that will enable users to migrate +shielded funds from the Sprout pool to the Sapling pool while minimizing +information leakage. + +The migration can be enabled using the RPC `z_setmigration` or by including +`-migration` in the `zcash.conf` file. Unless otherwise specified funds will be +migrated to the wallet's default Sapling address; it is also possible to set the +receiving Sapling address using the `-migrationdestaddress` option in `zcash.conf`. + +See [ZIP308](https://github.com/zcash/zips/blob/master/zip-0308.rst) for full details. + + +New consensus rule: Reject blocks that violate turnstile +-------------------------------------------------------- +In the 2.0.4 release the consensus rules were changed on testnet to enforce a +consensus rule which marks blocks as invalid if they would lead to a turnstile +violation in the Sprout or Shielded value pools. +**This release enforces the consensus rule change on mainnet** + +The motivations and deployment details can be found in the accompanying +[ZIP draft](https://github.com/zcash/zips/pull/210) and +[PR 3968](https://github.com/zcash/zcash/pull/3968). + +Developers can use a new experimental feature `-developersetpoolsizezero` to test +Sprout and Sapling turnstile violations. See [PR 3964](https://github.com/zcash/zcash/pull/3964) for more details. + + +64-bit ARMv8 support +-------------------- +Added ARMv8 (AArch64) support. This enables users to build zcash on even more +devices. + +For information on how to build see the [User Guide](https://zcash.readthedocs.io/en/latest/rtd_pages/user_guide.html#build) + +Users on the Zcash forum have reported successes with both the Pine64 Rock64Pro +and Odroid C2 which contain 4GB and 2GB of RAM respectively. + +Just released, the Odroid N2 looks like a great solution with 4GB of RAM. The +newly released Jetson Nano Developer Kit from Nvidia (also 4GB of RAM) is also +worth a look. The NanoPC-T3 Plus is another option but for the simplest/best +experience choose a board with 4GB of RAM. Just make sure before purchase that +the CPU supports the 64-bit ARMv8 architecture. + +Changelog +========= + +Braydon Fuller (1): + tests: adds unit test for IsPayToPublicKeyHash method + +Dimitris Apostolou (1): + Electric Coin Company + +Eirik0 (27): + Split test in to multiple parts + Use a custom error type if creating joinsplit descriptions fails + Rename and update comment + Add rpc to enable and disable Sprout to Sapling migration + Move migration logic to ChainTip + Documentation cleanup + Additional locking and race condition prevention + Refactor wait_and_assert_operationid_status to allow returning the result + Set min depth when selecting notes to migrate + Check for full failure message in test case + Add migration options to conf file + Create method for getting HD seed in RPCs + Add rpc to get Sprout to Sapling migration status + Fix help message + Test migration using both the parameter and the default Sapling address + Fix typos and update documentation + use -valueBalance rather than vpub_new to calculate migrated amount + Do not look at vin/vout when determining migration txs and other cleanup + Calculate the number of confimations in the canonical way + Do not throw an exception if HD Seed is not found when exporting wallet + make-release.py: Versioning changes for 2.0.5-rc1. + make-release.py: Updated manpages for 2.0.5-rc1. + make-release.py: Updated release notes and changelog for 2.0.5-rc1. + Notable changes for v2.0.5 + Add missing word to release notes + make-release.py: Versioning changes for 2.0.5. + make-release.py: Updated manpages for 2.0.5. + +Gareth Davies (1): + Adding addressindex.h to Makefile.am + +Ian Munoz (1): + add curl to package list for gitian lxc container + +Jack Grigg (9): + Add Sprout support to TransactionBuilder + depends: Use full path to cargo binary + depends: Generalise the rust package cross-compilation functions + depends: Add rust-std hash for aarch64-unknown-linux-gnu + depends: Compile bdb with --disable-atomics on aarch64 + depends: Update .gitignore + configure: Guess -march for libsnark OPTFLAGS instead of hard-coding + Add Blossom to upgrade list + init: Fix new HD seed generation for previously-encrypted wallets + +Larry Ruane (6): + fix enable-debug build DB_COINS undefined + add -addressindex changes for bitcore insight block explorer + add -spentindex changes for bitcore insight block explorer + Update boost from v1.69.0 to v1.70.0. #3947 + add -timestampindex for bitcore insight block explorer + 3873 z_setmigration cli bool enable arg conversion + +Marius Kjærstad (1): + Update _COPYRIGHT_YEAR in configure.ac to 2019 + +Mary Moore-Simmons (1): + Creates checklist template for new PRs being opened and addresses Str4d's suggestion for using GitHub handles + +Simon Liu (5): + Add testnet and regtest experimental feature: -developersetpoolsizezero + Add qa test for experimental feature: -developersetpoolsizezero + Enable ZIP209 on mainnet and set fallback Sprout pool balance. + Enable experimental feature -developersetpoolsizezero on mainnet. + Update chain work and checkpoint using block 525000. + +Jack Grigg (1): + remove extra hyphen + +zebambam (1): + Minor speling changes + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.6-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.6-rc1.md new file mode 100644 index 000000000..ce4014720 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.6-rc1.md @@ -0,0 +1,62 @@ +Changelog +========= + +Daira Hopwood (3): + Closes #3992. Remove obsolete warning message. + make-release.py: Versioning changes for 2.0.6-rc1. + make-release.py: Updated manpages for 2.0.6-rc1. + +Daniel Kraft (1): + Add some const declarations where they are appropriate. + +Eirik Ogilvie-Wigley (7): + Fix tree depth in comment + Update author aliases + Remove old mergetoaddress RPC test + Replace CSproutNotePlaintextEntry with SproutNoteEntry to match Sapling + z_getmigrationstatus help message wording change + Fix z_mergetoaddress sending from ANY_SPROUT/ANY_SAPLING when the wallet contains both note types + Clarify what combinations of from addresses can be used in z_mergetoaddress + +Jack Grigg (10): + Move Equihash parameters into consensus params + Globals: Remove Zcash-specific Params() calls from main.cpp + Globals: Explicitly pass const CChainParams& to IsStandardTx() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to ContextualCheckTransaction() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to DisconnectBlock() + Consistently use chainparams and consensusParams + Globals: Explicitly pass const CChainParams& to IsInitialBlockDownload() + Globals: Explicitly pass const CChainParams& to ReceivedBlockTransactions() + +Jorge Timón (6): + Globals: Explicit Consensus::Params arg for main: + Globals: Make AcceptBlockHeader static (Fix #6163) + Chainparams: Explicit CChainParams arg for main (pre miner): + Chainparams: Explicit CChainParams arg for miner: + Globals: Remove a bunch of Params() calls from main.cpp: + Globals: Explicitly pass const CChainParams& to UpdateTip() + +Larry Ruane (1): + add spentindex to getrawtransaction RPC results + +MarcoFalke (1): + [doc] Fix doxygen comments for members + +Peter Todd (1): + Improve block validity/ConnectBlock() comments + +Simon Liu (1): + Fix typo and clean up help message for RPC z_getmigrationstatus. + +Wladimir J. van der Laan (1): + Break circular dependency main ↔ txdb + +face (2): + Pass CChainParams to DisconnectTip() + Explicitly pass CChainParams to ConnectBlock + +Benjamin Winston (1): + Fixes #4013, added BitcoinABC as a disclosure partner + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.6.md b/depend/zcash/doc/release-notes/release-notes-2.0.6.md new file mode 100644 index 000000000..f1beec511 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.6.md @@ -0,0 +1,102 @@ +Notable changes +=============== + +Debian Stretch is now a Supported Platform +------------------------------------------ + +We now provide reproducible builds for Stretch as well as for Jessie. + + +Fixed a bug in ``z_mergetoaddress`` +----------------------------------- + +We fixed a bug which prevented users sending from ``ANY_SPROUT`` or ``ANY_SAPLING`` +with ``z_mergetoaddress`` when a wallet contained both Sprout and Sapling notes. + + +Insight Explorer +---------------- + +We have been incorporating changes to support the Insight explorer directly from +``zcashd``. v2.0.6 includes the first change to an RPC method. If ``zcashd`` is +run with the flag ``--insightexplorer``` (this requires an index rebuild), the +RPC method ``getrawtransaction`` will now return additional information about +spend indices. + +Changelog +========= + +Charlie O'Keefe (1): + Add stretch to list of suites in gitian linux descriptors + +Daira Hopwood (9): + Closes #3992. Remove obsolete warning message. + make-release.py: Versioning changes for 2.0.6-rc1. + make-release.py: Updated manpages for 2.0.6-rc1. + make-release.py: Updated release notes and changelog for 2.0.6-rc1. + ld --version doesn't work on macOS. + Tweak author aliases. + Add coding declaration to zcutil/release-notes.py + make-release.py: Versioning changes for 2.0.6. + make-release.py: Updated manpages for 2.0.6. + +Daniel Kraft (1): + Add some const declarations where they are appropriate. + +Eirik Ogilvie-Wigley (1): + Notable changes for 2.0.6 + +Eirik Ogilvie-Wigley (7): + Fix tree depth in comment + Update author aliases + Remove old mergetoaddress RPC test + Replace CSproutNotePlaintextEntry with SproutNoteEntry to match Sapling + z_getmigrationstatus help message wording change + Fix z_mergetoaddress sending from ANY_SPROUT/ANY_SAPLING when the wallet contains both note types + Clarify what combinations of from addresses can be used in z_mergetoaddress + +Jack Grigg (10): + Move Equihash parameters into consensus params + Globals: Remove Zcash-specific Params() calls from main.cpp + Globals: Explicitly pass const CChainParams& to IsStandardTx() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to ContextualCheckTransaction() + Globals: Explicit const CChainParams& arg for main: + Globals: Explicitly pass const CChainParams& to DisconnectBlock() + Consistently use chainparams and consensusParams + Globals: Explicitly pass const CChainParams& to IsInitialBlockDownload() + Globals: Explicitly pass const CChainParams& to ReceivedBlockTransactions() + +Jorge Timón (6): + Globals: Explicit Consensus::Params arg for main: + Globals: Make AcceptBlockHeader static (Fix #6163) + Chainparams: Explicit CChainParams arg for main (pre miner): + Chainparams: Explicit CChainParams arg for miner: + Globals: Remove a bunch of Params() calls from main.cpp: + Globals: Explicitly pass const CChainParams& to UpdateTip() + +Larry Ruane (1): + add spentindex to getrawtransaction RPC results + +Marco Falke (1): + [doc] Fix doxygen comments for members + +Mary Moore-Simmons (1): + Fixes issue #3504: Changes to --version and adds a couple other useful commands. + +Peter Todd (1): + Improve block validity/ConnectBlock() comments + +Simon Liu (1): + Fix typo and clean up help message for RPC z_getmigrationstatus. + +Wladimir J. van der Laan (1): + Break circular dependency main ↔ txdb + +face (2): + Pass CChainParams to DisconnectTip() + Explicitly pass CChainParams to ConnectBlock + +Benjamin Winston (1): + Fixes #4013, added BitcoinABC as a disclosure partner + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.7-1.md b/depend/zcash/doc/release-notes/release-notes-2.0.7-1.md new file mode 100644 index 000000000..997d4b9f4 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.7-1.md @@ -0,0 +1,38 @@ +Notable changes +=============== + +Testnet Blossom Rewind +---------------------- +Testnet users needed to upgrade to 2.0.7 before Blossom activated. The amount +of notice given to these users was brief, so many were not able to upgrade in +time. These users may now be on the wrong branch. v2.0.7-1 adds an "intended +rewind" to prevent having to manually reindex when reconnecting to the correct +chain. + + +Insight Explorer Logging Fix +---------------------------- +Fixed an issue where `ERROR: spent index not enabled` would be logged unnecessarily. + +Changelog +========= + +Alex Tsankov (2): + Update INSTALL + Typo Fix + +Daira Hopwood (1): + Add intended rewind for Blossom on testnet. + +Eirik Ogilvie-Wigley (6): + Notable changes for v2.0.7-1 + fix typo + Add note about logging fix + Better wording in release notes + make-release.py: Versioning changes for 2.0.7-1. + make-release.py: Updated manpages for 2.0.7-1. + +Larry Ruane (2): + #4114 don't call error() from GetSpentIndex() + better fix: make GetSpentIndex() consistent with others... + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.7-2.md b/depend/zcash/doc/release-notes/release-notes-2.0.7-2.md new file mode 100644 index 000000000..f135ad733 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.7-2.md @@ -0,0 +1,30 @@ +Notable changes +=============== + + +Pre-Blossom EOS Halt +-------------------- +v2.0.7-2 contains a shortened EOS halt so that is in alignment with v2.0.7. + + +Testnet Blossom Rewind +---------------------- +Testnet users needed to upgrade to 2.0.7 before Blossom activated. The amount +of notice given to these users was brief, so many were not able to upgrade in +time. These users may now be on the wrong branch. v2.0.7-2 adds an "intended +rewind" to prevent having to manually reindex when reconnecting to the correct +chain. + + +Insight Explorer Logging Fix +---------------------------- +Fixed an issue where `ERROR: spent index not enabled` would be logged unnecessarily. + +Changelog +========= + +Eirik Ogilvie-Wigley (3): + Notable changes for v2.0.7-2 + make-release.py: Versioning changes for 2.0.7-2. + make-release.py: Updated manpages for 2.0.7-2. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.7-3.md b/depend/zcash/doc/release-notes/release-notes-2.0.7-3.md new file mode 100644 index 000000000..baf7cac15 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.7-3.md @@ -0,0 +1,35 @@ +Notable changes +=============== + +This release fixes a security issue described at +https://z.cash/support/security/announcements/security-announcement-2019-09-24/ . + +The service period of this release is shorter than normal due to the upcoming +v2.1.0 Blossom release. The End-of-Service of v2.0.7-3 will occur at block height +653012, expected to be on 2019-12-10. + + +Shrinking of debug.log files is temporarily disabled +---------------------------------------------------- + +In previous versions, `zcashd` would shrink the `debug.log` file to 200 KB on +startup if it was larger than 10 MB. This behaviour, and the `-shrinkdebugfile` +option that controlled it, has been disabled. + +Changelog +========= + +Daira Hopwood (4): + Add hotfix release notes. + Make a note of the shorter service period in the release notes. + make-release.py: Versioning changes for 2.0.7-3. + make-release.py: Updated manpages for 2.0.7-3. + +Jack Grigg (6): + Disable -shrinkdebugfile command + SetMerkleBranch: remove unused code, remove cs_main lock requirement + Remove cs_main lock requirement from CWallet::SyncTransaction + Ignore exceptions when deserializing note plaintexts + Move mempool SyncWithWallets call into its own thread + Enable RPC tests to wait on mempool notifications + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.7-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.0.7-rc1.md new file mode 100644 index 000000000..ab448862a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.7-rc1.md @@ -0,0 +1,118 @@ +Changelog +========= + +Daira Hopwood (10): + Add MIT license to Makefiles + Add MIT license to build-aux/m4/bitcoin_* scripts, and a permissive license to build-aux/m4/l_atomic.m4 . + Update copyright information for Zcash, leveldb, and libsnark. + Add license information for Autoconf macros. refs #2827 + Update contrib/debian/copyright for ax_boost_thread.m4 + Replace http with https: in links to the MIT license. Also change MIT/X11 to just MIT, since no distinction was intended. + qa/zcash/checksec.sh is under a BSD license, with a specialized non-endorsement clause. + Link to ticket #2827 using URL + Release process doc: add step to set the gpg key id. + Release process doc: mention the commit message. + +Dimitris Apostolou (5): + Rename vjoinsplit to vJoinSplit + Fix naming inconsistency + Rename joinsplit to shielded + Rename FindWalletTx to FindWalletTxToZap + Fix RPC undefined behavior. + +Eirik Ogilvie-Wigley (47): + Make nextHeight required in CalculateNextWorkRequired + Fix nondeterministic failure in sapling migration test + Clean up and fix typo + Apply suggestions from code review + Shorter block times rpc test + Update pow_tests for shorter block times + Update test_pow for shorter block times + Update block subsidy halving for zip208 + Make NetworkUpgradeAvailable a method of Params + Temporarily disable test + Simplify PartitionCheck + Use static_assert + Add missing new line at end of file + pow test cleanup + Add message to static_assert + Update expiry height for shorter block times + Fix zip208 founders reward calculation and update test + PartitionCheck tests for shorter block times + Add test for Blossom default tx expiry delta + Update metrics block height estimation for shorter block times + Do not create transactions that will expire after the next epoch + Do not send migration transactions that would expire after a network upgrade + Fix integer truncation in Blossom halving calculation + Update main_tests for shorter block times + Use pre-Blossom max FR height when calculating address change interval + Make founders reward tests pass before and after Blossom activation height is set + Extract Halvings method and add tests + Add comments and fix typos + Improve EstimateNetHeight calculation + Fix check transaction tests + Make sure to deactivate blossom in test case + Fix parsing txexpirydelta argument + Do not add expiring soon threshold to expiry height of txs near NU activation + Fix/update comments + Make sure that expiry height is not less than height + Clarify documentation + Update PoW related assertions + Remove DefaultExpiryDelta method + Algebraic improvements related to halving + Distinguish between height and current header height on metrics screen + Test clean up and fixes + Add copyright info + NPE defense in metrics screen + Do not estimate height if there is no best header + Rename method and use int64_t + make-release.py: Versioning changes for 2.0.7-rc1. + make-release.py: Updated manpages for 2.0.7-rc1. + +Eirik Ogilvie-Wigley (8): + Use CommitTransaction() rather than sendrawtransaction() + Move reused async rpc send logic to separate file + Move reused sign and send logic + Do not shadow the return value when testmode is true + Inline sign_send_raw_transaction + Allow passing optional reserve key as a parameter to SendTransaction + Use reserve key for transparent change when sending to Sapling + Fix comment in mergetoaddress RPC test + +Jack Grigg (4): + test: Check for change t-addr reuse in z_sendmany + Use reserve key for transparent change when sending to Sprout + test: Fix permissions on wallet_changeaddresses RPC test + test: Fix pyflakes warnings + +Larry Ruane (6): + add addressindex related RPCs + add spentindex RPC for bitcore block explorer + add timestampindex related RPC getblockhashes + fix getblockdeltas documentation formatting + insightexplorer minor bug fixes + insightexplorer fix LogPrintf + +Luke Dashjr (2): + Add MIT license to autogen.sh and share/genbuild.sh + Trivial: build-aux/m4/l_atomic: Fix typo + +Simon Liu (8): + Redefine PoW functions to accept height parameter. + Remove use of redundant member nPowTargetSpacing. + Replace nPoWTargetSpacing -> PoWTargetSpacing() + Update PoW function calls to pass in height. + Update GetBlockTimeout() to take height parameter. + Replace nPoWTargetSpacing -> PoWTargetSpacing() in ProcessMessage() + Replace nPoWTargetSpacing -> PoWTargetSpacing() in tests + Modify PartitionCheck to be aware of pre & post Blossom target spacing. + +William M Peaster (1): + Handful of copyedits to README.md + +codetriage-readme-bot (1): + Link to development guidelines in CONTRIBUTING.md + +Jack Grigg (1): + Update README.md + diff --git a/depend/zcash/doc/release-notes/release-notes-2.0.7.md b/depend/zcash/doc/release-notes/release-notes-2.0.7.md new file mode 100644 index 000000000..6c5e8bc9d --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.0.7.md @@ -0,0 +1,149 @@ +Notable changes +=============== + +Shorter Block Times +------------------- +Shorter block times are coming to Zcash! In the v2.0.7 release we have implemented [ZIP208](https://github.com/zcash/zips/blob/master/zip-0208.rst) which will take effect when Blossom activates. Upon activation, the block times for Zcash will decrease from 150 seconds to 75 seconds, and the block reward will decrease accordingly. This affects at what block height halving events will occur, but should not affect the overall rate at which Zcash is mined. The total founders' reward stays the same, and the total supply of Zcash is decreased only microscopically due to rounding. + +Blossom Activation on Testnet +----------------------------- +The v2.0.7 release includes Blossom activation on testnet, bringing shorter block times. The testnet Blossom activation height is 584000. + +Insight Explorer +---------------- +Changes needed for the Insight explorer have been incorporated into Zcash. *This is an experimental feature* and therefore is subject to change. To enable, add the `experimentalfeatures=1`, `txindex=1`, and `insightexplorer=1` flags to `zcash.conf`. This feature adds several RPCs to `zcashd` which allow the user to run an Insight explorer. + +Changelog +========= + +Daira Hopwood (11): + Add MIT license to Makefiles + Add MIT license to build-aux/m4/bitcoin_* scripts, and a permissive license to build-aux/m4/l_atomic.m4 . + Update copyright information for Zcash, leveldb, and libsnark. + Add license information for Autoconf macros. refs #2827 + Update contrib/debian/copyright for ax_boost_thread.m4 + Replace http with https: in links to the MIT license. Also change MIT/X11 to just MIT, since no distinction was intended. + qa/zcash/checksec.sh is under a BSD license, with a specialized non-endorsement clause. + Link to ticket #2827 using URL + Release process doc: add step to set the gpg key id. + Release process doc: mention the commit message. + Add RPC test and test framework constants for Sapling->Blossom activation. + +Dimitris Apostolou (5): + Rename vjoinsplit to vJoinSplit + Fix naming inconsistency + Rename joinsplit to shielded + Rename FindWalletTx to FindWalletTxToZap + Fix RPC undefined behavior. + +Eirik Ogilvie-Wigley (56): + Make nextHeight required in CalculateNextWorkRequired + Fix nondeterministic failure in sapling migration test + Clean up and fix typo + Apply suggestions from code review + Shorter block times rpc test + Update pow_tests for shorter block times + Update test_pow for shorter block times + Update block subsidy halving for zip208 + Make NetworkUpgradeAvailable a method of Params + Temporarily disable test + Simplify PartitionCheck + Use static_assert + Add missing new line at end of file + pow test cleanup + Add message to static_assert + Update expiry height for shorter block times + Fix zip208 founders reward calculation and update test + PartitionCheck tests for shorter block times + Add test for Blossom default tx expiry delta + Update metrics block height estimation for shorter block times + Do not create transactions that will expire after the next epoch + Do not send migration transactions that would expire after a network upgrade + Fix integer truncation in Blossom halving calculation + Update main_tests for shorter block times + Use pre-Blossom max FR height when calculating address change interval + Make founders reward tests pass before and after Blossom activation height is set + Extract Halvings method and add tests + Add comments and fix typos + Improve EstimateNetHeight calculation + Fix check transaction tests + Make sure to deactivate blossom in test case + Fix parsing txexpirydelta argument + Do not add expiring soon threshold to expiry height of txs near NU activation + Fix/update comments + Make sure that expiry height is not less than height + Clarify documentation + Update PoW related assertions + Remove DefaultExpiryDelta method + Algebraic improvements related to halving + Distinguish between height and current header height on metrics screen + Test clean up and fixes + Add copyright info + NPE defense in metrics screen + Do not estimate height if there is no best header + Rename method and use int64_t + make-release.py: Versioning changes for 2.0.7-rc1. + make-release.py: Updated manpages for 2.0.7-rc1. + make-release.py: Updated release notes and changelog for 2.0.7-rc1. + Update download path + Set testnet Blossom activation height + Notable changes for v2.0.7 + Enable shorter block times rpc test + Grammatical fixes and improvements + Remove constant + make-release.py: Versioning changes for 2.0.7. + make-release.py: Updated manpages for 2.0.7. + +Eirik Ogilvie-Wigley (8): + Use CommitTransaction() rather than sendrawtransaction() + Move reused async rpc send logic to separate file + Move reused sign and send logic + Do not shadow the return value when testmode is true + Inline sign_send_raw_transaction + Allow passing optional reserve key as a parameter to SendTransaction + Use reserve key for transparent change when sending to Sapling + Fix comment in mergetoaddress RPC test + +Jack Grigg (5): + test: Check for change t-addr reuse in z_sendmany + Use reserve key for transparent change when sending to Sprout + test: Fix permissions on wallet_changeaddresses RPC test + test: Fix pyflakes warnings + test: Fix AuthServiceProxy closed conn detection + +Larry Ruane (6): + add addressindex related RPCs + add spentindex RPC for bitcore block explorer + add timestampindex related RPC getblockhashes + fix getblockdeltas documentation formatting + insightexplorer minor bug fixes + insightexplorer fix LogPrintf + +Luke Dashjr (2): + Add MIT license to autogen.sh and share/genbuild.sh + Trivial: build-aux/m4/l_atomic: Fix typo + +Simon Liu (8): + Redefine PoW functions to accept height parameter. + Remove use of redundant member nPowTargetSpacing. + Replace nPoWTargetSpacing -> PoWTargetSpacing() + Update PoW function calls to pass in height. + Update GetBlockTimeout() to take height parameter. + Replace nPoWTargetSpacing -> PoWTargetSpacing() in ProcessMessage() + Replace nPoWTargetSpacing -> PoWTargetSpacing() in tests + Modify PartitionCheck to be aware of pre & post Blossom target spacing. + +William M Peaster (1): + Handful of copyedits to README.md + +codetriage-readme-bot (1): + Link to development guidelines in CONTRIBUTING.md + +Jack Grigg (1): + Update README.md + +Benjamin Winston (3): + Updated location to new download server + Fixes 4097, improves caching on parameter downloads + Updated location to new download server, fixing #4100 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.0-1.md b/depend/zcash/doc/release-notes/release-notes-2.1.0-1.md new file mode 100644 index 000000000..21b08f168 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.0-1.md @@ -0,0 +1,10 @@ +Changelog +========= + +Jack Grigg (2): + make-release.py: Versioning changes for 2.1.0-1. + make-release.py: Updated manpages for 2.1.0-1. + +Sean Bowe (1): + Fix of CVE-2017-18350 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.1.0-rc1.md new file mode 100644 index 000000000..e11a6c09c --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.0-rc1.md @@ -0,0 +1,177 @@ +Notable changes +=============== + +DoS Mitigation: Mempool Size Limit and Random Drop +-------------------------------------------------- + +This release adds a mechanism for preventing nodes from running out of memory +in the situation where an attacker is trying to overwhelm the network with +transactions. This is achieved by keeping track of and limiting the total +`cost` and `evictionWeight` of all transactions in the mempool. The `cost` of a +transaction is determined by its size in bytes, and its `evictionWeight` is a +function of the transaction's `cost` and its fee. The maximum total cost is +configurable via the parameter `mempooltxcostlimit` which defaults to +80,000,000 (up to 20,000 txs). If a node's total mempool `cost` exceeds this +limit the node will evict a random transaction, preferentially picking larger +transactions and ones with below the standard fee. To prevent a node from +re-accepting evicted transactions, it keeps track of ones that it has evicted +recently. By default, a transaction will be considered recently evicted for 60 +minutes, but this can be configured with the parameter +`mempoolevictionmemoryminutes`. + +For full details see ZIP 401. + +Fake chain detection during initial block download +-------------------------------------------------- + +One of the mechanisms that `zcashd` uses to detect whether it is in "initial +block download" (IBD) mode is to compare the active chain's cumulative work +against a hard-coded "minimum chain work" value. This mechanism (inherited from +Bitcoin Core) means that once a node exits IBD mode, it is either on the main +chain, or a fake alternate chain with similar amounts of work. In the latter +case, the node has most likely become the victim of a 50% + 1 adversary. + +Starting from this release, `zcashd` additionally hard-codes the block hashes +for the activation blocks of each past network upgrade (NU). During initial +chain synchronization, and after the active chain has reached "minimum chain +work", the node checks the blocks at each NU activation height against the +hard-coded hashes. If any of them do not match, the node will immediately alert +the user and **shut down for safety**. + +Disabling old Sprout proofs +--------------------------- + +As part of our ongoing work to clean up the codebase and minimise the security +surface of `zcashd`, we are removing `libsnark` from the codebase, and dropping +support for creating and verifying old Sprout proofs. Funds stored in Sprout +addresses are not affected, as they are spent using the hybrid Sprout circuit +(built using `bellman`) that was deployed during the Sapling network upgrade. + +This change has several implications: + +- `zcashd` no longer verifies old Sprout proofs, and will instead assume they + are valid. This has a minor implication for nodes: during initial block + download, an adversary could feed the node fake blocks containing invalid old + Sprout proofs, and the node would accept the fake chain as valid. However, + as soon as the active chain contains at least as much work as the hard-coded + "minimum chain work" value, the node will detect this situation and shut down. + +- Shielded transactions can no longer be created before Sapling has activated. + This does not affect Zcash itself, but will affect downstream codebases that + have not yet activated Sapling (or that start a new chain after this point and + do not activate Sapling from launch). Note that the old Sprout circuit is + [vulnerable to counterfeiting](https://z.cash/support/security/announcements/security-announcement-2019-02-05-cve-2019-7167/) + and should not be used in current deployments. + +- Starting from this release, the circuit parameters from the original Sprout + MPC are no longer required to start `zcashd`, and will not be downloaded by + `fetch-params.sh`. They are not being automatically deleted at this time. + +We would like to take a moment to thank the `libsnark` authors and contributors. +It was vital to the success of Zcash, and the development of zero-knowledge +proofs in general, to have this code available and usable. + +Changelog +========= + +Bryant Eisenbach (2): + doc: Change Debian package description + doc: Move text prior to "This package provides..." + +Daira Hopwood (4): + Remove copyright entries for Autoconf macros that have been deleted. + Remove copyright entry for libsnark. + Test setting an expiry height of 0. + Fix setting an expiry height of 0. fixes #4132 + +Eirik Ogilvie-Wigley (33): + Wrap metrics message in strprintf + DoS protection: Weighted random drop of txs if mempool full + Rebuild weighted list on removal and fix size calculation + Grammatical fixes + Remove transactions when ensuring size limit + Help message cleanup and add lock + Performance: Store weighted transactions in a tree + Fix naming conventions + No need to activate Overwinter/Sapling in rpc test + Fix recently evicted list size + Put size increment and decrement on their own lines + Prevent adding duplicate transactions + Move duplicate macro to reusable location + mempool_limit rpc test cleanup + Represent tx costs as signed integers + Fix comments + Rename variables for consistency + Use tx cost rather than evictionWeight when checking mempool capacity + Log rather than return error if a transaction is recently evicted + Represent recently evicted list as a deque + Rename files + Update release notes + Add test + minor rpc test clean up + Add explanatory comments + Wording and grammatical fixes + Update parameter names to match ZIP + Clarify the difference between cost and evictionWeight + Fix test cases: default mempool limiters + Remove dots and underscores from parameter names + Use same type when calling max + make-release.py: Versioning changes for 2.1.0-rc1. + make-release.py: Updated manpages for 2.1.0-rc1. + +Gareth Davies (1): + Updating IPFS link for chunking + +Jack Grigg (39): + depends: Add FreeBSD to hosts and builders + depends: Explicitly set Boost toolchain during configuration + depends: Add FreeBSD support to OpenSSL + depends: Patch libevent to detect arch4random_addrandom + depends: Add FreeBSD Rust binaries + depends: Explicitly call Rust install script using bash + depends: Use project-config.jam to configure Boost instead of user-config.jam + depends: Set PIC flags for FreeBSD + Always skip verification for old Sprout proofs + Remove ability to create non-Groth16 Sprout JSDescriptions + Use Sapling JSDescriptions in Boost tests + Remove non-Groth16 Sprout proofs from joinsplit gtests + Migrate test utilities to generate Sapling-type Sprout proofs + Use Sapling JSDescriptions in gtests + Revert "Allow user to ask server to save the Sprout R1CS out during startup." + Remove libsnark code for pre-Sapling Sprout proofs + Remove pre-Sapling Sprout circuit + Revert "configure: Guess -march for libsnark OPTFLAGS instead of hard-coding" + Revert "Check if OpenMP is available before using it" + Remove libsnark from build system + Remove libsnark + Remove libgmp + Remove libsnark unit tests from full test suite + test: Require minimum of Sapling for all RPC tests + test: Add Sapling v4 transactions to mininode framework + test: Add hashFinalSaplingProxy to create_block + test: Update RPC tests to use a minimum of Sapling + rpc: Use Sapling transactions in zc_raw_joinsplit + depends: Fix crate vendoring path + depends: Helper for vendoring new crates + depends: Add flag for building with a local librustzcash repo + tests: Clean up use of repr() in mininode + Remove makeGrothProof argument from JoinSplit::prove + Stop fetching old Sprout parameters + Add libsnark removal to notable changes + Move AbortNode to the top of main.cpp + Abort node if NU activations have unexpected hashes + Add block hashes for Overwinter, Sapling, and testnet Blossom + Update release notes with node abort behaviour + +Larry Ruane (4): + insightexplorer: formatting, pyflakes cleanups + precompute empty merkle roots + update unit tests to compute empty roots + access array element using at() + +jeff-liang (1): + Display which network the node is running on. + +Benjamin Winston (1): + Removed stale seeder, fixing #4153 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.0.md b/depend/zcash/doc/release-notes/release-notes-2.1.0.md new file mode 100644 index 000000000..a34305b17 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.0.md @@ -0,0 +1,215 @@ +Notable changes +=============== + +Blossom network upgrade +----------------------- + +The mainnet activation of the Blossom network upgrade is supported by this +release, with an activation height of 653600, which should occur in early +December — roughly one day following the targeted EOS halt of our 2.0.7-3 +release. Please upgrade to this release, or any subsequent release, in order to +follow the Blossom network upgrade. + +The Blossom network upgrade implements +[ZIP208](https://github.com/zcash/zips/blob/master/zip-0208.rst) which shortens +block times from 150s to 75s. + +DoS Mitigation: Mempool Size Limit and Random Drop +-------------------------------------------------- + +This release adds a mechanism for preventing nodes from running out of memory +in the situation where an attacker is trying to overwhelm the network with +transactions. This is achieved by keeping track of and limiting the total +`cost` and `evictionWeight` of all transactions in the mempool. The `cost` of a +transaction is determined by its size in bytes, and its `evictionWeight` is a +function of the transaction's `cost` and its fee. The maximum total cost is +configurable via the parameter `mempooltxcostlimit` which defaults to +80,000,000 (up to 20,000 txs). If a node's total mempool `cost` exceeds this +limit the node will evict a random transaction, preferentially picking larger +transactions and ones with below the standard fee. To prevent a node from +re-accepting evicted transactions, it keeps track of ones that it has evicted +recently. By default, a transaction will be considered recently evicted for 60 +minutes, but this can be configured with the parameter +`mempoolevictionmemoryminutes`. + +For full details see ZIP 401. + +Asynchronous Operations Incorrectly Reporting Success +----------------------------------------------------- +We fixed an issue where asynchronous operations were sometimes reporting sucess +when they had actually failed. One way this could occur was when trying to use +`z_sendmany` to create a transaction spending coinbase funds in a way where +change would be generated (not a valid use of `z_sendmany`). In this case the +operation would erroneously report success, and the only way to see that the +transaction had actually failed was to look in the `debug.log` file. Such +operations will now correctly report that they have failed. + +Fake chain detection during initial block download +-------------------------------------------------- + +One of the mechanisms that `zcashd` uses to detect whether it is in "initial +block download" (IBD) mode is to compare the active chain's cumulative work +against a hard-coded "minimum chain work" value. This mechanism (inherited from +Bitcoin Core) means that once a node exits IBD mode, it is either on the main +chain, or a fake alternate chain with similar amounts of work. In the latter +case, the node has most likely become the victim of a 50% + 1 adversary. + +Starting from this release, `zcashd` additionally hard-codes the block hashes +for the activation blocks of each past network upgrade (NU). During initial +chain synchronization, and after the active chain has reached "minimum chain +work", the node checks the blocks at each NU activation height against the +hard-coded hashes. If any of them do not match, the node will immediately alert +the user and **shut down for safety**. + +Disabling old Sprout proofs +--------------------------- + +As part of our ongoing work to clean up the codebase and minimise the security +surface of `zcashd`, we are removing `libsnark` from the codebase, and dropping +support for creating and verifying old Sprout proofs. Funds stored in Sprout +addresses are not affected, as they are spent using the hybrid Sprout circuit +(built using `bellman`) that was deployed during the Sapling network upgrade. + +This change has several implications: + +- `zcashd` no longer verifies old Sprout proofs, and will instead assume they + are valid. This has a minor implication for nodes: during initial block + download, an adversary could feed the node fake blocks containing invalid old + Sprout proofs, and the node would accept the fake chain as valid. However, + as soon as the active chain contains at least as much work as the hard-coded + "minimum chain work" value, the node will detect this situation and shut down. + +- Shielded transactions can no longer be created before Sapling has activated. + This does not affect Zcash itself, but will affect downstream codebases that + have not yet activated Sapling (or that start a new chain after this point and + do not activate Sapling from launch). Note that the old Sprout circuit is + [vulnerable to counterfeiting](https://z.cash/support/security/announcements/security-announcement-2019-02-05-cve-2019-7167/) + and should not be used in current deployments. + +- Starting from this release, the circuit parameters from the original Sprout + MPC are no longer required to start `zcashd`, and will not be downloaded by + `fetch-params.sh`. They are not being automatically deleted at this time. + +We would like to take a moment to thank the `libsnark` authors and contributors. +It was vital to the success of Zcash, and the development of zero-knowledge +proofs in general, to have this code available and usable. + +Changelog +========= + +Bryant Eisenbach (2): + doc: Change Debian package description + doc: Move text prior to "This package provides..." + +Daira Hopwood (4): + Remove copyright entries for Autoconf macros that have been deleted. + Remove copyright entry for libsnark. + Test setting an expiry height of 0. + Fix setting an expiry height of 0. fixes #4132 + +Dimitris Apostolou (1): + depends macOS: point --sysroot to SDK + +Eirik Ogilvie-Wigley (41): + Wrap metrics message in strprintf + DoS protection: Weighted random drop of txs if mempool full + Rebuild weighted list on removal and fix size calculation + Grammatical fixes + Remove transactions when ensuring size limit + Help message cleanup and add lock + Performance: Store weighted transactions in a tree + Fix naming conventions + No need to activate Overwinter/Sapling in rpc test + Fix recently evicted list size + Put size increment and decrement on their own lines + Prevent adding duplicate transactions + Move duplicate macro to reusable location + mempool_limit rpc test cleanup + Represent tx costs as signed integers + Fix comments + Rename variables for consistency + Use tx cost rather than evictionWeight when checking mempool capacity + Log rather than return error if a transaction is recently evicted + Represent recently evicted list as a deque + Rename files + Update release notes + Add test + minor rpc test clean up + Add explanatory comments + Wording and grammatical fixes + Update parameter names to match ZIP + Clarify the difference between cost and evictionWeight + Fix test cases: default mempool limiters + Remove dots and underscores from parameter names + Use same type when calling max + make-release.py: Versioning changes for 2.1.0-rc1. + make-release.py: Updated manpages for 2.1.0-rc1. + make-release.py: Updated release notes and changelog for 2.1.0-rc1. + Release notes for bug fix + Better wording in release notes + Fix wording + Fix getblocksubsidy tests + fix comment + make-release.py: Versioning changes for 2.1.0. + make-release.py: Updated manpages for 2.1.0. + +Gareth Davies (1): + Updating IPFS link for chunking + +Jack Grigg (39): + depends: Add FreeBSD to hosts and builders + depends: Explicitly set Boost toolchain during configuration + depends: Add FreeBSD support to OpenSSL + depends: Patch libevent to detect arch4random_addrandom + depends: Add FreeBSD Rust binaries + depends: Explicitly call Rust install script using bash + depends: Use project-config.jam to configure Boost instead of user-config.jam + depends: Set PIC flags for FreeBSD + Always skip verification for old Sprout proofs + Remove ability to create non-Groth16 Sprout JSDescriptions + Use Sapling JSDescriptions in Boost tests + Remove non-Groth16 Sprout proofs from joinsplit gtests + Migrate test utilities to generate Sapling-type Sprout proofs + Use Sapling JSDescriptions in gtests + Revert "Allow user to ask server to save the Sprout R1CS out during startup." + Remove libsnark code for pre-Sapling Sprout proofs + Remove pre-Sapling Sprout circuit + Revert "configure: Guess -march for libsnark OPTFLAGS instead of hard-coding" + Revert "Check if OpenMP is available before using it" + Remove libsnark from build system + Remove libsnark + Remove libgmp + Remove libsnark unit tests from full test suite + test: Require minimum of Sapling for all RPC tests + test: Add Sapling v4 transactions to mininode framework + test: Add hashFinalSaplingProxy to create_block + test: Update RPC tests to use a minimum of Sapling + rpc: Use Sapling transactions in zc_raw_joinsplit + depends: Fix crate vendoring path + depends: Helper for vendoring new crates + depends: Add flag for building with a local librustzcash repo + tests: Clean up use of repr() in mininode + Remove makeGrothProof argument from JoinSplit::prove + Stop fetching old Sprout parameters + Add libsnark removal to notable changes + Move AbortNode to the top of main.cpp + Abort node if NU activations have unexpected hashes + Add block hashes for Overwinter, Sapling, and testnet Blossom + Update release notes with node abort behaviour + +Larry Ruane (5): + insightexplorer: formatting, pyflakes cleanups + precompute empty merkle roots + update unit tests to compute empty roots + access array element using at() + #4175 z_sendmany coinbase to zaddr with change: report error status + +Sean Bowe (1): + Set mainnet activation of Blossom + +jeff-liang (1): + Display which network the node is running on. + +Benjamin Winston (1): + Removed stale seeder, fixing #4153 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.1-1.md b/depend/zcash/doc/release-notes/release-notes-2.1.1-1.md new file mode 100644 index 000000000..5c764f24c --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.1-1.md @@ -0,0 +1,43 @@ +Notable changes +=============== + +This release fixes a security issue described at +https://z.cash/support/security/announcements/security-announcement-2020-02-06/ . + +This release also adds a `-maxtimeadjustment` option to set the maximum time, in +seconds, by which the node's clock can be adjusted based on the clocks of its +peer nodes. This option defaults to 0, meaning that no such adjustment is performed. +This is a change from the previous behaviour, which was to adjust the clock by up +to 70 minutes forward or backward. The maximum setting for this option is now +25 minutes (1500 seconds). + +Fix for incorrect banning of nodes during syncing +------------------------------------------------- +After activation of the Blossom network upgrade, a node that is syncing the +block chain from before Blossom would incorrectly ban peers that send it a +Blossom transaction. This resulted in slower and less reliable syncing (#4283). + +Changelog +========= + +Daira Hopwood (10): + Move check for block times that are too far ahead of adjusted time, to ContextualCheckBlock. + Improve messages for timestamp rules. + Add constant for how far a block timestamp can be ahead of adjusted time. Loosely based on https://github.com/bitcoin/bitcoin/commit/e57a1fd8999800b3fc744d45bb96354cae294032 + Soft fork: restrict block timestamps to be no more than 90 minutes after the MTP of the previous block. + Adjust the miner to satisfy consensus regarding future timestamps relative to median-time-past. + Enable future timestamp soft fork at varying heights according to network. + Cosmetic: brace style in ContextualCheckBlockHeader. + Add -maxtimeadjustment with default of 0 instead of the 4200 seconds used in Bitcoin Core. + Fix ContextualCheckBlock test (the ban score should be 100 since these are mined transactions). + Add string argument to static_asserts to satisfy C++11. + +Jack Grigg (2): + test: Update RPC test cache generation to handle new consensus rule + Apply a consistent ban policy within ContextualCheckTransaction + +Sean Bowe (3): + Release notes for vulnerability and -maxtimeadjustment option. + make-release.py: Versioning changes for 2.1.1-1. + make-release.py: Updated manpages for 2.1.1-1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.1-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.1.1-rc1.md new file mode 100644 index 000000000..9e286935b --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.1-rc1.md @@ -0,0 +1,288 @@ +Notable changes +=============== + +`z_mergetoaddress` promoted out of experimental status +------------------------------------------------------ + +The `z_mergetoaddress` API merges funds from t-addresses, z-addresses, or both, +and sends them to a single t-address or z-address. It was added in v1.0.15 as an +experimental feature, to simplify the process of combining many small UTXOs and +notes into a few larger ones. + +In this release we are promoting `z_mergetoaddress` out of experimental status. +It is now a stable RPC, and any future changes to it will only be additive. See +`zcash-cli help z_mergetoaddress` for API details and usage. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +Option parsing behavior +----------------------- + +Command line options are now parsed strictly in the order in which they are +specified. It used to be the case that `-X -noX` ends up, unintuitively, with X +set, as `-X` had precedence over `-noX`. This is no longer the case. Like for +other software, the last specified value for an option will hold. + +Low-level RPC changes +--------------------- + +- Bare multisig outputs to our keys are no longer automatically treated as + incoming payments. As this feature was only available for multisig outputs for + which you had all private keys in your wallet, there was generally no use for + them compared to single-key schemes. Furthermore, no address format for such + outputs is defined, and wallet software can't easily send to it. These outputs + will no longer show up in `listtransactions`, `listunspent`, or contribute to + your balance, unless they are explicitly watched (using `importaddress` or + `importmulti` with hex script argument). `signrawtransaction*` also still + works for them. + +Changelog +========= + +Alfredo Garcia (19): + remove duplicated prefix in errors and warnings + Consensus: Decouple pow.cpp from util.h + change some wallet functions from bool to void + limit blockchain progress to a max of 1.000000 + remove z_mergetoaddress from experimental + add version to thank you string + add next upgrade info to metrics console + change target spacing to up to upgrade height + create and use SecondsLeftToHeight to display next upgrade info + add NextUpgrade test case + fix spacing + add after blossom test + change var and function names for clarity, refactor function + reverse conditional, replace get_value_or(0) calls + remove redundant line from test + remove zmergetoaddress from experimental state in rpc-tests + get UPGRADE_TESTDUMMY back to default at the end of the test + remove dead code in init + readd create_directories + +Ben Woosley (1): + Assert CPubKey::ValidLength to the pubkey's header-relevent size + +Carl Dong (1): + depends: tar: Always extract as yourself + +Casey Rodarmor (1): + Give a better error message if system clock is bad + +Charlie O'Keefe (1): + Add check-depends step to STAGE_COMMANDS list + +Cory Fields (3): + depends: qt/cctools: fix checksum checksum tests + depends: bump OSX toolchain + depends: make osx output deterministic + +Dagur Valberg Johannsson (1): + Remove option mempooltxinputlimit + +Denis Lukianov (1): + Correct importaddress help reference to importpubkey + +Dimitris Apostolou (4): + Fix typo + Remove stale comment + Change "protect" terminology to "shield" + depends macOS: hide linker visibility warnings + +Eirik Ogilvie-Wigley (2): + Show time elapsed when running RPC tests + Update team email + +Gavin Andresen (1): + Unit test doublespends in new blocks + +Gregory Maxwell (1): + Make connect=0 disable automatic outbound connections. + +Gregory Sanders (1): + Added additional config option for multiple RPC users. + +Ian T (1): + Update RPC generate help for numblocks to include required + +Jack Grigg (32): + Upgrade librustzcash to 0.2.0 + Migrate to librustzcash 0.2.0 API + Remove invalid address comparison from gtest + Cast uint8* in InterruptibleRecv to char* for recv + Add Heartwood to upgrade list + Initialize experimental mode in a separate function + Fix benchmarks after removal of SelectParamsFromCommandLine() + Handle Equihash and optional miner code in TestChain100Setup + Add tests covering the current interaction of alerts with subver comments + Parameterize zcash.conf in init error message + cleanup: Comments + Wrap long line + Match alerts both with and without comments + pyflakes fixes + Revert "Remove insecurely-downloaded dependencies that we don't currently use." + depends: Compile bdb with --disable-atomics when cross-compiling darwin + depends: Add Rust targets for cross-compiling darwin + configure: Don't require RELRO and BIND_NOW when cross-compiling darwin + depends: Manually apply build_env to second half of googletest build + Revert "depends: Explicitly set Boost toolchain during configuration" + Add z_mergetoaddress to release notes + ThreadNotifyRecentlyAdded -> ThreadNotifyWallets + Move mempool tx notifying logic out of CTxMemPool + Merge tree and boolean fields in ChainTip API + Move block-notifying logic into ThreadNotifyWallets + Tie sync_blocks in RPC tests to notifier thread + Extend comment with reason for taking care with locks + test: Add sync_all points after block generation to RPC tests + test: Remove genesis-block Sapling activation from shorter_block_times + test: Reverse hashtx and hashblock ordering at start of ZMQ RPC test + test: Add missing sync_all point + test: Update wallet RPC test with change to "absurdly high fee" limit + +Jainan-Tandel (1): + Cosmetic update to README.md . + +Jim Posen (3): + Comments: More comments on functions/globals in standard.h. + [script] Unit tests for script/standard functions + [script] Unit tests for IsMine + +Jonas Schnelli (9): + [autoprune] allow wallet in pruned mode + [RPC] disable import functions in pruned mode + [squashme] improve/corrects prune mode detection test for required wallet rescans + Refactor parameter interaction, call it before AppInit2() + Initialize logging before we do parameter interaction + [Wallet] move wallet help string creation to CWallet + [Wallet] move "load wallet phase" to CWallet + [Wallet] optimize return value of InitLoadWallet() + [Wallet] refactor wallet/init interaction + +Jorge Timón (4): + Chainparams: Replace CBaseChainParams::Network enum with string constants (suggested by Wladimir) + Chainparams: Translations: DRY: options and error strings + Globals: Decouple GetConfigFile and ReadConfigFile from global mapArgs + Policy: MOVEONLY: Create policy/policy.h with some constants + +Larry Ruane (5): + simplify locking, merge cs_SpendingKeyStore into cs_KeyStore + eliminate races: hold cs_KeyStore lock while reading fUseCrypto + revert CCryptoKeyStore::SetCrypted() return value + insightexplorer: LOCK(cs_main) during rpcs + fix tests for enable-debug build + +Luke Dashjr (8): + Bugfix: RPC: blockchain: Display correct defaults in help for verifychain method + Bugfix: Describe dblogsize option correctly (it refers to the wallet database, not memory pool) + Bugfix: If genproclimit is omitted to RPC setgenerate, don't change it; also show correct default in getmininginfo + Bugfix: Omit wallet-related options from -help when wallet is disabled + Constrain constant values to a single location in code + Bugfix: Omit wallet-related options from -help when wallet is not supported + Policy: MOVEONLY: 3 functions to policy.o: + Common argument defaults for NODE_BLOOM stuff and -wallet + +Marco Falke (20): + [trivial] Reuse translation and cleanup DEFAULT_* values + [qt] Move GUI related HelpMessage() part downstream + [trivial] init cleanup + [wallet] Refactor to use new MIN_CHANGE + [wallet] Add comments for doxygen + Init: Use DEFAULT_TRANSACTION_MINFEE in help message + [qt] Properly display required fee instead of minTxFee + Clarify what minrelaytxfee does + translations: Don't translate markdown or force English grammar + transaction_tests: Be more strict checking dust + [trivial] init: Use defaults MIN_RELAY_TX_FEE & TRANSACTION_MAXFEE + contrib: Del. gitian downloader config and update gitian README + rpcwallet: Clarify what settxfee does + HelpMessage: Don't hide -mintxfee behind showDebug + mempool: Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee + [doxygen] Actually display comment + Fix doxygen comment for payTxFee + [doc] Fix markdown + Make sure LogPrintf strings are line-terminated + [wallet] Move hardcoded file name out of log messages + +Marshall Gaucher (3): + Update `import *` to unblock pyflakes from failing + Update z_sendmany calls passing int 0, instead of Decimal('0') + Update to stop random race error from assert + +Matt Corallo (10): + Also remove pay-2-pubkey from watch when adding a priv key + Split up importaddress into helper functions + Add p2sh option to importaddress to import redeemScripts + Add importpubkey method to import a watch-only pubkey + Update importaddress help to push its use to script-only + Add have-pubkey distinction to ISMINE flags + Add logic to track pubkeys as watch-only, not just scripts + Implement watchonly support in fundrawtransaction + SQUASH "Add have-pubkey distinction to ISMINE flags" + SQUASH "Implement watchonly support in fundrawtransaction" + +Peter Todd (3): + Make TX_SCRIPTHASH clear vSolutionsRet first + Add IsPushOnly(const_iterator pc) + Accept any sequence of PUSHDATAs in OP_RETURN outputs + +Pieter Wuille (9): + Remove template matching and pseudo opcodes + Stop treating importaddress'ed scripts as change + Make CScript -> CScriptID conversion explicit + Do not expose SigVersion argument to IsMine + Switch to a private version of SigVersion inside IsMine + Track difference between scriptPubKey and P2SH execution in IsMine + Do not treat bare multisig as IsMine + Mention removal of bare multisig IsMine in release notes + Use anonymous namespace instead of static functions + +Sean Bowe (2): + make-release.py: Versioning changes for 2.1.1-rc1. + make-release.py: Updated manpages for 2.1.1-rc1. + +Simon Liu (1): + Closes #3911. Fix help message of RPC getwalletinfo. + +Taylor Hornby (10): + Add AFL instrumentation scripts to zcutil. + Add configure option to replace main with a stub for fuzzing + Add all-in-one script for starting AFL fuzzing + Separate AFL build, run fuzz stages, and add afl argument pass-through + Have make clean delete fuzz.cpp + Pass AFL input file path to zcashd + Add fuzzing stub for AddrMan deserialization + Add fuzzing stub for ReadFeeEstimates + Add fuzzing stub for CheckBlock + Update proton from 0.26.0 to 0.30.0 + +Ulrich Kempken (1): + depends: switch to secure download of all dependencies + +Wladimir J. van der Laan (7): + make proxy_test work on servers without ipv6 + Fix argument parsing oddity with -noX + doc: mention change to option parsing behavior in release notes + test: move accounting_tests and rpc_wallet_tests to wallet/test + test: Create test fixture for wallet + wallet_ismine.h → script/ismine.h + test: Rename wallet.dat to wallet_test.dat + +sandakersmann (3): + Update of copyright year to 2020 + Update COPYRIGHT_YEAR in clientversion.h to 2020 + Update _COPYRIGHT_YEAR in configure.ac to 2020 + +Jack Grigg (2): + Apply suggestions from code review + Apply suggestions from code review + +Benjamin Winston (1): + Added basic fuzzing to the monolith, see ticket #4155 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.1-rc2.md b/depend/zcash/doc/release-notes/release-notes-2.1.1-rc2.md new file mode 100644 index 000000000..8d20d89d1 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.1-rc2.md @@ -0,0 +1,298 @@ +Notable changes +=============== + +`z_mergetoaddress` promoted out of experimental status +------------------------------------------------------ + +The `z_mergetoaddress` API merges funds from t-addresses, z-addresses, or both, +and sends them to a single t-address or z-address. It was added in v1.0.15 as an +experimental feature, to simplify the process of combining many small UTXOs and +notes into a few larger ones. + +In this release we are promoting `z_mergetoaddress` out of experimental status. +It is now a stable RPC, and any future changes to it will only be additive. See +`zcash-cli help z_mergetoaddress` for API details and usage. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +Option parsing behavior +----------------------- + +Command line options are now parsed strictly in the order in which they are +specified. It used to be the case that `-X -noX` ends up, unintuitively, with X +set, as `-X` had precedence over `-noX`. This is no longer the case. Like for +other software, the last specified value for an option will hold. + +Low-level RPC changes +--------------------- + +- Bare multisig outputs to our keys are no longer automatically treated as + incoming payments. As this feature was only available for multisig outputs for + which you had all private keys in your wallet, there was generally no use for + them compared to single-key schemes. Furthermore, no address format for such + outputs is defined, and wallet software can't easily send to it. These outputs + will no longer show up in `listtransactions`, `listunspent`, or contribute to + your balance, unless they are explicitly watched (using `importaddress` or + `importmulti` with hex script argument). `signrawtransaction*` also still + works for them. + +Changelog +========= + +Alfredo Garcia (19): + remove duplicated prefix in errors and warnings + Consensus: Decouple pow.cpp from util.h + change some wallet functions from bool to void + limit blockchain progress to a max of 1.000000 + remove z_mergetoaddress from experimental + add version to thank you string + add next upgrade info to metrics console + change target spacing to up to upgrade height + create and use SecondsLeftToHeight to display next upgrade info + add NextUpgrade test case + fix spacing + add after blossom test + change var and function names for clarity, refactor function + reverse conditional, replace get_value_or(0) calls + remove redundant line from test + remove zmergetoaddress from experimental state in rpc-tests + get UPGRADE_TESTDUMMY back to default at the end of the test + remove dead code in init + readd create_directories + +Ben Woosley (1): + Assert CPubKey::ValidLength to the pubkey's header-relevent size + +Carl Dong (1): + depends: tar: Always extract as yourself + +Casey Rodarmor (1): + Give a better error message if system clock is bad + +Charlie O'Keefe (1): + Add check-depends step to STAGE_COMMANDS list + +Cory Fields (3): + depends: qt/cctools: fix checksum checksum tests + depends: bump OSX toolchain + depends: make osx output deterministic + +Dagur Valberg Johannsson (1): + Remove option mempooltxinputlimit + +Daira Hopwood (1): + Remove temporary workaround for deprecation height. + +Denis Lukianov (1): + Correct importaddress help reference to importpubkey + +Dimitris Apostolou (4): + Fix typo + Remove stale comment + Change "protect" terminology to "shield" + depends macOS: hide linker visibility warnings + +Eirik Ogilvie-Wigley (2): + Show time elapsed when running RPC tests + Update team email + +Gavin Andresen (1): + Unit test doublespends in new blocks + +Gregory Maxwell (1): + Make connect=0 disable automatic outbound connections. + +Gregory Sanders (1): + Added additional config option for multiple RPC users. + +Ian T (1): + Update RPC generate help for numblocks to include required + +Jack Grigg (32): + Upgrade librustzcash to 0.2.0 + Migrate to librustzcash 0.2.0 API + Remove invalid address comparison from gtest + Cast uint8* in InterruptibleRecv to char* for recv + Add Heartwood to upgrade list + Initialize experimental mode in a separate function + Fix benchmarks after removal of SelectParamsFromCommandLine() + Handle Equihash and optional miner code in TestChain100Setup + Add tests covering the current interaction of alerts with subver comments + Parameterize zcash.conf in init error message + cleanup: Comments + Wrap long line + Match alerts both with and without comments + pyflakes fixes + Revert "Remove insecurely-downloaded dependencies that we don't currently use." + depends: Compile bdb with --disable-atomics when cross-compiling darwin + depends: Add Rust targets for cross-compiling darwin + configure: Don't require RELRO and BIND_NOW when cross-compiling darwin + depends: Manually apply build_env to second half of googletest build + Revert "depends: Explicitly set Boost toolchain during configuration" + Add z_mergetoaddress to release notes + ThreadNotifyRecentlyAdded -> ThreadNotifyWallets + Move mempool tx notifying logic out of CTxMemPool + Merge tree and boolean fields in ChainTip API + Move block-notifying logic into ThreadNotifyWallets + Tie sync_blocks in RPC tests to notifier thread + Extend comment with reason for taking care with locks + test: Add sync_all points after block generation to RPC tests + test: Remove genesis-block Sapling activation from shorter_block_times + test: Reverse hashtx and hashblock ordering at start of ZMQ RPC test + test: Add missing sync_all point + test: Update wallet RPC test with change to "absurdly high fee" limit + +Jainan-Tandel (1): + Cosmetic update to README.md . + +Jim Posen (3): + Comments: More comments on functions/globals in standard.h. + [script] Unit tests for script/standard functions + [script] Unit tests for IsMine + +Jonas Schnelli (9): + [autoprune] allow wallet in pruned mode + [RPC] disable import functions in pruned mode + [squashme] improve/corrects prune mode detection test for required wallet rescans + Refactor parameter interaction, call it before AppInit2() + Initialize logging before we do parameter interaction + [Wallet] move wallet help string creation to CWallet + [Wallet] move "load wallet phase" to CWallet + [Wallet] optimize return value of InitLoadWallet() + [Wallet] refactor wallet/init interaction + +Jorge Timón (4): + Chainparams: Replace CBaseChainParams::Network enum with string constants (suggested by Wladimir) + Chainparams: Translations: DRY: options and error strings + Globals: Decouple GetConfigFile and ReadConfigFile from global mapArgs + Policy: MOVEONLY: Create policy/policy.h with some constants + +Larry Ruane (5): + simplify locking, merge cs_SpendingKeyStore into cs_KeyStore + eliminate races: hold cs_KeyStore lock while reading fUseCrypto + revert CCryptoKeyStore::SetCrypted() return value + insightexplorer: LOCK(cs_main) during rpcs + fix tests for enable-debug build + +Luke Dashjr (8): + Bugfix: RPC: blockchain: Display correct defaults in help for verifychain method + Bugfix: Describe dblogsize option correctly (it refers to the wallet database, not memory pool) + Bugfix: If genproclimit is omitted to RPC setgenerate, don't change it; also show correct default in getmininginfo + Bugfix: Omit wallet-related options from -help when wallet is disabled + Constrain constant values to a single location in code + Bugfix: Omit wallet-related options from -help when wallet is not supported + Policy: MOVEONLY: 3 functions to policy.o: + Common argument defaults for NODE_BLOOM stuff and -wallet + +Marco Falke (20): + [trivial] Reuse translation and cleanup DEFAULT_* values + [qt] Move GUI related HelpMessage() part downstream + [trivial] init cleanup + [wallet] Refactor to use new MIN_CHANGE + [wallet] Add comments for doxygen + Init: Use DEFAULT_TRANSACTION_MINFEE in help message + [qt] Properly display required fee instead of minTxFee + Clarify what minrelaytxfee does + translations: Don't translate markdown or force English grammar + transaction_tests: Be more strict checking dust + [trivial] init: Use defaults MIN_RELAY_TX_FEE & TRANSACTION_MAXFEE + contrib: Del. gitian downloader config and update gitian README + rpcwallet: Clarify what settxfee does + HelpMessage: Don't hide -mintxfee behind showDebug + mempool: Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee + [doxygen] Actually display comment + Fix doxygen comment for payTxFee + [doc] Fix markdown + Make sure LogPrintf strings are line-terminated + [wallet] Move hardcoded file name out of log messages + +Marshall Gaucher (3): + Update `import *` to unblock pyflakes from failing + Update z_sendmany calls passing int 0, instead of Decimal('0') + Update to stop random race error from assert + +Matt Corallo (10): + Also remove pay-2-pubkey from watch when adding a priv key + Split up importaddress into helper functions + Add p2sh option to importaddress to import redeemScripts + Add importpubkey method to import a watch-only pubkey + Update importaddress help to push its use to script-only + Add have-pubkey distinction to ISMINE flags + Add logic to track pubkeys as watch-only, not just scripts + Implement watchonly support in fundrawtransaction + SQUASH "Add have-pubkey distinction to ISMINE flags" + SQUASH "Implement watchonly support in fundrawtransaction" + +Miles Manley (1): + Update libsodium download-path + +Peter Todd (3): + Make TX_SCRIPTHASH clear vSolutionsRet first + Add IsPushOnly(const_iterator pc) + Accept any sequence of PUSHDATAs in OP_RETURN outputs + +Pieter Wuille (9): + Remove template matching and pseudo opcodes + Stop treating importaddress'ed scripts as change + Make CScript -> CScriptID conversion explicit + Do not expose SigVersion argument to IsMine + Switch to a private version of SigVersion inside IsMine + Track difference between scriptPubKey and P2SH execution in IsMine + Do not treat bare multisig as IsMine + Mention removal of bare multisig IsMine in release notes + Use anonymous namespace instead of static functions + +Sean Bowe (5): + make-release.py: Versioning changes for 2.1.1-rc1. + make-release.py: Updated manpages for 2.1.1-rc1. + make-release.py: Updated release notes and changelog for 2.1.1-rc1. + make-release.py: Versioning changes for 2.1.1-rc2. + make-release.py: Updated manpages for 2.1.1-rc2. + +Simon Liu (1): + Closes #3911. Fix help message of RPC getwalletinfo. + +Taylor Hornby (11): + Add AFL instrumentation scripts to zcutil. + Add configure option to replace main with a stub for fuzzing + Add all-in-one script for starting AFL fuzzing + Separate AFL build, run fuzz stages, and add afl argument pass-through + Have make clean delete fuzz.cpp + Pass AFL input file path to zcashd + Add fuzzing stub for AddrMan deserialization + Add fuzzing stub for ReadFeeEstimates + Add fuzzing stub for CheckBlock + Update proton from 0.26.0 to 0.30.0 + Fix broken proton build + +Ulrich Kempken (1): + depends: switch to secure download of all dependencies + +Wladimir J. van der Laan (7): + make proxy_test work on servers without ipv6 + Fix argument parsing oddity with -noX + doc: mention change to option parsing behavior in release notes + test: move accounting_tests and rpc_wallet_tests to wallet/test + test: Create test fixture for wallet + wallet_ismine.h → script/ismine.h + test: Rename wallet.dat to wallet_test.dat + +sandakersmann (3): + Update of copyright year to 2020 + Update COPYRIGHT_YEAR in clientversion.h to 2020 + Update _COPYRIGHT_YEAR in configure.ac to 2020 + +Jack Grigg (2): + Apply suggestions from code review + Apply suggestions from code review + +Benjamin Winston (1): + Added basic fuzzing to the monolith, see ticket #4155 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.1.md b/depend/zcash/doc/release-notes/release-notes-2.1.1.md new file mode 100644 index 000000000..a51e29399 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.1.md @@ -0,0 +1,301 @@ +Notable changes +=============== + +`z_mergetoaddress` promoted out of experimental status +------------------------------------------------------ + +The `z_mergetoaddress` API merges funds from t-addresses, z-addresses, or both, +and sends them to a single t-address or z-address. It was added in v1.0.15 as an +experimental feature, to simplify the process of combining many small UTXOs and +notes into a few larger ones. + +In this release we are promoting `z_mergetoaddress` out of experimental status. +It is now a stable RPC, and any future changes to it will only be additive. See +`zcash-cli help z_mergetoaddress` for API details and usage. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +Option parsing behavior +----------------------- + +Command line options are now parsed strictly in the order in which they are +specified. It used to be the case that `-X -noX` ends up, unintuitively, with X +set, as `-X` had precedence over `-noX`. This is no longer the case. Like for +other software, the last specified value for an option will hold. + +Low-level RPC changes +--------------------- + +- Bare multisig outputs to our keys are no longer automatically treated as + incoming payments. As this feature was only available for multisig outputs for + which you had all private keys in your wallet, there was generally no use for + them compared to single-key schemes. Furthermore, no address format for such + outputs is defined, and wallet software can't easily send to it. These outputs + will no longer show up in `listtransactions`, `listunspent`, or contribute to + your balance, unless they are explicitly watched (using `importaddress` or + `importmulti` with hex script argument). `signrawtransaction*` also still + works for them. + +Changelog +========= + +Alfredo Garcia (19): + remove duplicated prefix in errors and warnings + Consensus: Decouple pow.cpp from util.h + change some wallet functions from bool to void + limit blockchain progress to a max of 1.000000 + remove z_mergetoaddress from experimental + add version to thank you string + add next upgrade info to metrics console + change target spacing to up to upgrade height + create and use SecondsLeftToHeight to display next upgrade info + add NextUpgrade test case + fix spacing + add after blossom test + change var and function names for clarity, refactor function + reverse conditional, replace get_value_or(0) calls + remove redundant line from test + remove zmergetoaddress from experimental state in rpc-tests + get UPGRADE_TESTDUMMY back to default at the end of the test + remove dead code in init + readd create_directories + +Ben Woosley (1): + Assert CPubKey::ValidLength to the pubkey's header-relevent size + +Carl Dong (1): + depends: tar: Always extract as yourself + +Casey Rodarmor (1): + Give a better error message if system clock is bad + +Charlie O'Keefe (1): + Add check-depends step to STAGE_COMMANDS list + +Cory Fields (3): + depends: qt/cctools: fix checksum checksum tests + depends: bump OSX toolchain + depends: make osx output deterministic + +Dagur Valberg Johannsson (1): + Remove option mempooltxinputlimit + +Daira Hopwood (1): + Remove temporary workaround for deprecation height. + +Denis Lukianov (1): + Correct importaddress help reference to importpubkey + +Dimitris Apostolou (4): + Fix typo + Remove stale comment + Change "protect" terminology to "shield" + depends macOS: hide linker visibility warnings + +Eirik Ogilvie-Wigley (2): + Show time elapsed when running RPC tests + Update team email + +Gavin Andresen (1): + Unit test doublespends in new blocks + +Gregory Maxwell (1): + Make connect=0 disable automatic outbound connections. + +Gregory Sanders (1): + Added additional config option for multiple RPC users. + +Ian T (1): + Update RPC generate help for numblocks to include required + +Jack Grigg (32): + Upgrade librustzcash to 0.2.0 + Migrate to librustzcash 0.2.0 API + Remove invalid address comparison from gtest + Cast uint8* in InterruptibleRecv to char* for recv + Add Heartwood to upgrade list + Initialize experimental mode in a separate function + Fix benchmarks after removal of SelectParamsFromCommandLine() + Handle Equihash and optional miner code in TestChain100Setup + Add tests covering the current interaction of alerts with subver comments + Parameterize zcash.conf in init error message + cleanup: Comments + Wrap long line + Match alerts both with and without comments + pyflakes fixes + Revert "Remove insecurely-downloaded dependencies that we don't currently use." + depends: Compile bdb with --disable-atomics when cross-compiling darwin + depends: Add Rust targets for cross-compiling darwin + configure: Don't require RELRO and BIND_NOW when cross-compiling darwin + depends: Manually apply build_env to second half of googletest build + Revert "depends: Explicitly set Boost toolchain during configuration" + Add z_mergetoaddress to release notes + ThreadNotifyRecentlyAdded -> ThreadNotifyWallets + Move mempool tx notifying logic out of CTxMemPool + Merge tree and boolean fields in ChainTip API + Move block-notifying logic into ThreadNotifyWallets + Tie sync_blocks in RPC tests to notifier thread + Extend comment with reason for taking care with locks + test: Add sync_all points after block generation to RPC tests + test: Remove genesis-block Sapling activation from shorter_block_times + test: Reverse hashtx and hashblock ordering at start of ZMQ RPC test + test: Add missing sync_all point + test: Update wallet RPC test with change to "absurdly high fee" limit + +Jainan-Tandel (1): + Cosmetic update to README.md . + +Jim Posen (3): + Comments: More comments on functions/globals in standard.h. + [script] Unit tests for script/standard functions + [script] Unit tests for IsMine + +Jonas Schnelli (9): + [autoprune] allow wallet in pruned mode + [RPC] disable import functions in pruned mode + [squashme] improve/corrects prune mode detection test for required wallet rescans + Refactor parameter interaction, call it before AppInit2() + Initialize logging before we do parameter interaction + [Wallet] move wallet help string creation to CWallet + [Wallet] move "load wallet phase" to CWallet + [Wallet] optimize return value of InitLoadWallet() + [Wallet] refactor wallet/init interaction + +Jorge Timón (4): + Chainparams: Replace CBaseChainParams::Network enum with string constants (suggested by Wladimir) + Chainparams: Translations: DRY: options and error strings + Globals: Decouple GetConfigFile and ReadConfigFile from global mapArgs + Policy: MOVEONLY: Create policy/policy.h with some constants + +Larry Ruane (5): + simplify locking, merge cs_SpendingKeyStore into cs_KeyStore + eliminate races: hold cs_KeyStore lock while reading fUseCrypto + revert CCryptoKeyStore::SetCrypted() return value + insightexplorer: LOCK(cs_main) during rpcs + fix tests for enable-debug build + +Luke Dashjr (8): + Bugfix: RPC: blockchain: Display correct defaults in help for verifychain method + Bugfix: Describe dblogsize option correctly (it refers to the wallet database, not memory pool) + Bugfix: If genproclimit is omitted to RPC setgenerate, don't change it; also show correct default in getmininginfo + Bugfix: Omit wallet-related options from -help when wallet is disabled + Constrain constant values to a single location in code + Bugfix: Omit wallet-related options from -help when wallet is not supported + Policy: MOVEONLY: 3 functions to policy.o: + Common argument defaults for NODE_BLOOM stuff and -wallet + +Marco Falke (20): + [trivial] Reuse translation and cleanup DEFAULT_* values + [qt] Move GUI related HelpMessage() part downstream + [trivial] init cleanup + [wallet] Refactor to use new MIN_CHANGE + [wallet] Add comments for doxygen + Init: Use DEFAULT_TRANSACTION_MINFEE in help message + [qt] Properly display required fee instead of minTxFee + Clarify what minrelaytxfee does + translations: Don't translate markdown or force English grammar + transaction_tests: Be more strict checking dust + [trivial] init: Use defaults MIN_RELAY_TX_FEE & TRANSACTION_MAXFEE + contrib: Del. gitian downloader config and update gitian README + rpcwallet: Clarify what settxfee does + HelpMessage: Don't hide -mintxfee behind showDebug + mempool: Replace maxFeeRate of 10000*minRelayTxFee with maxTxFee + [doxygen] Actually display comment + Fix doxygen comment for payTxFee + [doc] Fix markdown + Make sure LogPrintf strings are line-terminated + [wallet] Move hardcoded file name out of log messages + +Marshall Gaucher (3): + Update `import *` to unblock pyflakes from failing + Update z_sendmany calls passing int 0, instead of Decimal('0') + Update to stop random race error from assert + +Matt Corallo (10): + Also remove pay-2-pubkey from watch when adding a priv key + Split up importaddress into helper functions + Add p2sh option to importaddress to import redeemScripts + Add importpubkey method to import a watch-only pubkey + Update importaddress help to push its use to script-only + Add have-pubkey distinction to ISMINE flags + Add logic to track pubkeys as watch-only, not just scripts + Implement watchonly support in fundrawtransaction + SQUASH "Add have-pubkey distinction to ISMINE flags" + SQUASH "Implement watchonly support in fundrawtransaction" + +Miles Manley (1): + Update libsodium download-path + +Peter Todd (3): + Make TX_SCRIPTHASH clear vSolutionsRet first + Add IsPushOnly(const_iterator pc) + Accept any sequence of PUSHDATAs in OP_RETURN outputs + +Pieter Wuille (9): + Remove template matching and pseudo opcodes + Stop treating importaddress'ed scripts as change + Make CScript -> CScriptID conversion explicit + Do not expose SigVersion argument to IsMine + Switch to a private version of SigVersion inside IsMine + Track difference between scriptPubKey and P2SH execution in IsMine + Do not treat bare multisig as IsMine + Mention removal of bare multisig IsMine in release notes + Use anonymous namespace instead of static functions + +Sean Bowe (8): + make-release.py: Versioning changes for 2.1.1-rc1. + make-release.py: Updated manpages for 2.1.1-rc1. + make-release.py: Updated release notes and changelog for 2.1.1-rc1. + make-release.py: Versioning changes for 2.1.1-rc2. + make-release.py: Updated manpages for 2.1.1-rc2. + make-release.py: Updated release notes and changelog for 2.1.1-rc2. + make-release.py: Versioning changes for 2.1.1. + make-release.py: Updated manpages for 2.1.1. + +Simon Liu (1): + Closes #3911. Fix help message of RPC getwalletinfo. + +Taylor Hornby (11): + Add AFL instrumentation scripts to zcutil. + Add configure option to replace main with a stub for fuzzing + Add all-in-one script for starting AFL fuzzing + Separate AFL build, run fuzz stages, and add afl argument pass-through + Have make clean delete fuzz.cpp + Pass AFL input file path to zcashd + Add fuzzing stub for AddrMan deserialization + Add fuzzing stub for ReadFeeEstimates + Add fuzzing stub for CheckBlock + Update proton from 0.26.0 to 0.30.0 + Fix broken proton build + +Ulrich Kempken (1): + depends: switch to secure download of all dependencies + +Wladimir J. van der Laan (7): + make proxy_test work on servers without ipv6 + Fix argument parsing oddity with -noX + doc: mention change to option parsing behavior in release notes + test: move accounting_tests and rpc_wallet_tests to wallet/test + test: Create test fixture for wallet + wallet_ismine.h → script/ismine.h + test: Rename wallet.dat to wallet_test.dat + +sandakersmann (3): + Update of copyright year to 2020 + Update COPYRIGHT_YEAR in clientversion.h to 2020 + Update _COPYRIGHT_YEAR in configure.ac to 2020 + +Jack Grigg (2): + Apply suggestions from code review + Apply suggestions from code review + +Benjamin Winston (1): + Added basic fuzzing to the monolith, see ticket #4155 + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.2-1.md b/depend/zcash/doc/release-notes/release-notes-2.1.2-1.md new file mode 100644 index 000000000..02c101ea2 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.2-1.md @@ -0,0 +1,17 @@ +Notable changes +=============== + +This release solves an issue where nodes that did not follow the Heartwood activation on testnet (by running a version prior to v2.1.2) but then upgraded to v2.1.2 or later would be incapable of rolling back and following the Heartwood activation without performing a reindex operation. + +Changelog +========= + +Jack Grigg (1): + txdb/chain: Restrict Heartwood chain consistency check to block index objects that were created by Heartwood-unaware clients. + +Sean Bowe (4): + Add the intended testnet activation block of Heartwood to our intended rewind logic. + Don't throw exception in PopHistoryNode when popping from empty tree. + make-release.py: Versioning changes for 2.1.2-1. + make-release.py: Updated manpages for 2.1.2-1. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.2-2.md b/depend/zcash/doc/release-notes/release-notes-2.1.2-2.md new file mode 100644 index 000000000..0f2871cce --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.2-2.md @@ -0,0 +1,18 @@ +Notable changes +=============== + +This release fixes an issue that was identified by the Heartwood activation on testnet. v2.1.2 nodes that followed the Heartwood activation on testnet would crash on restart if, prior to shutdown, they had received a block from a miner that had not activated Heartwood, which is very likely. This release fixes that crash. + +Changelog +========= + +Daira Hopwood (1): + txdb: log additional debug information. + +Jack Grigg (1): + txdb: More complete fix for the Heartwood chain consistency check issue. + +Sean Bowe (2): + make-release.py: Versioning changes for 2.1.2-2. + make-release.py: Updated manpages for 2.1.2-2. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.2-3.md b/depend/zcash/doc/release-notes/release-notes-2.1.2-3.md new file mode 100644 index 000000000..02c66637e --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.2-3.md @@ -0,0 +1,12 @@ +Notable changes +=============== + +This release sets the EOS halt date to roughly July 14th, which was our original intention. + +Changelog +========= + +Sean Bowe (2): + make-release.py: Versioning changes for 2.1.2-3. + make-release.py: Updated manpages for 2.1.2-3. + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.2-rc1.md b/depend/zcash/doc/release-notes/release-notes-2.1.2-rc1.md new file mode 100644 index 000000000..328aaea07 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.2-rc1.md @@ -0,0 +1,615 @@ +Notable changes +=============== + +Network Upgrade 3: Heartwood +---------------------------- + +The code preparations for the Heartwood network upgrade are finished and +included in this release. The following ZIPs are being deployed: + +- [ZIP 213: Shielded Coinbase](https://zips.z.cash/zip-0213) +- [ZIP 221: FlyClient - Consensus-Layer Changes](https://zips.z.cash/zip-0221) + +Heartwood will activate on testnet at height XXXXXX, and can also be activated +at a specific height in regtest mode by setting the config option +`-nuparams=f5b9230b:HEIGHT`. + +As a reminder, because the Heartwood activation height is not yet specified for +mainnet, version 2.1.2 will behave similarly as other pre-Heartwood releases +even after a future activation of Heartwood on the network. Upgrading from 2.1.2 +will be required in order to follow the Heartwood network upgrade on mainnet. + +See [ZIP 250](https://zips.z.cash/zip-0250) for additional information about the +deployment process for Heartwood. + +### Mining to Sapling addresses + +Miners and mining pools that wish to test the new "shielded coinbase" support on +the Heartwood testnet can generate a new Sapling address with `z_getnewaddress`, +add the config option `mineraddress=SAPLING_ADDRESS` to their `zcash.conf` file, +and then restart their `zcashd` node. `getblocktemplate` will then return +coinbase transactions containing a shielded miner output. + +Note that `mineraddress` should only be set to a Sapling address after the +Heartwood network upgrade has activated; setting a Sapling address prior to +Heartwood activation will cause `getblocktemplate` to return block templates +that cannot be mined. + +Sapling viewing keys support +---------------------------- + +Support for Sapling viewing keys (specifically, Sapling extended full viewing +keys, as described in [ZIP 32](https://zips.z.cash/zip-0032)), has been added to +the wallet. Nodes will track both sent and received transactions for any Sapling +addresses associated with the imported Sapling viewing keys. + +- Use the `z_exportviewingkey` RPC method to obtain the viewing key for a + shielded address in a node's wallet. For Sapling addresses, these always begin + with "zxviews" (or "zxviewtestsapling" for testnet addresses). + +- Use `z_importviewingkey` to import a viewing key into another node. Imported + Sapling viewing keys will be stored in the wallet, and remembered across + restarts. + +- `z_getbalance` will show the balance of a Sapling address associated with an + imported Sapling viewing key. Balances for Sapling viewing keys will be + included in the output of `z_gettotalbalance` when the `includeWatchonly` + parameter is set to `true`. + +- RPC methods for viewing shielded transaction information (such as + `z_listreceivedbyaddress`) will return information for Sapling addresses + associated with imported Sapling viewing keys. + +Details about what information can be viewed with these Sapling viewing keys, +and what guarantees you have about that information, can be found in +[ZIP 310](https://zips.z.cash/zip-0310). + +Removal of time adjustment and the -maxtimeadjustment= option +------------------------------------------------------------- + +Prior to v2.1.1-1, `zcashd` would adjust the local time that it used by up +to 70 minutes, according to a median of the times sent by the first 200 peers +to connect to it. This mechanism was inherently insecure, since an adversary +making multiple connections to the node could effectively control its time +within that +/- 70 minute window (this is called a "timejacking attack"). + +In the v2.1.1-1 security release, in addition to other mitigations for +timejacking attacks, the maximum time adjustment was set to zero by default. +This effectively disabled time adjustment; however, a `-maxtimeadjustment=` +option was provided to override this default. + +As a simplification the time adjustment code has now been completely removed, +together with `-maxtimeadjustment=`. Node operators should instead ensure that +their local time is set reasonably accurately. + +If it appears that the node has a significantly different time than its peers, +a warning will still be logged and indicated on the metrics screen if enabled. + +View shielded information in wallet transactions +------------------------------------------------ + +In previous `zcashd` versions, to obtain information about shielded transactions +you would use either the `z_listreceivedbyaddress` RPC method (which returns all +notes received by an address) or `z_listunspent` (which returns unspent notes, +optionally filtered by addresses). There were no RPC methods that directly +returned details about spends, or anything equivalent to the `gettransaction` +method (which returns transparent information about in-wallet transactions). + +This release introduces a new RPC method `z_viewtransaction` to fill that gap. +Given the ID of a transaction in the wallet, it decrypts the transaction and +returns detailed shielded information for all decryptable new and spent notes, +including: + +- The address that each note belongs to. +- Values in both decimal ZEC and zatoshis. +- The ID of the transaction that each spent note was received in. +- An `outgoing` flag on each new note, which will be `true` if the output is not + for an address in the wallet. +- A `memoStr` field for each new note, containing its text memo (if its memo + field contains a valid UTF-8 string). + +Information will be shown for any address that appears in `z_listaddresses`; +this includes watch-only addresses linked to viewing keys imported with +`z_importviewingkey`, as well as addresses with spending keys (both generated +with `z_getnewaddress` and imported with `z_importkey`). + +Better error messages for rejected transactions after network upgrades +---------------------------------------------------------------------- + +The Zcash network upgrade process includes several features designed to protect +users. One of these is the "consensus branch ID", which prevents transactions +created after a network upgrade has activated from being replayed on another +chain (that might have occurred due to, for example, a +[friendly fork](https://electriccoin.co/blog/future-friendly-fork/)). This is +known as "two-way replay protection", and is a core requirement by +[various](https://blog.bitgo.com/bitgos-approach-to-handling-a-hard-fork-71e572506d7d?gi=3b80c02e027e) +[members](https://trezor.io/support/general/hard-forks/) of the cryptocurrency +ecosystem for supporting "hard fork"-style changes like our network upgrades. + +One downside of the way replay protection is implemented in Zcash, is that there +is no visible difference between a transaction being rejected by a `zcashd` node +due to targeting a different branch, and being rejected due to an invalid +signature. This has caused issues in the past when a user had not upgraded their +wallet software, or when a wallet lacked support for the new network upgrade's +consensus branch ID; the resulting error messages when users tried to create +transactions were non-intuitive, and particularly cryptic for transparent +transactions. + +Starting from this release, `zcashd` nodes will re-verify invalid transparent +and Sprout signatures against the consensus branch ID from before the most +recent network upgrade. If the signature then becomes valid, the transaction +will be rejected with the error message `old-consensus-branch-id`. This error +can be handled specifically by wallet providers to inform the user that they +need to upgrade their wallet software. + +Wallet software can also automatically obtain the latest consensus branch ID +from their (up-to-date) `zcashd` node, by calling `getblockchaininfo` and +looking at `{'consensus': {'nextblock': BRANCH_ID, ...}, ...}` in the JSON +output. + +Expired transactions notifications +---------------------------------- + +A new config option `-txexpirynotify` has been added that will cause `zcashd` to +execute a command when a transaction in the mempool expires. This can be used to +notify external systems about transaction expiry, similar to the existing +`-blocknotify` config option that notifies when the chain tip changes. + +RPC methods +----------- + +- The `z_importkey` and `z_importviewingkey` RPC methods now return the type of + the imported spending or viewing key (`sprout` or `sapling`), and the + corresponding payment address. + +- Negative heights are now permitted in `getblock` and `getblockhash`, to select + blocks backwards from the chain tip. A height of `-1` corresponds to the last + known valid block on the main chain. + +- A new RPC method `getexperimentalfeatures` returns the list of enabled + experimental features. + +Build system +------------ + +- The `--enable-lcov`, `--disable-tests`, and `--disable-mining` flags for + `zcutil/build.sh` have been removed. You can pass these flags instead by using + the `CONFIGURE_FLAGS` environment variable. For example, to enable coverage + instrumentation (thus enabling "make cov" to work), call: + + ``` + CONFIGURE_FLAGS="--enable-lcov --disable-hardening" ./zcutil/build.sh + ``` + +- The build system no longer defaults to verbose output. You can re-enable + verbose output with `./zcutil/build.sh V=1` + +Changelog +========= + +Alfredo Garcia (40): + remove SignatureHash from python rpc tests + add negative height to getblock + allow negative index to getblockhash + update docs + add additional tests to rpc_wallet_z_getnewaddress + change convention + change regex + Return address and type of imported key in z_importkey + Delete travis file + dedup decode keys and addresses + remove unused imports + add txexpirynotify + fix rpx_wallet_tests + remove debug noise from 2 gtests + make type and size a pair in DecodeAny arguments + add missing calls to DecodeAny + add destination wrappers + change tuples to classes + change cm() to cmu() in SaplingNote class + change the cm member of OutputDescription to cmu + change maybe_cm to maybe_cmu + add getexperimentalfeatures rpc call + refactor experimental features + make fInsightExplorer a local + add check_node_log utility function + remove space after new line + move check_node_log framework test to a new file + use check_node_log in turnstile.py + add stop_node argument to check_node_log, use it in shieldingcoinbase + change constructors + minor comment fix + preserve test semantics + remove unused import + multiple debug categories documentation + return address info in z_importviewingkey + add expected address check to tests + change unclear wording in z_import calls address returned + Lock with cs_main inside gtests that call chainActive.Height() + add -lightwalletd experimental option + compute more structures in mempool DynamicMemoryUsage + +Carl Dong (1): + autoconf: Sane --enable-debug defaults. + +Chun Kuan Lee (1): + Reset default -g -O2 flags when enable debug + +Cory Fields (3): + bench: switch to std::chrono for time measurements + bench: prefer a steady clock if the resolution is no worse + build: Split hardening/fPIE options out + +Dagur Valberg Johannsson (1): + Improve z_getnewaddress tests + +Daira Hopwood (24): + Add missing cases for Blossom in ContextualCheckBlock tests. + Revert "Add -maxtimeadjustment with default of 0 instead of the 4200 seconds used in Bitcoin Core." + Remove uses of GetTimeOffset(). + Replace time adjustment with warning only. + Update GetAdjustedTime() to GetTime(). + Sort entries in zcash_gtest_SOURCES (other than test_tautology which is deliberately first). + Add release notes for removal of -maxtimeadjustment. + Resolve a race condition on `chainActive.Tip()` in initialization (introduced in #4379). + Setting a std::atomic variable in a signal handler only has defined behaviour if it is lock-free. + Add comment to `MilliSleep` documenting that it is an interruption point. + Exit init early if we request shutdown before having loaded the genesis block. + Fix typos/minor errors in comments, and wrap some lines. + Avoid a theoretical possibility of division-by-zero introduced in #4368. + Make the memo a mandatory argument for SendManyRecipient + Add a `zcutil/clean.sh` script that works (unlike `make clean`). + Split into clean.sh and distclean.sh. + Minor refactoring. + Executables end with .exe on Windows. + Avoid spurious error messages when cleaning up directories. + Address review comments. + Use `SA_RESTART` in `sa_flags` when setting up signal handlers. + Remove a redundant `rm -f` command. + Refer to altitude instead of height for history tree peaks + Address review comments: `target` and `depends/work` should be cleaned by clean.sh. + +Dimitris Apostolou (8): + Fix Boost compilation on macOS + Remove libsnark preprocessor flags + Fix typo + End diff with LF character + Remove stale comment + Point at support community on Discord + Update documentation info + Fix typos + +Eirik Ogilvie-Wigley (2): + Include shielded transaction data when calculating RecursiveDynamicUsage of transactions + Account for malloc overhead + +Evan Klitzke (2): + Add --with-sanitizers option to configure + Make --enable-debug to pick better options + +Gavin Andresen (2): + Simple benchmarking framework + Support very-fast-running benchmarks + +Gregory Maxwell (4): + Avoid integer division in the benchmark inner-most loop. + Move GetWarnings and related globals to util. + Eliminate data races for strMiscWarning and fLargeWork*Found. + Move GetWarnings() into its own file. + +Jack Grigg (94): + Revert "Add configure flags for enabling ASan/UBSan and TSan" + configure: Re-introduce additional sanitizer flags + RPC: z_viewtransaction + depends: Add utfcpp to dependencies + RPC: Display valid UTF-8 memos in z_viewtransaction + RPC: Use OutgoingViewingKeys to recover non-wallet Sapling outputs + test: Check z_viewtransaction output in wallet_listreceived RPC test + Benchmark Zcash verification operations + Simulate worst-case block verification + zcutil/build.sh: Remove lcov and mining flags + configure: Change default Proton to match build.sh + zcutil/build.sh: Turn off verbosity by default + Make -fwrapv conditional on --enable-debug=no + Move default -g flag into configure.ac behind --enable-debug=no + Add build system changes to release notes + test: Hard-code hex memo in wallet_listreceived for Python3 compatibility + test: Fix pyflakes warnings + bench: "Use" result of crypto_sign_verify_detached + Add test vectors for small-order Ed25519 pubkeys + Patch libsodium 1.0.15 pubkey validation onto 1.0.18 + Patch libsodium 1.0.15 signature validation onto 1.0.18 + Add release notes for z_viewtransaction + Deduplicate some wallet keystore logic + Move Sprout and Sapling address logic into separate files + Move ZIP 32 classes inside zcash/Address.hpp + SaplingFullViewingKey -> SaplingExtendedFullViewingKey in keystore maps + Remove default address parameter from Sapling keystore methods + test: Add test for CBasicKeyStore::AddSaplingFullViewingKey + Add encoding and decoding for Sapling extended full viewing keys + Add Sapling ExtFVK support to z_exportviewingkey + Add in-memory Sapling ExtFVK support to z_importviewingkey + Store imported Sapling ExtFVKs in wallet database + OutputDescriptionInfo::Build() + ZIP 213 consensus rules + Add support for Sapling addresses in -mineraddress + wallet: Include coinbase txs in Sapling note selection + Add regtest-only -nurejectoldversions option + test: Minor tweaks to comments in LibsodiumPubkeyValidation + test: RPC test for shielded coinbase + Adjust comments on ZIP 213 logic + Use DoS level constants and parameters for ZIP 213 rejections + test: Check that shielded coinbase can be spent to a t-address + init: Inform on error that -mineraddress must be Sapling or transparent + test: Explicitly check Sapling consensus rules apply to shielded coinbase + Migrate GitHub issue template to new format + Add GitHub issue templates for feature requests and UX reports + depends: Remove comments from libsodium signature validation patch + Bring in librustzcash crate + Bring in Cargo.lock from librustzcash repo + rust: Pin toolchain to 1.36.0, matching depends system + rust: Adjust Cargo.toml so that it compiles + Update .gitignore for Rust code + Replace librustzcash from depends system with src/rust + Move root of Rust crate into repo root + depends: Remove unused vendored crates + Fix Rust static library linking for Windows builds + test: Rename FakeCoinsViewDB -> ValidationFakeCoinsViewDB + test: Modify ValidationFakeCoinsViewDB to optionally contain a coin + test: Add missing parameter selection to Validation.ReceivedBlockTransactions + mempool: Check transparent signatures against the previous network upgrade + mempool: Remove duplicate consensusBranchId from AcceptToMemoryPool + test: Add Overwinter and Sapling support to GetValidTransaction() helper + consensus: Check JoinSplit signatures against the previous network upgrade + depends: Use Rust 1.42.0 toolchain + Bring in updates to librustzcash crate + depends: Define Rust target in a single location + depends: Hard-code Rust target for all Darwin hosts + Add ZIP 221 logic to block index + Add ZIP 221 support to miner and getblocktemplate + Implement ZIP 221 consensus rules + Return the correct root from librustzcash_mmr_{append, delete} + Use a C array for HistoryEntry instead of std::array + test: Verify ZIP 221 logic against reference implementation + build: Move cargo arguments into RUST_BUILD_OPTS + build: Correctly remove generated files from .cargo + test: Build Rust tests as part of qa/zcash/full_test_suite.py + build: Connect cargo verbosity to make verbosity + test: Assert that GetValidTransaction supports the given branch ID + Comment tweaks and cleanups + test: Add an extra assertion to feature_zip221.py + Remove unnecessary else case in CCoinsViewCache::PreloadHistoryTree + Improve documentation of CCoinsViewCache::PreloadHistoryTree + Truncate HistoryCache.appends correctly for zero-indexed entries + Comment clarifications and fixes + Make peak_pos zero-indexed in CCoinsViewCache::PreloadHistoryTree + test: Ignore timestamps in addressindex checks + test: Add a second Sapling note to WalletTests.ClearNoteWitnessCache + test: Run Equihash test vectors on both C++ and Rust validators + Pass the block height through to CheckEquihashSolution() + consensus: From Heartwood activation, use Rust Equihash validator + zcutil/make-release.py: Fix to run with Python 3 + zcutil/make-release.py: Check for release dependencies + Update release notes for v2.1.2 + zcutil/release-notes.py: Add Python 3 execution header + +James O'Beirne (1): + Add basic coverage reporting for RPC tests + +Jeremy Rubin (3): + Add Basic CheckQueue Benchmark + Address ryanofsky feedback on CCheckQueue benchmarks. Eliminated magic numbers, fixed scoping of vectors (and memory movement component of benchmark). + Add prevector destructor benchmark + +Karl-Johan Alm (1): + Refactoring: Removed using namespace from bench/ and test/ source files. + +Larry Ruane (2): + zcutil/fetch-params.sh unneeded --testnet arg should warn user + util: CBufferedFile fixes + +LitecoinZ (1): + Fix issue #3772 + +Marshall Gaucher (1): + Update qa/rpc-tests/addressindex.py + +Matt Corallo (2): + Remove countMaskInv caching in bench framework + Require a steady clock for bench with at least micro precision + +MeshCollider (3): + Fix race for mapBlockIndex in AppInitMain + Make fReindex atomic to avoid race + Consistent parameter names in txdb.h + +NicolasDorier (1): + [qa] assert_start_raises_init_error + +NikVolf (3): + push/pop history with tests + update chain history in ConnectBlock and DisconnectBlock + use iterative platform-independent log2i + +Patrick Strateman (1): + Acquire lock to check for genesis block. + +Pavel Janík (3): + Rewrite help texts for features enabled by default. + Ignore bench_bitcoin binary. + Prevent warning: variable 'x' is uninitialized + +Philip Kaufmann (1): + [Trivial] ensure minimal header conventions + +Pieter Wuille (3): + Benchmark rolling bloom filter + Introduce FastRandomContext::randbool() + FastRandom benchmark + +Sean Bowe (9): + Initialize ThreadNotifyWallets before additional blocks are imported. + Handle case of fresh wallets in ThreadNotifyWallets. + Clarify comment + Add librustzcash tests to the full test suite. + Add release profile optimizations and turn off panic unwinding in librustzcash. + Minor typo fixes. + Simplification for MacOS in rust-test. + make-release.py: Versioning changes for 2.1.2-rc1. + make-release.py: Updated manpages for 2.1.2-rc1. + +Taylor Hornby (15): + Make the equihash validator macro set its output to false when throwing an exception. + Add test for unused bits in the Equihash solution encoding. + Add Python script for checking if dependencies have updates. + Add GitHub API credential + Update list of dependencies to check + Wrap long lines + Cache releases to reduce network usage and improve performance + Make updatecheck.py compatible with python2 + Have make clean delete temporary AFL build directory + Add AFL build directory to .gitignore + Have make clean delete AFL output directories. + Fix bug in updatecheck.py and add utfcpp to its dependency list + Fix typo in updatecheck.py + Update updatecheck.py with the new Rust dependencies and improve the error message in case the untracked dependency list becomes out of date. + Fix undefined behavior in CScriptNum + +Wladimir J. van der Laan (7): + bench: Add crypto hash benchmarks + Kill insecure_random and associated global state + bench: Fix subtle counting issue when rescaling iteration count + bench: Add support for measuring CPU cycles + bench: Fix initialization order in registration + util: Don't set strMiscWarning on every exception + test_framework: detect failure of bitcoind startup + +Yuri Zhykin (1): + bench: Added base58 encoding/decoding benchmarks + +avnish (14): + changed block_test to BlockTests + changed test names from _ to CamelCase + changed header_size_is_expected to HeaderSizeIsExpected + changed "equihash_tests" to EquihashTests + changed founders_reward_test to FoundersRewardTest + changes tests to camelcase + chnged keystore_tests to KeystoreTests + changed libzcash_utils to LibzcashUtils + changed test to CamelCase + changed test to CamelCase + changed test to CamelCase + changed seven_eq_seven to SevenEqSeven + changed txid_tests to TxidTests + changed wallet_zkeys_test to WalletZkeysTest + +avnish98 (1): + requested changes are rectified + +ca333 (2): + update libsodium to v1.0.18 + fix dead openssl download path + +gladcow (4): + Show reindex state in metrics + Use processed file size as progress in metrics during reindex + Byte sizes format + Move reindex progress globals to metrics.h/cpp + +Marshall Gaucher (74): + update /usr/bin/env; fix print conventions + update test_framework modules + Update rpc-test/test_framework to Py3 convention,modules,encoding + Update ignored testScriptsExt to Python3 + Update python3 env path, remove python 2.7 assert + Update hexlify for encoding, update to py3 io module + Update py3 env path, remove py2 assert + Update py2 conventions to py3, remove py2 env and assert + Update py2 conventions to py3, update Decimal calls + Update py2 env path, remove py2 assert + Update py2 env path, remove py2 assert + Update py2 env path, remove py2 assert, update filter to return list for py3 + Update py2 env path, remove py2 assert, update http module and assert encoding + Update cmp to py3 functions, update map return to list for py3 + Standard py2 to py3 updates + Update py2 modules to py3, update encoding to be py3 compatible + Update to py3 conventions, update decimal calls to be consistent + Update to py3 conventions, update filter to return list + update to py3 conventions, update range to return list for py3 + update to py3 convention, update execfile to py3 call + update to py3 conventions, update cmp to be py3 compatible, update map to return list for py3 + update to py3 conventions, preserve ipv6 patch + update str cast to prevent address assert issues + clean up binascii call + Add keyerror execption + update to py3 env path + update to py3 conventions, update functions to be upstream consistent + update to py3 conventions, clean up code to be upstream consistent + update to py3 encodings + update encoding, decoding, serialize funcs for py3 + Update type to be decimal + update to py3 conventions, BUG with last assert_equal + Update io modules for py3, ISSUE with create_transaction function + Update to py3, ISSUE with encoding + Update to py3, ISSUE with encoding + Update to py3, ISSUE with encoding in create_block + Update to py3, ISSUE with encoding in create_block + Clean up code not needed from upstream + update io module, fix py3 division, and string encoding + update remaining encoding issues, add pyblake2 + Use more meaningful assert_equal from our original codebase + Clean up code from upstream we dont use + fix except bug for undefined url + Remove semi colons + make import urlparse module consistent,httplib update to py3 + correct update to python3 + clean-up imports, keep string notation consistent, remove spacing + clean up + Use upstream encoding for encodeDecimal + fix type issue + fix initialize statements for imports + clean up initiliaze statements from imports + update type for decimal 0 + remove debug lines from prior commits + clean up to minimize diff + remove u encoding + Fix decimal 0 issues + Clean up import calls + clean up + clean up + clean up + fix url and port issue + cleanups and fixing odd casting + Update json to simplejson to remove unicode and str issue from py2 to py3 + Update py3 division + fix pyflakes errors + clean up conventions and whitespace + fix string pattern issue on byte object + update comment regarding prior py2 exception + Fix remaining python3 conventions + Update remaining Python3 conventions + Updating remaining python3 conventions + Update #! env for python3 + Update RPCs to support cross platform paths and libs + +murrayn (1): + Add build support for 'gprof' profiling. + +practicalswift (8): + build: Show enabled sanitizers in configure output + Add -ftrapv to DEBUG_CXXFLAGS when --enable-debug is used + Assert that what might look like a possible division by zero is actually unreachable + Replace boost::function with std::function (C++11) + Avoid static analyzer warnings regarding uninitialized arguments + Restore default format state of cout after printing with std::fixed/setprecision + Initialize recently introduced non-static class member lastCycles to zero in constructor + Replace boost::function with std::function (C++11) + +ptschip (1): + Enable python tests for Native Windows + +zancas (3): + update comment, to correctly specify number of methods injected + replace "virtual" with "override" in subclasses + Remove remaining instances of boost::function + diff --git a/depend/zcash/doc/release-notes/release-notes-2.1.2.md b/depend/zcash/doc/release-notes/release-notes-2.1.2.md new file mode 100644 index 000000000..0a4aa45d4 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-2.1.2.md @@ -0,0 +1,623 @@ +Notable changes +=============== + +Network Upgrade 3: Heartwood +---------------------------- + +The code preparations for the Heartwood network upgrade are finished and +included in this release. The following ZIPs are being deployed: + +- [ZIP 213: Shielded Coinbase](https://zips.z.cash/zip-0213) +- [ZIP 221: FlyClient - Consensus-Layer Changes](https://zips.z.cash/zip-0221) + +Heartwood will activate on testnet at height 903800, and can also be activated +at a specific height in regtest mode by setting the config option +`-nuparams=f5b9230b:HEIGHT`. + +As a reminder, because the Heartwood activation height is not yet specified for +mainnet, version 2.1.2 will behave similarly as other pre-Heartwood releases +even after a future activation of Heartwood on the network. Upgrading from 2.1.2 +will be required in order to follow the Heartwood network upgrade on mainnet. + +See [ZIP 250](https://zips.z.cash/zip-0250) for additional information about the +deployment process for Heartwood. + +### Mining to Sapling addresses + +Miners and mining pools that wish to test the new "shielded coinbase" support on +the Heartwood testnet can generate a new Sapling address with `z_getnewaddress`, +add the config option `mineraddress=SAPLING_ADDRESS` to their `zcash.conf` file, +and then restart their `zcashd` node. `getblocktemplate` will then return +coinbase transactions containing a shielded miner output. + +Note that `mineraddress` should only be set to a Sapling address after the +Heartwood network upgrade has activated; setting a Sapling address prior to +Heartwood activation will cause `getblocktemplate` to return block templates +that cannot be mined. + +Sapling viewing keys support +---------------------------- + +Support for Sapling viewing keys (specifically, Sapling extended full viewing +keys, as described in [ZIP 32](https://zips.z.cash/zip-0032)), has been added to +the wallet. Nodes will track both sent and received transactions for any Sapling +addresses associated with the imported Sapling viewing keys. + +- Use the `z_exportviewingkey` RPC method to obtain the viewing key for a + shielded address in a node's wallet. For Sapling addresses, these always begin + with "zxviews" (or "zxviewtestsapling" for testnet addresses). + +- Use `z_importviewingkey` to import a viewing key into another node. Imported + Sapling viewing keys will be stored in the wallet, and remembered across + restarts. + +- `z_getbalance` will show the balance of a Sapling address associated with an + imported Sapling viewing key. Balances for Sapling viewing keys will be + included in the output of `z_gettotalbalance` when the `includeWatchonly` + parameter is set to `true`. + +- RPC methods for viewing shielded transaction information (such as + `z_listreceivedbyaddress`) will return information for Sapling addresses + associated with imported Sapling viewing keys. + +Details about what information can be viewed with these Sapling viewing keys, +and what guarantees you have about that information, can be found in +[ZIP 310](https://zips.z.cash/zip-0310). + +Removal of time adjustment and the -maxtimeadjustment= option +------------------------------------------------------------- + +Prior to v2.1.1-1, `zcashd` would adjust the local time that it used by up +to 70 minutes, according to a median of the times sent by the first 200 peers +to connect to it. This mechanism was inherently insecure, since an adversary +making multiple connections to the node could effectively control its time +within that +/- 70 minute window (this is called a "timejacking attack"). + +In the v2.1.1-1 security release, in addition to other mitigations for +timejacking attacks, the maximum time adjustment was set to zero by default. +This effectively disabled time adjustment; however, a `-maxtimeadjustment=` +option was provided to override this default. + +As a simplification the time adjustment code has now been completely removed, +together with `-maxtimeadjustment=`. Node operators should instead ensure that +their local time is set reasonably accurately. + +If it appears that the node has a significantly different time than its peers, +a warning will still be logged and indicated on the metrics screen if enabled. + +View shielded information in wallet transactions +------------------------------------------------ + +In previous `zcashd` versions, to obtain information about shielded transactions +you would use either the `z_listreceivedbyaddress` RPC method (which returns all +notes received by an address) or `z_listunspent` (which returns unspent notes, +optionally filtered by addresses). There were no RPC methods that directly +returned details about spends, or anything equivalent to the `gettransaction` +method (which returns transparent information about in-wallet transactions). + +This release introduces a new RPC method `z_viewtransaction` to fill that gap. +Given the ID of a transaction in the wallet, it decrypts the transaction and +returns detailed shielded information for all decryptable new and spent notes, +including: + +- The address that each note belongs to. +- Values in both decimal ZEC and zatoshis. +- The ID of the transaction that each spent note was received in. +- An `outgoing` flag on each new note, which will be `true` if the output is not + for an address in the wallet. +- A `memoStr` field for each new note, containing its text memo (if its memo + field contains a valid UTF-8 string). + +Information will be shown for any address that appears in `z_listaddresses`; +this includes watch-only addresses linked to viewing keys imported with +`z_importviewingkey`, as well as addresses with spending keys (both generated +with `z_getnewaddress` and imported with `z_importkey`). + +Better error messages for rejected transactions after network upgrades +---------------------------------------------------------------------- + +The Zcash network upgrade process includes several features designed to protect +users. One of these is the "consensus branch ID", which prevents transactions +created after a network upgrade has activated from being replayed on another +chain (that might have occurred due to, for example, a +[friendly fork](https://electriccoin.co/blog/future-friendly-fork/)). This is +known as "two-way replay protection", and is a core requirement by +[various](https://blog.bitgo.com/bitgos-approach-to-handling-a-hard-fork-71e572506d7d?gi=3b80c02e027e) +[members](https://trezor.io/support/general/hard-forks/) of the cryptocurrency +ecosystem for supporting "hard fork"-style changes like our network upgrades. + +One downside of the way replay protection is implemented in Zcash, is that there +is no visible difference between a transaction being rejected by a `zcashd` node +due to targeting a different branch, and being rejected due to an invalid +signature. This has caused issues in the past when a user had not upgraded their +wallet software, or when a wallet lacked support for the new network upgrade's +consensus branch ID; the resulting error messages when users tried to create +transactions were non-intuitive, and particularly cryptic for transparent +transactions. + +Starting from this release, `zcashd` nodes will re-verify invalid transparent +and Sprout signatures against the consensus branch ID from before the most +recent network upgrade. If the signature then becomes valid, the transaction +will be rejected with the error message `old-consensus-branch-id`. This error +can be handled specifically by wallet providers to inform the user that they +need to upgrade their wallet software. + +Wallet software can also automatically obtain the latest consensus branch ID +from their (up-to-date) `zcashd` node, by calling `getblockchaininfo` and +looking at `{'consensus': {'nextblock': BRANCH_ID, ...}, ...}` in the JSON +output. + +Expired transactions notifications +---------------------------------- + +A new config option `-txexpirynotify` has been added that will cause `zcashd` to +execute a command when a transaction in the mempool expires. This can be used to +notify external systems about transaction expiry, similar to the existing +`-blocknotify` config option that notifies when the chain tip changes. + +RPC methods +----------- + +- The `z_importkey` and `z_importviewingkey` RPC methods now return the type of + the imported spending or viewing key (`sprout` or `sapling`), and the + corresponding payment address. + +- Negative heights are now permitted in `getblock` and `getblockhash`, to select + blocks backwards from the chain tip. A height of `-1` corresponds to the last + known valid block on the main chain. + +- A new RPC method `getexperimentalfeatures` returns the list of enabled + experimental features. + +Build system +------------ + +- The `--enable-lcov`, `--disable-tests`, and `--disable-mining` flags for + `zcutil/build.sh` have been removed. You can pass these flags instead by using + the `CONFIGURE_FLAGS` environment variable. For example, to enable coverage + instrumentation (thus enabling "make cov" to work), call: + + ``` + CONFIGURE_FLAGS="--enable-lcov --disable-hardening" ./zcutil/build.sh + ``` + +- The build system no longer defaults to verbose output. You can re-enable + verbose output with `./zcutil/build.sh V=1` + +Changelog +========= + +Alfredo Garcia (40): + remove SignatureHash from python rpc tests + add negative height to getblock + allow negative index to getblockhash + update docs + add additional tests to rpc_wallet_z_getnewaddress + change convention + change regex + Return address and type of imported key in z_importkey + Delete travis file + dedup decode keys and addresses + remove unused imports + add txexpirynotify + fix rpx_wallet_tests + remove debug noise from 2 gtests + make type and size a pair in DecodeAny arguments + add missing calls to DecodeAny + add destination wrappers + change tuples to classes + change cm() to cmu() in SaplingNote class + change the cm member of OutputDescription to cmu + change maybe_cm to maybe_cmu + add getexperimentalfeatures rpc call + refactor experimental features + make fInsightExplorer a local + add check_node_log utility function + remove space after new line + move check_node_log framework test to a new file + use check_node_log in turnstile.py + add stop_node argument to check_node_log, use it in shieldingcoinbase + change constructors + minor comment fix + preserve test semantics + remove unused import + multiple debug categories documentation + return address info in z_importviewingkey + add expected address check to tests + change unclear wording in z_import calls address returned + Lock with cs_main inside gtests that call chainActive.Height() + add -lightwalletd experimental option + compute more structures in mempool DynamicMemoryUsage + +Carl Dong (1): + autoconf: Sane --enable-debug defaults. + +Chun Kuan Lee (1): + Reset default -g -O2 flags when enable debug + +Cory Fields (3): + bench: switch to std::chrono for time measurements + bench: prefer a steady clock if the resolution is no worse + build: Split hardening/fPIE options out + +Dagur Valberg Johannsson (1): + Improve z_getnewaddress tests + +Daira Hopwood (25): + Add missing cases for Blossom in ContextualCheckBlock tests. + Revert "Add -maxtimeadjustment with default of 0 instead of the 4200 seconds used in Bitcoin Core." + Remove uses of GetTimeOffset(). + Replace time adjustment with warning only. + Update GetAdjustedTime() to GetTime(). + Sort entries in zcash_gtest_SOURCES (other than test_tautology which is deliberately first). + Add release notes for removal of -maxtimeadjustment. + Resolve a race condition on `chainActive.Tip()` in initialization (introduced in #4379). + Setting a std::atomic variable in a signal handler only has defined behaviour if it is lock-free. + Add comment to `MilliSleep` documenting that it is an interruption point. + Exit init early if we request shutdown before having loaded the genesis block. + Fix typos/minor errors in comments, and wrap some lines. + Avoid a theoretical possibility of division-by-zero introduced in #4368. + Make the memo a mandatory argument for SendManyRecipient + Add a `zcutil/clean.sh` script that works (unlike `make clean`). + Split into clean.sh and distclean.sh. + Minor refactoring. + Executables end with .exe on Windows. + Avoid spurious error messages when cleaning up directories. + Address review comments. + Use `SA_RESTART` in `sa_flags` when setting up signal handlers. + Remove a redundant `rm -f` command. + Refer to altitude instead of height for history tree peaks + Address review comments: `target` and `depends/work` should be cleaned by clean.sh. + Clarify definition of NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD. + +Dimitris Apostolou (8): + Fix Boost compilation on macOS + Remove libsnark preprocessor flags + Fix typo + End diff with LF character + Remove stale comment + Point at support community on Discord + Update documentation info + Fix typos + +Eirik Ogilvie-Wigley (2): + Include shielded transaction data when calculating RecursiveDynamicUsage of transactions + Account for malloc overhead + +Evan Klitzke (2): + Add --with-sanitizers option to configure + Make --enable-debug to pick better options + +Gavin Andresen (2): + Simple benchmarking framework + Support very-fast-running benchmarks + +Gregory Maxwell (4): + Avoid integer division in the benchmark inner-most loop. + Move GetWarnings and related globals to util. + Eliminate data races for strMiscWarning and fLargeWork*Found. + Move GetWarnings() into its own file. + +Jack Grigg (95): + Revert "Add configure flags for enabling ASan/UBSan and TSan" + configure: Re-introduce additional sanitizer flags + RPC: z_viewtransaction + depends: Add utfcpp to dependencies + RPC: Display valid UTF-8 memos in z_viewtransaction + RPC: Use OutgoingViewingKeys to recover non-wallet Sapling outputs + test: Check z_viewtransaction output in wallet_listreceived RPC test + Benchmark Zcash verification operations + Simulate worst-case block verification + zcutil/build.sh: Remove lcov and mining flags + configure: Change default Proton to match build.sh + zcutil/build.sh: Turn off verbosity by default + Make -fwrapv conditional on --enable-debug=no + Move default -g flag into configure.ac behind --enable-debug=no + Add build system changes to release notes + test: Hard-code hex memo in wallet_listreceived for Python3 compatibility + test: Fix pyflakes warnings + bench: "Use" result of crypto_sign_verify_detached + Add test vectors for small-order Ed25519 pubkeys + Patch libsodium 1.0.15 pubkey validation onto 1.0.18 + Patch libsodium 1.0.15 signature validation onto 1.0.18 + Add release notes for z_viewtransaction + Deduplicate some wallet keystore logic + Move Sprout and Sapling address logic into separate files + Move ZIP 32 classes inside zcash/Address.hpp + SaplingFullViewingKey -> SaplingExtendedFullViewingKey in keystore maps + Remove default address parameter from Sapling keystore methods + test: Add test for CBasicKeyStore::AddSaplingFullViewingKey + Add encoding and decoding for Sapling extended full viewing keys + Add Sapling ExtFVK support to z_exportviewingkey + Add in-memory Sapling ExtFVK support to z_importviewingkey + Store imported Sapling ExtFVKs in wallet database + OutputDescriptionInfo::Build() + ZIP 213 consensus rules + Add support for Sapling addresses in -mineraddress + wallet: Include coinbase txs in Sapling note selection + Add regtest-only -nurejectoldversions option + test: Minor tweaks to comments in LibsodiumPubkeyValidation + test: RPC test for shielded coinbase + Adjust comments on ZIP 213 logic + Use DoS level constants and parameters for ZIP 213 rejections + test: Check that shielded coinbase can be spent to a t-address + init: Inform on error that -mineraddress must be Sapling or transparent + test: Explicitly check Sapling consensus rules apply to shielded coinbase + Migrate GitHub issue template to new format + Add GitHub issue templates for feature requests and UX reports + depends: Remove comments from libsodium signature validation patch + Bring in librustzcash crate + Bring in Cargo.lock from librustzcash repo + rust: Pin toolchain to 1.36.0, matching depends system + rust: Adjust Cargo.toml so that it compiles + Update .gitignore for Rust code + Replace librustzcash from depends system with src/rust + Move root of Rust crate into repo root + depends: Remove unused vendored crates + Fix Rust static library linking for Windows builds + test: Rename FakeCoinsViewDB -> ValidationFakeCoinsViewDB + test: Modify ValidationFakeCoinsViewDB to optionally contain a coin + test: Add missing parameter selection to Validation.ReceivedBlockTransactions + mempool: Check transparent signatures against the previous network upgrade + mempool: Remove duplicate consensusBranchId from AcceptToMemoryPool + test: Add Overwinter and Sapling support to GetValidTransaction() helper + consensus: Check JoinSplit signatures against the previous network upgrade + depends: Use Rust 1.42.0 toolchain + Bring in updates to librustzcash crate + depends: Define Rust target in a single location + depends: Hard-code Rust target for all Darwin hosts + Add ZIP 221 logic to block index + Add ZIP 221 support to miner and getblocktemplate + Implement ZIP 221 consensus rules + Return the correct root from librustzcash_mmr_{append, delete} + Use a C array for HistoryEntry instead of std::array + test: Verify ZIP 221 logic against reference implementation + build: Move cargo arguments into RUST_BUILD_OPTS + build: Correctly remove generated files from .cargo + test: Build Rust tests as part of qa/zcash/full_test_suite.py + build: Connect cargo verbosity to make verbosity + test: Assert that GetValidTransaction supports the given branch ID + Comment tweaks and cleanups + test: Add an extra assertion to feature_zip221.py + Remove unnecessary else case in CCoinsViewCache::PreloadHistoryTree + Improve documentation of CCoinsViewCache::PreloadHistoryTree + Truncate HistoryCache.appends correctly for zero-indexed entries + Comment clarifications and fixes + Make peak_pos zero-indexed in CCoinsViewCache::PreloadHistoryTree + test: Ignore timestamps in addressindex checks + test: Add a second Sapling note to WalletTests.ClearNoteWitnessCache + test: Run Equihash test vectors on both C++ and Rust validators + Pass the block height through to CheckEquihashSolution() + consensus: From Heartwood activation, use Rust Equihash validator + zcutil/make-release.py: Fix to run with Python 3 + zcutil/make-release.py: Check for release dependencies + Update release notes for v2.1.2 + zcutil/release-notes.py: Add Python 3 execution header + Set hashFinalSaplingRoot and hashChainHistoryRoot in AddToBlockIndex + +James O'Beirne (1): + Add basic coverage reporting for RPC tests + +Jeremy Rubin (3): + Add Basic CheckQueue Benchmark + Address ryanofsky feedback on CCheckQueue benchmarks. Eliminated magic numbers, fixed scoping of vectors (and memory movement component of benchmark). + Add prevector destructor benchmark + +Karl-Johan Alm (1): + Refactoring: Removed using namespace from bench/ and test/ source files. + +Larry Ruane (2): + zcutil/fetch-params.sh unneeded --testnet arg should warn user + util: CBufferedFile fixes + +LitecoinZ (1): + Fix issue #3772 + +Marshall Gaucher (1): + Update qa/rpc-tests/addressindex.py + +Matt Corallo (2): + Remove countMaskInv caching in bench framework + Require a steady clock for bench with at least micro precision + +MeshCollider (3): + Fix race for mapBlockIndex in AppInitMain + Make fReindex atomic to avoid race + Consistent parameter names in txdb.h + +NicolasDorier (1): + [qa] assert_start_raises_init_error + +NikVolf (3): + push/pop history with tests + update chain history in ConnectBlock and DisconnectBlock + use iterative platform-independent log2i + +Patrick Strateman (1): + Acquire lock to check for genesis block. + +Pavel Janík (3): + Rewrite help texts for features enabled by default. + Ignore bench_bitcoin binary. + Prevent warning: variable 'x' is uninitialized + +Philip Kaufmann (1): + [Trivial] ensure minimal header conventions + +Pieter Wuille (3): + Benchmark rolling bloom filter + Introduce FastRandomContext::randbool() + FastRandom benchmark + +Sean Bowe (15): + Initialize ThreadNotifyWallets before additional blocks are imported. + Handle case of fresh wallets in ThreadNotifyWallets. + Clarify comment + Add librustzcash tests to the full test suite. + Add release profile optimizations and turn off panic unwinding in librustzcash. + Minor typo fixes. + Simplification for MacOS in rust-test. + make-release.py: Versioning changes for 2.1.2-rc1. + make-release.py: Updated manpages for 2.1.2-rc1. + make-release.py: Updated release notes and changelog for 2.1.2-rc1. + Add Rust resources to distribution tarball. + Add test_random.h to distribution tarball. + Set Heartwood activation height for testnet to 903800. + make-release.py: Versioning changes for 2.1.2. + make-release.py: Updated manpages for 2.1.2. + +Taylor Hornby (15): + Make the equihash validator macro set its output to false when throwing an exception. + Add test for unused bits in the Equihash solution encoding. + Add Python script for checking if dependencies have updates. + Add GitHub API credential + Update list of dependencies to check + Wrap long lines + Cache releases to reduce network usage and improve performance + Make updatecheck.py compatible with python2 + Have make clean delete temporary AFL build directory + Add AFL build directory to .gitignore + Have make clean delete AFL output directories. + Fix bug in updatecheck.py and add utfcpp to its dependency list + Fix typo in updatecheck.py + Update updatecheck.py with the new Rust dependencies and improve the error message in case the untracked dependency list becomes out of date. + Fix undefined behavior in CScriptNum + +Wladimir J. van der Laan (7): + bench: Add crypto hash benchmarks + Kill insecure_random and associated global state + bench: Fix subtle counting issue when rescaling iteration count + bench: Add support for measuring CPU cycles + bench: Fix initialization order in registration + util: Don't set strMiscWarning on every exception + test_framework: detect failure of bitcoind startup + +Yuri Zhykin (1): + bench: Added base58 encoding/decoding benchmarks + +avnish (14): + changed block_test to BlockTests + changed test names from _ to CamelCase + changed header_size_is_expected to HeaderSizeIsExpected + changed "equihash_tests" to EquihashTests + changed founders_reward_test to FoundersRewardTest + changes tests to camelcase + chnged keystore_tests to KeystoreTests + changed libzcash_utils to LibzcashUtils + changed test to CamelCase + changed test to CamelCase + changed test to CamelCase + changed seven_eq_seven to SevenEqSeven + changed txid_tests to TxidTests + changed wallet_zkeys_test to WalletZkeysTest + +avnish98 (1): + requested changes are rectified + +ca333 (2): + update libsodium to v1.0.18 + fix dead openssl download path + +gladcow (4): + Show reindex state in metrics + Use processed file size as progress in metrics during reindex + Byte sizes format + Move reindex progress globals to metrics.h/cpp + +Marshall Gaucher (74): + update /usr/bin/env; fix print conventions + update test_framework modules + Update rpc-test/test_framework to Py3 convention,modules,encoding + Update ignored testScriptsExt to Python3 + Update python3 env path, remove python 2.7 assert + Update hexlify for encoding, update to py3 io module + Update py3 env path, remove py2 assert + Update py2 conventions to py3, remove py2 env and assert + Update py2 conventions to py3, update Decimal calls + Update py2 env path, remove py2 assert + Update py2 env path, remove py2 assert + Update py2 env path, remove py2 assert, update filter to return list for py3 + Update py2 env path, remove py2 assert, update http module and assert encoding + Update cmp to py3 functions, update map return to list for py3 + Standard py2 to py3 updates + Update py2 modules to py3, update encoding to be py3 compatible + Update to py3 conventions, update decimal calls to be consistent + Update to py3 conventions, update filter to return list + update to py3 conventions, update range to return list for py3 + update to py3 convention, update execfile to py3 call + update to py3 conventions, update cmp to be py3 compatible, update map to return list for py3 + update to py3 conventions, preserve ipv6 patch + update str cast to prevent address assert issues + clean up binascii call + Add keyerror execption + update to py3 env path + update to py3 conventions, update functions to be upstream consistent + update to py3 conventions, clean up code to be upstream consistent + update to py3 encodings + update encoding, decoding, serialize funcs for py3 + Update type to be decimal + update to py3 conventions, BUG with last assert_equal + Update io modules for py3, ISSUE with create_transaction function + Update to py3, ISSUE with encoding + Update to py3, ISSUE with encoding + Update to py3, ISSUE with encoding in create_block + Update to py3, ISSUE with encoding in create_block + Clean up code not needed from upstream + update io module, fix py3 division, and string encoding + update remaining encoding issues, add pyblake2 + Use more meaningful assert_equal from our original codebase + Clean up code from upstream we dont use + fix except bug for undefined url + Remove semi colons + make import urlparse module consistent,httplib update to py3 + correct update to python3 + clean-up imports, keep string notation consistent, remove spacing + clean up + Use upstream encoding for encodeDecimal + fix type issue + fix initialize statements for imports + clean up initiliaze statements from imports + update type for decimal 0 + remove debug lines from prior commits + clean up to minimize diff + remove u encoding + Fix decimal 0 issues + Clean up import calls + clean up + clean up + clean up + fix url and port issue + cleanups and fixing odd casting + Update json to simplejson to remove unicode and str issue from py2 to py3 + Update py3 division + fix pyflakes errors + clean up conventions and whitespace + fix string pattern issue on byte object + update comment regarding prior py2 exception + Fix remaining python3 conventions + Update remaining Python3 conventions + Updating remaining python3 conventions + Update #! env for python3 + Update RPCs to support cross platform paths and libs + +murrayn (1): + Add build support for 'gprof' profiling. + +practicalswift (8): + build: Show enabled sanitizers in configure output + Add -ftrapv to DEBUG_CXXFLAGS when --enable-debug is used + Assert that what might look like a possible division by zero is actually unreachable + Replace boost::function with std::function (C++11) + Avoid static analyzer warnings regarding uninitialized arguments + Restore default format state of cout after printing with std::fixed/setprecision + Initialize recently introduced non-static class member lastCycles to zero in constructor + Replace boost::function with std::function (C++11) + +ptschip (1): + Enable python tests for Native Windows + +zancas (3): + update comment, to correctly specify number of methods injected + replace "virtual" with "override" in subclasses + Remove remaining instances of boost::function + diff --git a/depend/zcash/doc/release-notes/release-notes-3.0.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-3.0.0-rc1.md new file mode 100644 index 000000000..3a8acb93b --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-3.0.0-rc1.md @@ -0,0 +1,120 @@ +Notable changes +=============== + +The mainnet activation of the Heartwood network upgrade is supported by this +release, with an activation height of 903000, which should occur in the middle +of July — following the targeted EOS halt of our 2.1.2-3 release. Please upgrade +to this release, or any subsequent release, in order to follow the Heartwood +network upgrade. + +The following two ZIPs are being deployed as part of this upgrade: + +- [ZIP 213: Shielded Coinbase](https://zips.z.cash/zip-0213) +- [ZIP 221: FlyClient - Consensus-Layer Changes](https://zips.z.cash/zip-0221) + +In order to help the ecosystem prepare for the mainnet activiation, Heartwood +has already been activated on the Zcash testnet. Any node version 2.1.2 or +higher, including this release, supports the Heartwood activation on testnet. + +## Mining to Sapling addresses + +After the mainnet activation of Heartwood, miners can mine directly into a +Sapling shielded address. Miners should wait until after Heartwood activation +before they make changes to their configuration to leverage this new feature. +After activation of Heartwood, miners can add `mineraddress=SAPLING_ADDRESS` to +their `zcash.conf` file, where `SAPLING_ADDRESS` represents a Sapling address +that can be generated locally with the `z_getnewaddress` RPC command. Restart +your node, and block templates produced by the `getblocktemplate` RPC command +will now have coinbase transactions that mine directly into this shielded +address. +Changelog +========= + +Aaron Clauson (1): + Minimal code changes to allow msvc compilation. + +Adam Langley (1): + Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with link-time optimization. + +Alfredo Garcia (12): + fix rpc testcase + add blockheight, blockindex and blocktime to z_listreceivedbyaddress + change time to blocktime in help + add status to transactions + minor fix + minor cleanup style, var names + Add a new safe chars rule for node version string + fix wallet nullifiers test + Fix typo + add a test case + implement z_getnotescount api call + remove not needed help parameters to dump and import impl + +Ben Wilson (4): + Added Dockerfile to contrib with README + Fixed README grammar, reuse Dockerfile vars + Fixed Docker README grammar + Dockerfiles for zcashd CI builds + +Daira Hopwood (2): + Fix a null pointer dereference that occurs when formatting an error message, if we haven't activated an upgrade as expected. + Explicitly assert that chainActive[upgrade.nActivationHeight] is non-null at this point. + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (5): + Use BOOST_SCOPE_EXIT_TPL to clean and free datValue in CDB::Read + Improve memory_cleanse documentation + Add NU4 to upgrade list + Add NU4 test helpers + Update URLs for prior network upgrades + +Jonathan "Duke" Leto (1): + Add confirmations to z_listreceivedbyaddress + +Kris Nuttycombe (21): + Add a test reproducing the off-by-one error. + Check network reunification. + Narrow down the test case. + Make the test reproduce the actual off-by-one error in rewind length. + Fix #4119. + The last valid height condition reads better flipped. + Restart node in a chain split state to allow the test to complete. + Trivial comment. + Remove option to load new blocks from ConnectTip + Make condition closer to original, Fix incorrect comment. + Ensure that we don't pass a null block pointer to ConnectTip. + Update all crates. + Update to the Cargo V2 lockfile format. + Clean up imports in sapling_rewind_check.py + Use `%x` formatter for branch id hex string in test_framework/util.py + Update qa/rpc-tests/test_framework/mininode.py + Update qa/rpc-tests/sapling_rewind_check.py + Add Zcash copyright to sapling_rewind_check.py + Update test description and clarify internal comments. + Revert "Update qa/rpc-tests/sapling_rewind_check.py" + Remove unused imports. + +Sean Bowe (6): + Update minimum chain work on testnet to reflect Heartwood activation. + Pass DO_NOT_UPDATE_CONFIG_SCRIPTS=1 to autogen.sh in libsodium dependency, to avoid updating config scripts over the network. + Set the Heartwood activation height to 903000. + Bump the protocol version, as this node supports Heartwood on mainnet. + make-release.py: Versioning changes for 3.0.0-rc1. + make-release.py: Updated manpages for 3.0.0-rc1. + +Taylor Hornby (2): + Add univalue to updatecheck.py and update univalue, removing calls to deprecated methods + Avoid names starting with __. + +Thomas Snider (1): + [wallet] Securely erase potentially sensitive keys/values + +Tim Ruffing (2): + Clean up logic in memory_cleanse() for MSVC + Improve documentation of memory_cleanse() + +therealyingtong (1): + Fix off-by-one error in CreateNewBlock() + diff --git a/depend/zcash/doc/release-notes/release-notes-3.0.0.md b/depend/zcash/doc/release-notes/release-notes-3.0.0.md new file mode 100644 index 000000000..479636a56 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-3.0.0.md @@ -0,0 +1,130 @@ +Notable changes +=============== + +The mainnet activation of the Heartwood network upgrade is supported by this +release, with an activation height of 903000, which should occur in the middle +of July — following the targeted EOS halt of our 2.1.2-3 release. Please upgrade +to this release, or any subsequent release, in order to follow the Heartwood +network upgrade. + +The following two ZIPs are being deployed as part of this upgrade: + +- [ZIP 213: Shielded Coinbase](https://zips.z.cash/zip-0213) +- [ZIP 221: FlyClient - Consensus-Layer Changes](https://zips.z.cash/zip-0221) + +In order to help the ecosystem prepare for the mainnet activiation, Heartwood +has already been activated on the Zcash testnet. Any node version 2.1.2 or +higher, including this release, supports the Heartwood activation on testnet. + +## Mining to Sapling addresses + +After the mainnet activation of Heartwood, miners can mine directly into a +Sapling shielded address. Miners should wait until after Heartwood activation +before they make changes to their configuration to leverage this new feature. +After activation of Heartwood, miners can add `mineraddress=SAPLING_ADDRESS` to +their `zcash.conf` file, where `SAPLING_ADDRESS` represents a Sapling address +that can be generated locally with the `z_getnewaddress` RPC command. Restart +your node, and block templates produced by the `getblocktemplate` RPC command +will now have coinbase transactions that mine directly into this shielded +address. + +Changelog +========= + +Aaron Clauson (1): + Minimal code changes to allow msvc compilation. + +Adam Langley (1): + Switch memory_cleanse implementation to BoringSSL's to ensure memory clearing even with link-time optimization. + +Alfredo Garcia (12): + fix rpc testcase + add blockheight, blockindex and blocktime to z_listreceivedbyaddress + change time to blocktime in help + add status to transactions + minor fix + minor cleanup style, var names + Add a new safe chars rule for node version string + fix wallet nullifiers test + Fix typo + add a test case + implement z_getnotescount api call + remove not needed help parameters to dump and import impl + +Ben Wilson (4): + Added Dockerfile to contrib with README + Fixed README grammar, reuse Dockerfile vars + Fixed Docker README grammar + Dockerfiles for zcashd CI builds + +Daira Hopwood (2): + Fix a null pointer dereference that occurs when formatting an error message, if we haven't activated an upgrade as expected. + Explicitly assert that chainActive[upgrade.nActivationHeight] is non-null at this point. + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (5): + Use BOOST_SCOPE_EXIT_TPL to clean and free datValue in CDB::Read + Improve memory_cleanse documentation + Add NU4 to upgrade list + Add NU4 test helpers + Update URLs for prior network upgrades + +Jonathan "Duke" Leto (1): + Add confirmations to z_listreceivedbyaddress + +Kris Nuttycombe (25): + Add a test reproducing the off-by-one error. + Check network reunification. + Narrow down the test case. + Make the test reproduce the actual off-by-one error in rewind length. + Fix #4119. + The last valid height condition reads better flipped. + Restart node in a chain split state to allow the test to complete. + Trivial comment. + Remove option to load new blocks from ConnectTip + Make condition closer to original, Fix incorrect comment. + Ensure that we don't pass a null block pointer to ConnectTip. + Update all crates. + Update to the Cargo V2 lockfile format. + Clean up imports in sapling_rewind_check.py + Use `%x` formatter for branch id hex string in test_framework/util.py + Update qa/rpc-tests/test_framework/mininode.py + Update qa/rpc-tests/sapling_rewind_check.py + Add Zcash copyright to sapling_rewind_check.py + Update test description and clarify internal comments. + Revert "Update qa/rpc-tests/sapling_rewind_check.py" + Remove unused imports. + Add baseline for golden testing across network upgrade boundaries. + Update golden test for heartwood network upgrade. + Fully remove the regtest tree from restored nodes. + Remove unused imports. + +Sean Bowe (11): + Add NU4 activation to golden test. + Update minimum chain work on testnet to reflect Heartwood activation. + Pass DO_NOT_UPDATE_CONFIG_SCRIPTS=1 to autogen.sh in libsodium dependency, to avoid updating config scripts over the network. + Set the Heartwood activation height to 903000. + Bump the protocol version, as this node supports Heartwood on mainnet. + make-release.py: Versioning changes for 3.0.0-rc1. + make-release.py: Updated manpages for 3.0.0-rc1. + make-release.py: Updated release notes and changelog for 3.0.0-rc1. + Set deprecation of 3.0.0 to target EOS halt mid-September. + make-release.py: Versioning changes for 3.0.0. + make-release.py: Updated manpages for 3.0.0. + +Taylor Hornby (2): + Add univalue to updatecheck.py and update univalue, removing calls to deprecated methods + Avoid names starting with __. + +Thomas Snider (1): + [wallet] Securely erase potentially sensitive keys/values + +Tim Ruffing (2): + Clean up logic in memory_cleanse() for MSVC + Improve documentation of memory_cleanse() + +therealyingtong (1): + Fix off-by-one error in CreateNewBlock() + diff --git a/depend/zcash/doc/release-notes/release-notes-3.1.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-3.1.0-rc1.md new file mode 100644 index 000000000..c994b5971 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-3.1.0-rc1.md @@ -0,0 +1,243 @@ +Notable changes +=============== + +Network Upgrade 4: Canopy +-------------------------- + +The code preparations for the Canopy network upgrade are finished and included in this release. The following ZIPs are being deployed: + +- [ZIP 207: Funding Streams](https://zips.z.cash/zip-0207) +- [ZIP 211: Disabling Addition of New Value to the Sprout Value Pool](https://zips.z.cash/zip-0211) +- [ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext](https://zips.z.cash/zip-0212) +- [ZIP 214: Consensus rules for a Zcash Development Fund](https://zips.z.cash/zip-0214) +- [ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules](https://zips.z.cash/zip-0215) + +Canopy will activate on testnet at height TODO, and can also be activated at a specific height in regtest mode by setting the config option `-nuparams=0xe9ff75a6:HEIGHT`. + +Canopy will activate on mainnet at height 1046400. + +See [ZIP 251](https://zips.z.cash/zip-0251) for additional information about the deployment process for Canopy. + +Flush witness data to disk only when it's consistent +----------------------------------------------------- +This fix prevents the wallet database from getting into an inconsistent state. By flushing witness data to disk from the wallet thread instead of the main thread, we ensure that the on-disk block height is always the same as the witness data height. Previously, the database occasionally got into a state where the latest block height was one ahead of the witness data. This then triggered an assertion failure in `CWallet::IncrementNoteWitnesses()` upon restarting after a zcashd shutdown. + +Note that this code change will not automatically repair a data directory that has been affected by this problem; that requires starting zcashd with the `-rescan` or `-reindex` options. + +New DNS seeders +---------------- +DNS seeders hosted at "zfnd.org" and "yolo.money" have been added to the list in `chainparams.cpp`. They're running [CoreDNS](https://coredns.io) with a [Zcash crawler plugin](https://github.com/ZcashFoundation/dnsseeder), the result of a Zcash Foundation in-house development effort to replace `zcash-seeder` with something memory-safe and easier to maintain. + +These are validly operated seeders per the [existing policy](https://zcash.readthedocs.io/en/latest/rtd_pages/dnsseed_policy.html). For general questions related to either seeder, contact george@zfnd.org or mention @gtank in the Zcash Foundation's Discord. For bug reports, open an issue on the [dnsseeder](https://github.com/ZcashFoundation/dnsseeder) repo. + +Changed command-line options +----------------------------- +- `-debuglogfile=` can be used to specify an alternative debug logging file. + +RPC methods +------------ +- `joinSplitPubKey` and `joinSplitSig` have been added to verbose transaction outputs. This enables the transaction's binary form to be fully reconstructed from the RPC output. +- The output of `getblockchaininfo` now includes an `estimatedheight` parameter. This can be shown in UIs as an indication of the current chain height while `zcashd` is syncing, but should not be relied upon when creating transactions. + +Metrics screen +----------------------- +- A progress bar is now visible when in Initial Block Download mode, showing both the prefetched headers and validated blocks. It is only printed for TTY output. Additionally, the "not mining" message is no longer shown on mainnet, as the built-in CPU miner is not effective at the current network difficulty. +- The number of block headers prefetched during Initial Block Download is now displayed alongside the number of validated blocks. With current compile-time defaults, a Zcash node prefetches up to 160 block headers per request without a limit on how far it can prefetch, but only up to 16 full blocks at a time. + +Changelog +========= + +Alfredo Garcia (28): + add estimatedheight to getblockchaininfo + add documentation and command line parsing to afl scripts + get fuzzing options from directory + add bool argument to get balance in satoshis to rpc getreceivedbyaddress + add documentation to flag + change argument name + add boolean inZat to getreceivedbyaccount + add boolean inZat to getbalance + add boolean inZat to z_getbalance + add amountZat field to listreceivedbyaddress and listreceivedbyaccount + add amountZat field to listtransactions, gettransaction and listsinceblock + add amountZat field to listunspent + add amountZat field to z_listreceivedbyaddress + replace with AssertionError assert_equal in receivedby.py + Fix casting in wallet.py + simplify inzat balances logic + Fix casting in listtransactions.py + add MINOR_CURRENCY_UNIT + remove additional not needed casts from py tests + change name of harden option + fix test cases + fix sort of options + remove not needed comments from wallet.py + update docs + add new parameters to rpc client and fix some bugs + initialize size_t + fix/improve docs + add log aporximation to metrics solution rates + +Anthony Towns (1): + test: Add tests for `-debuglogfile` with subdirs + +Daira Hopwood (15): + Rename NU4 to Canopy in constant and function names. + Rename golden/nu4.tar.gz to canopy.tar.gz. + Missing NU4->Canopy renames. + Remove unused import in qa/rpc-tests/listtransactions.py + Remove an unused CCriticalSection. + Add GetActiveFundingStreams function. + Tests for changes to getblocksubsidy. + Change getblocksubsidy RPC to take into account funding streams. + Use ValueFromAmount instead of double arithmetic, and improve variable names. + Cosmetic spacing changes. + Apply suggestions from code review + Change the format of `getblocksubsidy` output to use an array of funding stream objects. + Clean up some iterator usage. + Remove an unnecessary iterator increment. + Another cleanup. + +Danny Willems (3): + librustzcash: make the header C compatible + Use assert.h instead of define manually static_assert + Use preprocessor for ENTRY_SERIALIZED_LENGTH + +Eirik Ogilvie-Wigley (2): + Resolve decimal vs float issues + Various improvements + +George Tankersley (1): + Add ZF and gtank's DNS seeders + +Jack Grigg (18): + Use the cached consensusBranchId in DisconnectBlock + qa: Smoke test driver + qa: Run Zcash node for smoke tests + qa: Simple smoke tests + qa: Transaction chain smoke test + qa: Use slick-bitcoinrpc for smoke tests + qa: Don't allow smoke tests with mainnet wallet.dat + qa: Improve reliability of smoke tests + qa: Improve reliability of smoke test cleanup + metrics: Fix indents + metrics: Draw IBD progress bar showing headers and blocks + metrics: Don't show "not mining" text for mainnet + qa: Add --use-faucet flag to smoke tests + qa: Remove unused timeout configuration from wait_for_balance + qa: Add --automate flag to smoke tests + metrics: Switch to ANSI colour codes for progress bar + metrics: Only print IBD progress bar on TTY + Implement zip-207 and zip-214. + +Kris Nuttycombe (29): + Identify `-fundingstream` parameter as being regtest-only + Use for..: rather than BOOST_FOREACH + Trivial error message fix. + Minor fixes for ZIP-207 review comments. + Trivial copyright fix. + Replace BOOST_FOREACH with for..: + Qualified imports of std:: types + Capitalization fixes from code review + Minor naming change FundingStreamShare -> FundingStreamElement + Record-constructor syntax for funding stream initialization. + Update HalvingHeight documentation. + Fix pyflakes. + Fix funding stream end-height-exclusion bugs + Add `RegtestDeactivateCanopy` calls to restore shared regtest params. + Move test-only code into test sources. + Trivial comment correction. + Minor help message correction. + Pass by const reference where possible. + Use uint32_t for vFundingStreams indexing. + Fix incorrect subtraction of Halving(blossomActivationHeight) from halvingIndex + Fix ordering of transparent outputs such that miner reward is vout[0] + Remove assertion that was breaking regtest in the case that blossom activates after the halving. + Use for..in rather than an indexed loop. + Make evident the relationship between chainparams and key IO. + Rename KeyInfo -> KeyConstants and move out of Consensus namespace. + Fix typo in constant. + Fix assertion check in GetBlockSubsidy + Apply suggestions from code review + Trivial whitespace fix. + +Larry Ruane (7): + add python test to reproduce bug 4301 + flush witness cache correctly + review, cleanup: eliminate uninitialized variable + self.sync_all(), not time.sleep(4) + fix pyflakes CI errors + undo flushing witness data on shutdown + sync before stopping nodes + +Rod Vagg (1): + Add joinSplitPubKey and joinSplitSig to RPC + +Sean Bowe (23): + Add implementations of PRF_expand calls that obtain esk and rcm. + Remove bare SaplingNote constructor. + Add a getter method to obtain rcm from a Sapling note plaintext. + Add support for receiving v2 Sapling note plaintexts. + Change transaction builder and miner to use v2 Sapling note plaintexts after Canopy activates. + Make ed25519-zebra available via librustzcash. + Change to version of ed25519-zebra crate which is compliant with ZIP 215. + Enforce ZIP 215 rules upon activation of Canopy. + Add test that a weird signature successfully validates. + Remove bincode crate. + Remove unused curve25519-dalek dev-dependency. + Minor adjustments to librustzcash and tests. + Redirect git checkouts of ebfull/ed25519-zebra through our vendored sources in offline mode. + Require that shielded coinbase output note plaintexts are version 2 if Canopy is active. + Make transaction builder take the next block height into account for use of v2 note plaintexts. + Turn return values for libsodium-like API into constants for clarity. + Add more exhaustive tests for ZIP 215 compatibility. + Cargo fmt + Remove unused imports from remove_sprout_shielding RPC test. + Migrate ZIP 215 test vectors to gtest suite. + Change LIBSODIUM_ERROR to -1. + Hash "Zcash" to align tests with ZIP 215 test vectors. + Remove outdated comment. + +Solar Designer (2): + Fix typos in ProcessMessage() "headers" + During initial blocks download, also report the number of headers + +Taylor Hornby (3): + Fix undefined behavior in gtest tests + Add missing header for std::invalid_argument + Fix bug in CScheduler + +Wladimir J. van der Laan (3): + Add `-debuglogfile` option + test: Add test for `-debuglogfile` + doc: Update release notes for `-debuglogfile` + +Marshall Gaucher (1): + Add helpers for tapping and donating to the testnet faucet + +therealyingtong (22): + Add RPC tests for post-Heartwood rollback + Reject v1 plaintexts after grace period + Check epk vs esk whenever caller has esk + Refactor SaplingNotePlaintext::decrypt + Add gtests for v2 plaintexts + Add contextual check to main.cpp + Add gtests + Add checks to z_ methods in rpcwallet + Add RPC tests + Replace leadByte in SaplingNote with is_zip_212 + Throw error in plaintext deserialization + Pass pindex to AddToWalletIfInvolvingMe() + Remove plaintext check from AddSaplingSpend + Remove plaintext check from GetFilteredNotes + Refactor bool is_zip_212 to enum Zip212Enabled + Minor changes + Remove old SaplingNote() constructor + Pass nHeight instead of pindex to AddToWalletIfInvolvingMe() + Directly call RegtestActivate* in gtests + Update release notes for v3.1.0 + make-release.py: Versioning changes for 3.1.0-rc1. + make-release.py: Updated manpages for 3.1.0-rc1. + +ying tong (1): + Apply suggestions from code review + diff --git a/depend/zcash/doc/release-notes/release-notes-3.1.0-rc2.md b/depend/zcash/doc/release-notes/release-notes-3.1.0-rc2.md new file mode 100644 index 000000000..e3ec7680a --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-3.1.0-rc2.md @@ -0,0 +1,250 @@ +Notable changes +=============== + +Network Upgrade 4: Canopy +-------------------------- + +The code preparations for the Canopy network upgrade are finished and included in this release. The following ZIPs are being deployed: + +- [ZIP 207: Funding Streams](https://zips.z.cash/zip-0207) +- [ZIP 211: Disabling Addition of New Value to the Sprout Value Pool](https://zips.z.cash/zip-0211) +- [ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext](https://zips.z.cash/zip-0212) +- [ZIP 214: Consensus rules for a Zcash Development Fund](https://zips.z.cash/zip-0214) +- [ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules](https://zips.z.cash/zip-0215) + +Canopy will activate on testnet at height TODO, and can also be activated at a specific height in regtest mode by setting the config option `-nuparams=0xe9ff75a6:HEIGHT`. Note that v3.1.0-rc2 does not enable Canopy support on the testnet. + +Canopy will activate on mainnet at height 1046400. + +See [ZIP 251](https://zips.z.cash/zip-0251) for additional information about the deployment process for Canopy. + +Flush witness data to disk only when it's consistent +----------------------------------------------------- +This fix prevents the wallet database from getting into an inconsistent state. By flushing witness data to disk from the wallet thread instead of the main thread, we ensure that the on-disk block height is always the same as the witness data height. Previously, the database occasionally got into a state where the latest block height was one ahead of the witness data. This then triggered an assertion failure in `CWallet::IncrementNoteWitnesses()` upon restarting after a zcashd shutdown. + +Note that this code change will not automatically repair a data directory that has been affected by this problem; that requires starting zcashd with the `-rescan` or `-reindex` options. + +New DNS seeders +---------------- +DNS seeders hosted at "zfnd.org" and "yolo.money" have been added to the list in `chainparams.cpp`. They're running [CoreDNS](https://coredns.io) with a [Zcash crawler plugin](https://github.com/ZcashFoundation/dnsseeder), the result of a Zcash Foundation in-house development effort to replace `zcash-seeder` with something memory-safe and easier to maintain. + +These are validly operated seeders per the [existing policy](https://zcash.readthedocs.io/en/latest/rtd_pages/dnsseed_policy.html). For general questions related to either seeder, contact george@zfnd.org or mention @gtank in the Zcash Foundation's Discord. For bug reports, open an issue on the [dnsseeder](https://github.com/ZcashFoundation/dnsseeder) repo. + +Changed command-line options +----------------------------- +- `-debuglogfile=` can be used to specify an alternative debug logging file. + +RPC methods +------------ +- `joinSplitPubKey` and `joinSplitSig` have been added to verbose transaction outputs. This enables the transaction's binary form to be fully reconstructed from the RPC output. +- The output of `getblockchaininfo` now includes an `estimatedheight` parameter. This can be shown in UIs as an indication of the current chain height while `zcashd` is syncing, but should not be relied upon when creating transactions. + +Metrics screen +----------------------- +- A progress bar is now visible when in Initial Block Download mode, showing both the prefetched headers and validated blocks. It is only printed for TTY output. Additionally, the "not mining" message is no longer shown on mainnet, as the built-in CPU miner is not effective at the current network difficulty. +- The number of block headers prefetched during Initial Block Download is now displayed alongside the number of validated blocks. With current compile-time defaults, a Zcash node prefetches up to 160 block headers per request without a limit on how far it can prefetch, but only up to 16 full blocks at a time. + +Changelog +========= + +Alfredo Garcia (28): + add estimatedheight to getblockchaininfo + add documentation and command line parsing to afl scripts + get fuzzing options from directory + add bool argument to get balance in satoshis to rpc getreceivedbyaddress + add documentation to flag + change argument name + add boolean inZat to getreceivedbyaccount + add boolean inZat to getbalance + add boolean inZat to z_getbalance + add amountZat field to listreceivedbyaddress and listreceivedbyaccount + add amountZat field to listtransactions, gettransaction and listsinceblock + add amountZat field to listunspent + add amountZat field to z_listreceivedbyaddress + replace with AssertionError assert_equal in receivedby.py + Fix casting in wallet.py + simplify inzat balances logic + Fix casting in listtransactions.py + add MINOR_CURRENCY_UNIT + remove additional not needed casts from py tests + change name of harden option + fix test cases + fix sort of options + remove not needed comments from wallet.py + update docs + add new parameters to rpc client and fix some bugs + initialize size_t + fix/improve docs + add log aporximation to metrics solution rates + +Anthony Towns (1): + test: Add tests for `-debuglogfile` with subdirs + +Daira Hopwood (17): + Rename NU4 to Canopy in constant and function names. + Rename golden/nu4.tar.gz to canopy.tar.gz. + Missing NU4->Canopy renames. + Remove unused import in qa/rpc-tests/listtransactions.py + Remove an unused CCriticalSection. + Add GetActiveFundingStreams function. + Tests for changes to getblocksubsidy. + Change getblocksubsidy RPC to take into account funding streams. + Use ValueFromAmount instead of double arithmetic, and improve variable names. + Cosmetic spacing changes. + Apply suggestions from code review + Change the format of `getblocksubsidy` output to use an array of funding stream objects. + Clean up some iterator usage. + Remove an unnecessary iterator increment. + Another cleanup. + Add key_constants.h to src/Makefile.am. + Fix an unintended consensus change in decryption of coinbase outputs. + +Danny Willems (3): + librustzcash: make the header C compatible + Use assert.h instead of define manually static_assert + Use preprocessor for ENTRY_SERIALIZED_LENGTH + +Eirik Ogilvie-Wigley (2): + Resolve decimal vs float issues + Various improvements + +George Tankersley (1): + Add ZF and gtank's DNS seeders + +Jack Grigg (18): + Use the cached consensusBranchId in DisconnectBlock + qa: Smoke test driver + qa: Run Zcash node for smoke tests + qa: Simple smoke tests + qa: Transaction chain smoke test + qa: Use slick-bitcoinrpc for smoke tests + qa: Don't allow smoke tests with mainnet wallet.dat + qa: Improve reliability of smoke tests + qa: Improve reliability of smoke test cleanup + metrics: Fix indents + metrics: Draw IBD progress bar showing headers and blocks + metrics: Don't show "not mining" text for mainnet + qa: Add --use-faucet flag to smoke tests + qa: Remove unused timeout configuration from wait_for_balance + qa: Add --automate flag to smoke tests + metrics: Switch to ANSI colour codes for progress bar + metrics: Only print IBD progress bar on TTY + Implement zip-207 and zip-214. + +Kris Nuttycombe (30): + Identify `-fundingstream` parameter as being regtest-only + Use for..: rather than BOOST_FOREACH + Trivial error message fix. + Minor fixes for ZIP-207 review comments. + Trivial copyright fix. + Replace BOOST_FOREACH with for..: + Qualified imports of std:: types + Capitalization fixes from code review + Minor naming change FundingStreamShare -> FundingStreamElement + Record-constructor syntax for funding stream initialization. + Update HalvingHeight documentation. + Fix pyflakes. + Fix funding stream end-height-exclusion bugs + Add `RegtestDeactivateCanopy` calls to restore shared regtest params. + Move test-only code into test sources. + Trivial comment correction. + Minor help message correction. + Pass by const reference where possible. + Use uint32_t for vFundingStreams indexing. + Fix incorrect subtraction of Halving(blossomActivationHeight) from halvingIndex + Fix ordering of transparent outputs such that miner reward is vout[0] + Use ed25519-zebra from crates.io. + Remove assertion that was breaking regtest in the case that blossom activates after the halving. + Use for..in rather than an indexed loop. + Make evident the relationship between chainparams and key IO. + Rename KeyInfo -> KeyConstants and move out of Consensus namespace. + Fix typo in constant. + Fix assertion check in GetBlockSubsidy + Apply suggestions from code review + Trivial whitespace fix. + +Larry Ruane (7): + add python test to reproduce bug 4301 + flush witness cache correctly + review, cleanup: eliminate uninitialized variable + self.sync_all(), not time.sleep(4) + fix pyflakes CI errors + undo flushing witness data on shutdown + sync before stopping nodes + +Rod Vagg (1): + Add joinSplitPubKey and joinSplitSig to RPC + +Sean Bowe (23): + Add implementations of PRF_expand calls that obtain esk and rcm. + Remove bare SaplingNote constructor. + Add a getter method to obtain rcm from a Sapling note plaintext. + Add support for receiving v2 Sapling note plaintexts. + Change transaction builder and miner to use v2 Sapling note plaintexts after Canopy activates. + Make ed25519-zebra available via librustzcash. + Change to version of ed25519-zebra crate which is compliant with ZIP 215. + Enforce ZIP 215 rules upon activation of Canopy. + Add test that a weird signature successfully validates. + Remove bincode crate. + Remove unused curve25519-dalek dev-dependency. + Minor adjustments to librustzcash and tests. + Redirect git checkouts of ebfull/ed25519-zebra through our vendored sources in offline mode. + Require that shielded coinbase output note plaintexts are version 2 if Canopy is active. + Make transaction builder take the next block height into account for use of v2 note plaintexts. + Turn return values for libsodium-like API into constants for clarity. + Add more exhaustive tests for ZIP 215 compatibility. + Cargo fmt + Remove unused imports from remove_sprout_shielding RPC test. + Migrate ZIP 215 test vectors to gtest suite. + Change LIBSODIUM_ERROR to -1. + Hash "Zcash" to align tests with ZIP 215 test vectors. + Remove outdated comment. + +Solar Designer (2): + Fix typos in ProcessMessage() "headers" + During initial blocks download, also report the number of headers + +Taylor Hornby (3): + Fix undefined behavior in gtest tests + Add missing header for std::invalid_argument + Fix bug in CScheduler + +Wladimir J. van der Laan (3): + Add `-debuglogfile` option + test: Add test for `-debuglogfile` + doc: Update release notes for `-debuglogfile` + +Marshall Gaucher (1): + Add helpers for tapping and donating to the testnet faucet + +therealyingtong (26): + Add RPC tests for post-Heartwood rollback + Reject v1 plaintexts after grace period + Check epk vs esk whenever caller has esk + Refactor SaplingNotePlaintext::decrypt + Add gtests for v2 plaintexts + Add contextual check to main.cpp + Add gtests + Add checks to z_ methods in rpcwallet + Add RPC tests + Replace leadByte in SaplingNote with is_zip_212 + Throw error in plaintext deserialization + Pass pindex to AddToWalletIfInvolvingMe() + Remove plaintext check from AddSaplingSpend + Remove plaintext check from GetFilteredNotes + Refactor bool is_zip_212 to enum Zip212Enabled + Minor changes + Remove old SaplingNote() constructor + Pass nHeight instead of pindex to AddToWalletIfInvolvingMe() + Directly call RegtestActivate* in gtests + Update release notes for v3.1.0 + make-release.py: Versioning changes for 3.1.0-rc1. + make-release.py: Updated manpages for 3.1.0-rc1. + make-release.py: Updated release notes and changelog for 3.1.0-rc1. + Undo manual DEPRECATION_HEIGHT + make-release.py: Versioning changes for 3.1.0-rc2. + make-release.py: Updated manpages for 3.1.0-rc2. + +ying tong (1): + Apply suggestions from code review + diff --git a/depend/zcash/doc/release-notes/release-notes-3.1.0.md b/depend/zcash/doc/release-notes/release-notes-3.1.0.md new file mode 100644 index 000000000..b96995c95 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-3.1.0.md @@ -0,0 +1,274 @@ +Notable changes +=============== + +Network Upgrade 4: Canopy +-------------------------- + +The code preparations for the Canopy network upgrade are finished and included in this release. The following ZIPs are being deployed: + +- [ZIP 207: Funding Streams](https://zips.z.cash/zip-0207) +- [ZIP 211: Disabling Addition of New Value to the Sprout Value Pool](https://zips.z.cash/zip-0211) +- [ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext](https://zips.z.cash/zip-0212) +- [ZIP 214: Consensus rules for a Zcash Development Fund](https://zips.z.cash/zip-0214) +- [ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules](https://zips.z.cash/zip-0215) + +Canopy will activate on testnet at height 1028500, and can also be activated at a specific height in regtest mode by setting the config option `-nuparams=0xe9ff75a6:HEIGHT`. Note that v3.1.0 enables Canopy support on the testnet. + +Canopy will activate on mainnet at height 1046400. + +See [ZIP 251](https://zips.z.cash/zip-0251) for additional information about the deployment process for Canopy. + +Debian 8 "Jessie" will no longer be supported after v3.1.0, due to its [end-of-life](https://www.debian.org/News/2020/20200709#:~:text=The%20Debian%20Long%20Term%20Support,security%20updates%20for%20Debian%208) on June 30th, 2020. This will allow us to direct more resources to supporting Debian 10 Buster, other Linux distributions, and other platforms such as Windows and macOS. + +Flush witness data to disk only when it's consistent +----------------------------------------------------- +This fix prevents the wallet database from getting into an inconsistent state. By flushing witness data to disk from the wallet thread instead of the main thread, we ensure that the on-disk block height is always the same as the witness data height. Previously, the database occasionally got into a state where the latest block height was one ahead of the witness data. This then triggered an assertion failure in `CWallet::IncrementNoteWitnesses()` upon restarting after a zcashd shutdown. + +Note that this code change will not automatically repair a data directory that has been affected by this problem; that requires starting zcashd with the `-rescan` or `-reindex` options. + +New DNS seeders +---------------- +DNS seeders hosted at "zfnd.org" and "yolo.money" have been added to the list in `chainparams.cpp`. They're running [CoreDNS](https://coredns.io) with a [Zcash crawler plugin](https://github.com/ZcashFoundation/dnsseeder), the result of a Zcash Foundation in-house development effort to replace `zcash-seeder` with something memory-safe and easier to maintain. + +These are validly operated seeders per the [existing policy](https://zcash.readthedocs.io/en/latest/rtd_pages/dnsseed_policy.html). For general questions related to either seeder, contact george@zfnd.org or mention @gtank in the Zcash Foundation's Discord. For bug reports, open an issue on the [dnsseeder](https://github.com/ZcashFoundation/dnsseeder) repo. + +Changed command-line options +----------------------------- +- `-debuglogfile=` can be used to specify an alternative debug logging file. + +RPC methods +------------ +- `joinSplitPubKey` and `joinSplitSig` have been added to verbose transaction outputs. This enables the transaction's binary form to be fully reconstructed from the RPC output. +- The output of `getblockchaininfo` now includes an `estimatedheight` parameter. This can be shown in UIs as an indication of the current chain height while `zcashd` is syncing, but should not be relied upon when creating transactions. + +Metrics screen +----------------------- +- A progress bar is now visible when in Initial Block Download mode, showing both the prefetched headers and validated blocks. It is only printed for TTY output. Additionally, the "not mining" message is no longer shown on mainnet, as the built-in CPU miner is not effective at the current network difficulty. +- The number of block headers prefetched during Initial Block Download is now displayed alongside the number of validated blocks. With current compile-time defaults, a Zcash node prefetches up to 160 block headers per request without a limit on how far it can prefetch, but only up to 16 full blocks at a time. + +Changelog +========= + +Alfredo Garcia (28): + add estimatedheight to getblockchaininfo + add documentation and command line parsing to afl scripts + get fuzzing options from directory + add bool argument to get balance in satoshis to rpc getreceivedbyaddress + add documentation to flag + change argument name + add boolean inZat to getreceivedbyaccount + add boolean inZat to getbalance + add boolean inZat to z_getbalance + add amountZat field to listreceivedbyaddress and listreceivedbyaccount + add amountZat field to listtransactions, gettransaction and listsinceblock + add amountZat field to listunspent + add amountZat field to z_listreceivedbyaddress + replace with AssertionError assert_equal in receivedby.py + Fix casting in wallet.py + simplify inzat balances logic + Fix casting in listtransactions.py + add MINOR_CURRENCY_UNIT + remove additional not needed casts from py tests + change name of harden option + fix test cases + fix sort of options + remove not needed comments from wallet.py + update docs + add new parameters to rpc client and fix some bugs + initialize size_t + fix/improve docs + add log aporximation to metrics solution rates + +Anthony Towns (1): + test: Add tests for `-debuglogfile` with subdirs + +Daira Hopwood (24): + Rename NU4 to Canopy in constant and function names. + Rename golden/nu4.tar.gz to canopy.tar.gz. + Missing NU4->Canopy renames. + Remove unused import in qa/rpc-tests/listtransactions.py + Remove an unused CCriticalSection. + Add GetActiveFundingStreams function. + Tests for changes to getblocksubsidy. + Change getblocksubsidy RPC to take into account funding streams. + Use ValueFromAmount instead of double arithmetic, and improve variable names. + Cosmetic spacing changes. + Apply suggestions from code review + Change the format of `getblocksubsidy` output to use an array of funding stream objects. + Clean up some iterator usage. + Remove an unnecessary iterator increment. + Another cleanup. + Add key_constants.h to src/Makefile.am. + Fix an unintended consensus change in decryption of coinbase outputs. + More iterator cleanups. + src/metrics.cpp: cosmetic whitespace changes. + Metrics screen: display hash rates using SI prefixes rather than as powers of 2. + Add unit tests for DisplayDuration, DisplaySize, and DisplayHashRate. + Fix the formatting of the 3.0.0 release notes. + Fix --disable-mining build regression. closes #4634 + Allow Equihash validation tests to be compiled with --disable-mining. + +Danny Willems (3): + librustzcash: make the header C compatible + Use assert.h instead of define manually static_assert + Use preprocessor for ENTRY_SERIALIZED_LENGTH + +Eirik Ogilvie-Wigley (2): + Resolve decimal vs float issues + Various improvements + +George Tankersley (1): + Add ZF and gtank's DNS seeders + +Jack Grigg (21): + Use the cached consensusBranchId in DisconnectBlock + qa: Smoke test driver + qa: Run Zcash node for smoke tests + qa: Simple smoke tests + qa: Transaction chain smoke test + qa: Use slick-bitcoinrpc for smoke tests + qa: Don't allow smoke tests with mainnet wallet.dat + qa: Improve reliability of smoke tests + qa: Improve reliability of smoke test cleanup + metrics: Fix indents + metrics: Draw IBD progress bar showing headers and blocks + metrics: Don't show "not mining" text for mainnet + qa: Add --use-faucet flag to smoke tests + qa: Remove unused timeout configuration from wait_for_balance + qa: Add --automate flag to smoke tests + metrics: Switch to ANSI colour codes for progress bar + metrics: Only print IBD progress bar on TTY + Implement zip-207 and zip-214. + Use Rust Equihash validator unconditionally + Remove C++ Equihash validator + Revert "Pass the block height through to CheckEquihashSolution()" + +Kris Nuttycombe (31): + Identify `-fundingstream` parameter as being regtest-only + Use for..: rather than BOOST_FOREACH + Trivial error message fix. + Minor fixes for ZIP-207 review comments. + Trivial copyright fix. + Replace BOOST_FOREACH with for..: + Qualified imports of std:: types + Capitalization fixes from code review + Minor naming change FundingStreamShare -> FundingStreamElement + Record-constructor syntax for funding stream initialization. + Update HalvingHeight documentation. + Fix pyflakes. + Fix funding stream end-height-exclusion bugs + Add `RegtestDeactivateCanopy` calls to restore shared regtest params. + Move test-only code into test sources. + Trivial comment correction. + Minor help message correction. + Pass by const reference where possible. + Use uint32_t for vFundingStreams indexing. + Fix incorrect subtraction of Halving(blossomActivationHeight) from halvingIndex + Fix ordering of transparent outputs such that miner reward is vout[0] + Use ed25519-zebra from crates.io. + Remove assertion that was breaking regtest in the case that blossom activates after the halving. + Use for..in rather than an indexed loop. + Make evident the relationship between chainparams and key IO. + Rename KeyInfo -> KeyConstants and move out of Consensus namespace. + Fix typo in constant. + Fix assertion check in GetBlockSubsidy + Apply suggestions from code review + Trivial whitespace fix. + Zero-initialize HistoryNode values. + +Larry Ruane (7): + add python test to reproduce bug 4301 + flush witness cache correctly + review, cleanup: eliminate uninitialized variable + self.sync_all(), not time.sleep(4) + fix pyflakes CI errors + undo flushing witness data on shutdown + sync before stopping nodes + +Rod Vagg (1): + Add joinSplitPubKey and joinSplitSig to RPC + +Sean Bowe (23): + Add implementations of PRF_expand calls that obtain esk and rcm. + Remove bare SaplingNote constructor. + Add a getter method to obtain rcm from a Sapling note plaintext. + Add support for receiving v2 Sapling note plaintexts. + Change transaction builder and miner to use v2 Sapling note plaintexts after Canopy activates. + Make ed25519-zebra available via librustzcash. + Change to version of ed25519-zebra crate which is compliant with ZIP 215. + Enforce ZIP 215 rules upon activation of Canopy. + Add test that a weird signature successfully validates. + Remove bincode crate. + Remove unused curve25519-dalek dev-dependency. + Minor adjustments to librustzcash and tests. + Redirect git checkouts of ebfull/ed25519-zebra through our vendored sources in offline mode. + Require that shielded coinbase output note plaintexts are version 2 if Canopy is active. + Make transaction builder take the next block height into account for use of v2 note plaintexts. + Turn return values for libsodium-like API into constants for clarity. + Add more exhaustive tests for ZIP 215 compatibility. + Cargo fmt + Remove unused imports from remove_sprout_shielding RPC test. + Migrate ZIP 215 test vectors to gtest suite. + Change LIBSODIUM_ERROR to -1. + Hash "Zcash" to align tests with ZIP 215 test vectors. + Remove outdated comment. + +Solar Designer (2): + Fix typos in ProcessMessage() "headers" + During initial blocks download, also report the number of headers + +Taylor Hornby (3): + Fix undefined behavior in gtest tests + Add missing header for std::invalid_argument + Fix bug in CScheduler + +Wladimir J. van der Laan (3): + Add `-debuglogfile` option + test: Add test for `-debuglogfile` + doc: Update release notes for `-debuglogfile` + +ewillbefull@gmail.com (1): + Add dev fund addresses for testnet NU4 activation. + +Marshall Gaucher (1): + Add helpers for tapping and donating to the testnet faucet + +therealyingtong (35): + Add RPC tests for post-Heartwood rollback + Reject v1 plaintexts after grace period + Check epk vs esk whenever caller has esk + Refactor SaplingNotePlaintext::decrypt + Add gtests for v2 plaintexts + Add contextual check to main.cpp + Add gtests + Add checks to z_ methods in rpcwallet + Add RPC tests + Replace leadByte in SaplingNote with is_zip_212 + Throw error in plaintext deserialization + Pass pindex to AddToWalletIfInvolvingMe() + Remove plaintext check from AddSaplingSpend + Remove plaintext check from GetFilteredNotes + Refactor bool is_zip_212 to enum Zip212Enabled + Minor changes + Remove old SaplingNote() constructor + Pass nHeight instead of pindex to AddToWalletIfInvolvingMe() + Directly call RegtestActivate* in gtests + Update release notes for v3.1.0 + make-release.py: Versioning changes for 3.1.0-rc1. + make-release.py: Updated manpages for 3.1.0-rc1. + make-release.py: Updated release notes and changelog for 3.1.0-rc1. + Undo manual DEPRECATION_HEIGHT + make-release.py: Versioning changes for 3.1.0-rc2. + make-release.py: Updated manpages for 3.1.0-rc2. + make-release.py: Updated release notes and changelog for 3.1.0-rc2. + Edit release notes to specify that rc2 does not enable Canopy support on the testnet + Set Canopy testnet activation height to 1020500 + Set PROTOCOL_VERSION to 170012 + Pass HistoryNode struct to librustzcash FFI + Delay testnet activation height by one week + Use 51 Testnet Dev Fund addresses, and adjust the end heights. + make-release.py: Versioning changes for 3.1.0. + make-release.py: Updated manpages for 3.1.0. + +ying tong (1): + Apply suggestions from code review diff --git a/depend/zcash/doc/release-notes/release-notes-4.0.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.0.0-rc1.md new file mode 100644 index 000000000..b25b85ebd --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.0.0-rc1.md @@ -0,0 +1,276 @@ +Notable changes +=============== + +The mainnet activation of the Canopy network upgrade is supported by the 4.0.0 +release, with an activation height of 1046400, which should occur roughly in the +middle of November — following the targeted EOS halt of our 3.1.0 release. +Please upgrade to this release, or any subsequent release, in order to follow +the Canopy network upgrade. + +The following ZIPs are being deployed as part of this upgrade: + +* [ZIP 207: Funding Streams](https://zips.z.cash/zip-0207) in conjunction with [ZIP 214: Consensus rules for a Zcash Development Fund](https://zips.z.cash/zip-0214) +* [ZIP 211: Disabling Addition of New Value to the Sprout Value Pool](https://zips.z.cash/zip-0211) +* [ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext](https://zips.z.cash/zip-0212) +* [ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules](https://zips.z.cash/zip-0215) + +In order to help the ecosystem prepare for the mainnet activation, Canopy has +already been activated on the Zcash testnet. Any node version 3.1.0 or higher, +including this release, supports the Canopy activation on testnet. + +Disabling new value in the Sprout value pool +-------------------------------------------- + +After the mainnet activation of Canopy, it will not be possible to send funds to +Sprout z-addresses from any _other_ kind of address, as described in [ZIP 211](https://zips.z.cash/zip-0211). +It will still be possible to send funds _from_ a Sprout z-address and to send +funds between Sprout addresses. Users of Sprout z-addresses are encouraged to +use Sapling z-addresses instead, and to migrate their remaining Sprout funds +into a Sapling z-address using the migration utility in zcashd: set `migrate=1` +in your `zcash.conf` file, or use the `z_setmigration` RPC. + +New logging system +------------------ + +The `zcashd` logging system is now powered by the Rust `tracing` crate. This +has two main benefits: + +- `tracing` supports the concept of "spans", which represent periods of time + with a beginning and end. These enable logging additional information about + temporality and causality of events. (Regular log lines, which represent + moments in time, are called `events` in `tracing`.) +- Spans and events are structured, and can record typed data in addition to text + messages. This structure can then be filtered dynamically. + +The existing `-debug=target` config flags are mapped to `tracing` log filters, +and will continue to correctly enable additional logging when starting `zcashd`. +A new `setlogfilter` RPC method has been introduced that enables reconfiguring +the log filter at runtime. See `zcash-cli help setlogfilter` for its syntax. + +As a minor note, `zcashd` no longer reopens the `debug.log` file on `SIGHUP`. +This behaviour was originally introduced in upstream Bitcoin Core to support log +rotation using external tools. `tracing` supports log rotation internally (which +is currently disabled), as well as a variety of interesting backends (such as +`journald` and OpenTelemetry integration); we are investigating how these might +be exposed in future releases. + +Compatibility +------------- +macOS versions earlier than 10.12 (Sierra) are no longer supported. + +Changelog +========= + +Alfredo Garcia (3): + only allow duplicates for certain options of the config + install bdb binaries + add more allowed duplicates + +Andrew Chow (1): + Fix naming of macOS SDK and clarify version + +Carl Dong (8): + contrib: macdeploy: Correctly generate macOS SDK + Adapt rest of tooling to new SDK naming scheme + native_cctools: Don't use libc++ from pinned clang + contrib: macdeploy: Use apple-sdk-tools instead of xar+pbzx + contrib: macdeploy: Remove historical extraction notes + depends: Decouple toolchain + binutils + depends: Specify path to native binaries as clang argument + depends: Add justifications for macOS clang flags + +Charlie O'Keefe (1): + Remove 'jessie' (debian 8) from suites list in linux gitian descriptors + +Cory Fields (14): + crypto: add AES 128/256 CBC classes + crypto: add aes cbc tests + crypter: fix the stored initialization vector size + crypter: constify encrypt/decrypt + crypter: hook up the new aes cbc classes + crypter: add a BytesToKey clone to replace the use of openssl + crypter: add tests for crypter + build: Enumerate ctaes rather than globbing + depends: bump MacOS toolchain + macos: Bump to xcode 11.3.1 and 10.15 SDK + darwin: pass mlinker-version so that clang enables new features + depends: specify libc++ header location for darwin + depends: enable lto support for Apple's ld64 + depends: bump native_cctools for fixed lto with external clang + +Daira Hopwood (6): + zcutil/distclean.sh: remove BDB utility programs. + Update .gitignore. + Fix a return status issue. + Update Makefile.am + Newer version of checksec.sh from https://github.com/slimm609/checksec.sh/commit/a6df608ac077689b2160e521db6601abc7b9e26e + Repair full_test_suite.py for new checksec.sh. + +Dimitris Apostolou (1): + Remove deprecated contrib utilities + +Jack Grigg (67): + Move GrothProof and SproutProof definitions into zcash/Proof.hpp + Remove unused declarations left over from libsnark verification + Make ZCJoinSplit::prove static and remove ZCJoinSplit globals + Move ProofVerifier out of the libzcash namespace + Move JSDescription::Verify to ProofVerifier::VerifySprout + Skip Sprout proof verification for ProofVerifier::Disabled + Send alert to put pre-Heartwood nodes into safe mode. + Squashed 'src/crypto/ctaes/' content from commit 003a4acfc + build: shuffle gtest Makefile so that crypto can be used by the wallet + metrics: Collect general stats before clearing screen + Debian: Add copyright entries for ctaes and secp256k1 + Revert "Rename FALLBACK_DOWNLOAD_PATH to PRIORITY_DOWNLOAD_PATH" + Revert "Try downloading from our mirror first to avoid headaches." + depends: Use FALLBACK_DOWNLOAD_PATH if the primary's hash doesn't match + test: Remove obsolete TransactionBuilder test + Add tracing to librustzcash dependencies + FFI wrapper around tracing crate + Replace C++ logging with tracing logging + Use a tracing EnvFilter directive for -debug flags + Add support for reloading the tracing filter + Add an RPC method for setting the tracing filter directives + Add support for tracing spans + Add some spans to the Zcash codebase + FFI: Extract common codeunit types into a rust/types.h header + tracing: Use 'static constexpr' hack in macros + wallet: Fix logging to satisfy constexpr requirements + FFI: Add missing includes + init: Place additional constraints on pathDebug + rpc: Throw error in setlogfilter if filter reloading fails + tracing: Log field values that aren't valid UTF-8 + tracing: Document macro arguments that MUST be static constant UTF-8 strings + doc: Update release notes for tracing backend + qa: Add tracing dependencies to updatecheck.py + depends: tracing-core 0.1.13 + Revert "Add check-depends step to STAGE_COMMANDS list" + contrib: Update macdeploy README + depends: Rework Rust integration + depends: Add platform-specific overrides for download files + depends: Split check-packages and check-sources across categories + FFI: Fix tracing log path handling on Windows + tracing: Add MAP macro + tracing: Add support for event fields + tracing: Add support for span fields + tracing: Format field values with Display + Add fields to logging in CNode and UpdateTip + util: Use DEBUG level for LogPrint(), leaving INFO for LogPrintf() + tracing: Parse log_path into an Option + tracing: Rework tracing_init into a single function + init: Rework tracing_init call + init: Add spans for initialization and shutdown + Replace libsodium's randombytes_buf with rand_core::OsRng::fill_bytes + consensus: Add assertions for Params::HalvingHeight parameters + consensus: Document the empty conditional branch in ContextualCheckBlock + consensus: Statically check funding stream numerators and denominators + consensus: Clearly gate active funding stream elements on Canopy + Replace libsodium's crypto_sign with ed25519-zebra + ed25519: Panic (triggering abort) if nullptr passed into APIs + test: Update ZIP 215 test cases from ed25519-zebra + depends: Migrate to zcash_* 0.3.0 Rust crates + FFI: Remove circuit parameter hashes from librustzcash_init_zksnark_params + FFI: Migrate to bls12_381 and jubjub crates + depends: cargo update + qa: Update list of postponed crate versions + FFI: Rename to librustzcash_sapling_compute_cmu + FFI: Rename r to rcm + debian: Rename X11 to Expat-with-advertising-clause in copyright + Adjust GetActiveFundingStream* comments + +Kris Nuttycombe (13): + Remove amqp code and Proton library depenencies & flags. + Remove Proton license from contrib/debian/copyright + consensus: Clean up some whitespace and variable names + consensus: Refactor Sprout contextual rules to match the rest + consensus: Remove canopyActive gate around GetActiveFundingStreamElements + consensus: Combine heartwoodActive conditionals + consensus: Add a placeholder for !canopyActive + consensus: Move overwinterActive rules ahead of saplingActive rules + consensus: Combine saplingActive conditionals + consensus: Move Sapling-disabled Overwinter rules above Sapling rules + consensus: Reorder Overwinter+!Sapling rules + consensus: Remove redundant contextual consensus rules + Add comment in lieu of redundant overwinter version check & fix tests. + +Larry Ruane (2): + flush wallet db (SetBestChain()) on clean shutdown + wallet: lock cs_main while accessing chainActive + +LongShao007 (1): + fix bug of bdb.mk + +Per Grön (11): + Get rid of implicit hidden dependencies between test .cpp files + Add missing #includes to test_block.cpp + Add actual header file for utilities in gtest/utils.cpp + Fix linkage issue with consts in primitives/block.h + Remove Checkpoints_tests.cpp + libsnark: Don't (implicitly) rely on other tests initializing the public params + Add missing libsnark initialization call + Don't clobber cwd in rpc_wallet_tests.cpp + Include header files within the source tree using "" instead of <> + Be consistent about what path to include bitcoin-config.h with + Be consistent with how to #include test data headers + +Pieter Wuille (1): + Add ctaes-based constant time AES implementation + +Sean Bowe (4): + Postpone boost 1.74.0 update + Postpone rust updates + make-release.py: Versioning changes for 4.0.0-rc1. + make-release.py: Updated manpages for 4.0.0-rc1. + +Taylor Hornby (5): + Implement system for postponing dependency updates. + Change release instructions to block the release when dependencies are not updated and not postponed. + Enforce pre-release dependency update check in make-release.py + Extend deadline for postponing dependency updates + Add new dependencies to updatecheck.py, add a flag we can use to have our CI test it. + +Ariel Gabizon (1): + explain expiry error + +Benjamin Winston (2): + Added support for afl-clang-fast. + Added libfuzzer support. + +elbandi (3): + Allow configure params directory + Add paramsdir option for manpage + Throw error if -paramsdir not a valid directory + +fanquake (8): + depends: set OSX_MIN_VERSION to 10.10 + doc: mention that macOS 10.10 is now required + scripted-diff: prefer MAC_OSX over __APPLE__ + build: set minimum supported macOS to 10.12 + depends: clang 6.0.1 + depends: native_cctools 921, ld64 409.12, libtapi 1000.10.8 + build: use macOS 10.14 SDK + doc: explain why passing -mlinker-version is required + +noname45688@gmail.com (2): + Updating to Python 3 + Update to Python 3 + +teor (1): + Fix a comment typo in pow.cpp + +Ying Tong Lai (11): + Add Debian8 deprecation to release notes + Add missing curly braces after if statement + Add test for garbage memory in history nodes + Add documentation specific to ZIP 212 + Move esk derivation check to beginning of plaintext_checks_without_height() + Define PRF diversifiers in prf.h + assert(leadbyte == 0x02) after every if(leadbyte != 0x01) + Update doc/release-notes/release-notes-3.1.0.md + Make sure garbage bytes are different + Rename PRV_DIVERSIFIER to PRF_TAG + Add link to ZIP212 in coinbase comment + +Zancas Wilcox (1): + make deprecation.h include consensus/params.h + diff --git a/depend/zcash/doc/release-notes/release-notes-4.0.0.md b/depend/zcash/doc/release-notes/release-notes-4.0.0.md new file mode 100644 index 000000000..cd675c434 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.0.0.md @@ -0,0 +1,290 @@ +Notable changes +=============== + +The mainnet activation of the Canopy network upgrade is supported by the 4.0.0 +release, with an activation height of 1046400, which should occur roughly in the +middle of November — following the targeted EOS halt of our 3.1.0 release. +Please upgrade to this release, or any subsequent release, in order to follow +the Canopy network upgrade. + +The following ZIPs are being deployed as part of this upgrade: + +* [ZIP 207: Funding Streams](https://zips.z.cash/zip-0207) in conjunction with [ZIP 214: Consensus rules for a Zcash Development Fund](https://zips.z.cash/zip-0214) +* [ZIP 211: Disabling Addition of New Value to the Sprout Value Pool](https://zips.z.cash/zip-0211) +* [ZIP 212: Allow Recipient to Derive Sapling Ephemeral Secret from Note Plaintext](https://zips.z.cash/zip-0212) +* [ZIP 215: Explicitly Defining and Modifying Ed25519 Validation Rules](https://zips.z.cash/zip-0215) + +In order to help the ecosystem prepare for the mainnet activation, Canopy has +already been activated on the Zcash testnet. Any node version 3.1.0 or higher, +including this release, supports the Canopy activation on testnet. + +Disabling new value in the Sprout value pool +-------------------------------------------- + +After the mainnet activation of Canopy, it will not be possible to send funds to +Sprout z-addresses from any _other_ kind of address, as described in [ZIP 211](https://zips.z.cash/zip-0211). +It will still be possible to send funds _from_ a Sprout z-address and to send +funds between Sprout addresses. Users of Sprout z-addresses are encouraged to +use Sapling z-addresses instead, and to migrate their remaining Sprout funds +into a Sapling z-address using the migration utility in zcashd: set `migrate=1` +in your `zcash.conf` file, or use the `z_setmigration` RPC. + +New logging system +------------------ + +The `zcashd` logging system is now powered by the Rust `tracing` crate. This +has two main benefits: + +- `tracing` supports the concept of "spans", which represent periods of time + with a beginning and end. These enable logging additional information about + temporality and causality of events. (Regular log lines, which represent + moments in time, are called `events` in `tracing`.) +- Spans and events are structured, and can record typed data in addition to text + messages. This structure can then be filtered dynamically. + +The existing `-debug=target` config flags are mapped to `tracing` log filters, +and will continue to correctly enable additional logging when starting `zcashd`. +A new `setlogfilter` RPC method has been introduced that enables reconfiguring +the log filter at runtime. See `zcash-cli help setlogfilter` for its syntax. + +As a minor note, `zcashd` no longer reopens the `debug.log` file on `SIGHUP`. +This behaviour was originally introduced in upstream Bitcoin Core to support log +rotation using external tools. `tracing` supports log rotation internally (which +is currently disabled), as well as a variety of interesting backends (such as +`journald` and OpenTelemetry integration); we are investigating how these might +be exposed in future releases. + +Compatibility +------------- +macOS versions earlier than 10.12 (Sierra) are no longer supported. + +Changelog +========= + +Alfredo Garcia (3): + only allow duplicates for certain options of the config + install bdb binaries + add more allowed duplicates + +Andrew Chow (1): + Fix naming of macOS SDK and clarify version + +Carl Dong (8): + contrib: macdeploy: Correctly generate macOS SDK + Adapt rest of tooling to new SDK naming scheme + native_cctools: Don't use libc++ from pinned clang + contrib: macdeploy: Use apple-sdk-tools instead of xar+pbzx + contrib: macdeploy: Remove historical extraction notes + depends: Decouple toolchain + binutils + depends: Specify path to native binaries as clang argument + depends: Add justifications for macOS clang flags + +Charlie O'Keefe (1): + Remove 'jessie' (debian 8) from suites list in linux gitian descriptors + +Cory Fields (14): + crypto: add AES 128/256 CBC classes + crypto: add aes cbc tests + crypter: fix the stored initialization vector size + crypter: constify encrypt/decrypt + crypter: hook up the new aes cbc classes + crypter: add a BytesToKey clone to replace the use of openssl + crypter: add tests for crypter + build: Enumerate ctaes rather than globbing + depends: bump MacOS toolchain + macos: Bump to xcode 11.3.1 and 10.15 SDK + darwin: pass mlinker-version so that clang enables new features + depends: specify libc++ header location for darwin + depends: enable lto support for Apple's ld64 + depends: bump native_cctools for fixed lto with external clang + +Daira Hopwood (7): + zcutil/distclean.sh: remove BDB utility programs. + Update .gitignore. + Fix a return status issue. + Update Makefile.am + Newer version of checksec.sh from https://github.com/slimm609/checksec.sh/commit/a6df608ac077689b2160e521db6601abc7b9e26e + Repair full_test_suite.py for new checksec.sh. + Clarify a comment about the ZF and MG addresses + +Dimitris Apostolou (1): + Remove deprecated contrib utilities + +Jack Grigg (65): + Move GrothProof and SproutProof definitions into zcash/Proof.hpp + Remove unused declarations left over from libsnark verification + Make ZCJoinSplit::prove static and remove ZCJoinSplit globals + Move ProofVerifier out of the libzcash namespace + Move JSDescription::Verify to ProofVerifier::VerifySprout + Skip Sprout proof verification for ProofVerifier::Disabled + Send alert to put pre-Heartwood nodes into safe mode. + Squashed 'src/crypto/ctaes/' content from commit 003a4acfc + build: shuffle gtest Makefile so that crypto can be used by the wallet + metrics: Collect general stats before clearing screen + Debian: Add copyright entries for ctaes and secp256k1 + Revert "Rename FALLBACK_DOWNLOAD_PATH to PRIORITY_DOWNLOAD_PATH" + Revert "Try downloading from our mirror first to avoid headaches." + depends: Use FALLBACK_DOWNLOAD_PATH if the primary's hash doesn't match + test: Remove obsolete TransactionBuilder test + Add tracing to librustzcash dependencies + FFI wrapper around tracing crate + Replace C++ logging with tracing logging + Use a tracing EnvFilter directive for -debug flags + Add support for reloading the tracing filter + Add an RPC method for setting the tracing filter directives + Add support for tracing spans + Add some spans to the Zcash codebase + FFI: Extract common codeunit types into a rust/types.h header + tracing: Use 'static constexpr' hack in macros + wallet: Fix logging to satisfy constexpr requirements + FFI: Add missing includes + init: Place additional constraints on pathDebug + rpc: Throw error in setlogfilter if filter reloading fails + tracing: Log field values that aren't valid UTF-8 + tracing: Document macro arguments that MUST be static constant UTF-8 strings + doc: Update release notes for tracing backend + qa: Add tracing dependencies to updatecheck.py + depends: tracing-core 0.1.13 + Revert "Add check-depends step to STAGE_COMMANDS list" + contrib: Update macdeploy README + depends: Rework Rust integration + depends: Add platform-specific overrides for download files + depends: Split check-packages and check-sources across categories + FFI: Fix tracing log path handling on Windows + tracing: Add MAP macro + tracing: Add support for event fields + tracing: Add support for span fields + tracing: Format field values with Display + Add fields to logging in CNode and UpdateTip + util: Use DEBUG level for LogPrint(), leaving INFO for LogPrintf() + tracing: Parse log_path into an Option + tracing: Rework tracing_init into a single function + init: Rework tracing_init call + init: Add spans for initialization and shutdown + Replace libsodium's randombytes_buf with rand_core::OsRng::fill_bytes + consensus: Add assertions for Params::HalvingHeight parameters + consensus: Document the empty conditional branch in ContextualCheckBlock + consensus: Statically check funding stream numerators and denominators + consensus: Clearly gate active funding stream elements on Canopy + Replace libsodium's crypto_sign with ed25519-zebra + ed25519: Panic (triggering abort) if nullptr passed into APIs + test: Update ZIP 215 test cases from ed25519-zebra + depends: Migrate to zcash_* 0.3.0 Rust crates + FFI: Remove circuit parameter hashes from librustzcash_init_zksnark_params + FFI: Migrate to bls12_381 and jubjub crates + depends: cargo update + qa: Update list of postponed crate versions + FFI: Rename to librustzcash_sapling_compute_cmu + FFI: Rename r to rcm + +Kris Nuttycombe (13): + Remove amqp code and Proton library depenencies & flags. + Remove Proton license from contrib/debian/copyright + consensus: Clean up some whitespace and variable names + consensus: Refactor Sprout contextual rules to match the rest + consensus: Remove canopyActive gate around GetActiveFundingStreamElements + consensus: Combine heartwoodActive conditionals + consensus: Add a placeholder for !canopyActive + consensus: Move overwinterActive rules ahead of saplingActive rules + consensus: Combine saplingActive conditionals + consensus: Move Sapling-disabled Overwinter rules above Sapling rules + consensus: Reorder Overwinter+!Sapling rules + consensus: Remove redundant contextual consensus rules + Add comment in lieu of redundant overwinter version check & fix tests. + +Larry Ruane (2): + flush wallet db (SetBestChain()) on clean shutdown + wallet: lock cs_main while accessing chainActive + +LongShao007 (1): + fix bug of bdb.mk + +Per Grön (11): + Get rid of implicit hidden dependencies between test .cpp files + Add missing #includes to test_block.cpp + Add actual header file for utilities in gtest/utils.cpp + Fix linkage issue with consts in primitives/block.h + Remove Checkpoints_tests.cpp + libsnark: Don't (implicitly) rely on other tests initializing the public params + Add missing libsnark initialization call + Don't clobber cwd in rpc_wallet_tests.cpp + Include header files within the source tree using "" instead of <> + Be consistent about what path to include bitcoin-config.h with + Be consistent with how to #include test data headers + +Pieter Wuille (1): + Add ctaes-based constant time AES implementation + +Sean Bowe (13): + Postpone boost 1.74.0 update + Postpone rust updates + make-release.py: Versioning changes for 4.0.0-rc1. + make-release.py: Updated manpages for 4.0.0-rc1. + make-release.py: Updated release notes and changelog for 4.0.0-rc1. + Add release notes to describe the Canopy network upgrade. + Update names of contributors in release notes. + Specify 4.0.0 in release notes + Add dev fund addresses for mainnet. + Set activation height for Canopy on mainnet. + Postpone updates for dependencies until after 4.0.0 release. + make-release.py: Versioning changes for 4.0.0. + make-release.py: Updated manpages for 4.0.0. + +Taylor Hornby (5): + Implement system for postponing dependency updates. + Change release instructions to block the release when dependencies are not updated and not postponed. + Enforce pre-release dependency update check in make-release.py + Extend deadline for postponing dependency updates + Add new dependencies to updatecheck.py, add a flag we can use to have our CI test it. + +Ariel Gabizon (1): + explain expiry error + +Benjamin Winston (2): + Added support for afl-clang-fast. + Added libfuzzer support. + +elbandi (3): + Allow configure params directory + Add paramsdir option for manpage + Throw error if -paramsdir not a valid directory + +fanquake (8): + depends: set OSX_MIN_VERSION to 10.10 + doc: mention that macOS 10.10 is now required + scripted-diff: prefer MAC_OSX over `__APPLE__` + build: set minimum supported macOS to 10.12 + depends: clang 6.0.1 + depends: native_cctools 921, ld64 409.12, libtapi 1000.10.8 + build: use macOS 10.14 SDK + doc: explain why passing -mlinker-version is required + +noname45688@gmail.com (2): + Updating to Python 3 + Update to Python 3 + +Jack Grigg (2): + debian: Rename X11 to Expat-with-advertising-clause in copyright + Adjust GetActiveFundingStream* comments + +teor (1): + Fix a comment typo in pow.cpp + +Ying Tong Lai (7): + Add Debian8 deprecation to release notes + Add missing curly braces after if statement + Add test for garbage memory in history nodes + Add documentation specific to ZIP 212 + Move esk derivation check to beginning of plaintext_checks_without_height() + Define PRF diversifiers in prf.h + assert(leadbyte == 0x02) after every if(leadbyte != 0x01) + +ying tong (4): + Update doc/release-notes/release-notes-3.1.0.md + Make sure garbage bytes are different + Rename PRV_DIVERSIFIER to PRF_TAG + Add link to ZIP212 in coinbase comment + +Zancas Wilcox (1): + make deprecation.h include consensus/params.h + diff --git a/depend/zcash/doc/release-notes/release-notes-4.1.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.1.0-rc1.md new file mode 100644 index 000000000..593f3305e --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.1.0-rc1.md @@ -0,0 +1,382 @@ +Notable changes +=============== + +Migration to Clang and static libc++ +------------------------------------ + +`zcashd` now builds its C++ (and C) dependencies entirely with a pinned version +of Clang, and statically links libc++ instead of dynamically linking libstdc++. +This migration enables us to reliably use newer C++ features while supporting +older LTS platforms, be more confident in the compiler's optimisations, and +leverage security features such as sanitisers and efficient fuzzing. In future, +this will also allow optimizing across the boundary between Rust and C++. + +The system compiler is still used to compile a few native dependencies (used by +the build machine to then compile `zcashd` for the target machine). These will +likely also be migrated to use the pinned Clang in a future release. + +Fast sync for initial block download +------------------------------------ + +The `-ibdskiptxverification` flag allows faster synchronization during initial +block sync, by skipping transaction verification and instead verifying only PoW. +Note that this mode requires checkpoints to be enabled, to make sure that each +block under inspection is an ancestor of the latest checkpoint. + +Convenient testing for invalid note plaintexts +---------------------------------------------- + +After the mainnet activation of Canopy (block 1046400), correct wallet software +will no longer produce v1 note plaintexts (with a lead byte of `0x01`). However, +v1 note plaintexts will continue to be accepted for a grace period of 32256 +blocks (about 4 weeks), as specified in [ZIP 212](https://zips.z.cash/zip-0212). +The new `receiveunsafe` log category complains if an invalid note plaintext is +received. + +Additional lightwalletd and light client RPCs +--------------------------------------------- + +- lightwalletd is now able to retrieve all UTXOs related to a t-address through +the `getaddressutxos` RPC. (Previously, this was only available to the Insight +Explorer.) +- The new `z_gettreestate` RPC returns the Sprout and Sapling treestate at a +given block height or block hash. This makes it easier for light clients to +generate checkpoints. + +Update/removal of several cryptographic dependencies +---------------------------------------------------- + +This release updates secp256k1 to enable the GLV endomorphism optimisation by +default, after the recent expiry of the GLV patents. It also removes OpenSSL, +and replaces libsodium BLAKE2b usage with the [blake2b_simd Rust crate](https://github.com/oconnor663/blake2_simd). + +Changelog +========= + +Aditya Kulkarni (1): + Add a config option to skip transaction verification in IBD mode + +Ahmad Kazi (1): + [Trivial] Add BITCOIN_FS_H endif footer in fs.h + +Alfredo Garcia (9): + add timestamp to warnings + change order of returned pair, fix compatibility issue + revert result key change, fix calls to getime + add shielded balance to getwalletinfo + Add null check to feof. + allow wallet file to be outside datadir + Apply suggestions from code review + simplify TestBlockValidity + update function comment + +Ben Wilson (4): + Added libtinfo5 to ci builder containers + Added Arch and Centos to script, added libtinfo5 for arch + Fixed Centos and Arch python requirements + Build python for debian9 and ubuntu16.04 + +Carl Dong (3): + depends: Build secondary deps statically. + depends: Purge libtool archives + scripted-diff: Run scripted-diff in subshell + +Cory Fields (8): + leveldb: integrate leveldb into our buildsystem + build: No need to check for leveldb atomics + build: out-of-tree fixups + leveldb: enable runtime-detected crc32 instructions + build: verify that the assembler can handle crc32 functions + httpserver: use a future rather than relying on boost's try_join_for + httpserver: replace boost threads with std + devtools: add script to verify scriptable changes + +Daira Hopwood (29): + CBufferedFile: assert that Fill() is only called when nReadPos == nSrcPos, and simplify based on that assumption. + CBufferedFile: use eof() method rather than feof(src) in error message. + Make some conversions explicit to reduce sanitizer warnings. + Rename z_*_balance fields of getwalletinfo output to shielded_*_balance + Fix grammar in error messages. + Ensure that the absolute path used in the test definitely does not exist. + Line-wrap addition to README.md + Minor additional OpenSSL scouring. + Avoid undefined behaviour in scriptnum tests. + Add assertions for CScriptNum[10] +/- int64_t to avoid the possibility of UB. + It's unnecessary to pass int64_t by const reference. + Cosmetics in CScriptNum code and tests. + Add logging when we receive an invalid note plaintext (using the "receiveunsafe" log category). + Fix a new warning about use of boost::bind placeholders after updating Boost. closes #4774 + Beef up the CoC to address use of dog-whistles. + Fix warnings surfaced by compiling with clang++. + Use the current time as the timestamp if we override a misc warning. + qa/zcash/full_test_suite.py: changes needed for macOS. fixes #4785 + qa/zcash/full_test_suite.py: print immediately if a test fails. + log(x)/log(2.0) can be written as log2(x). + Fix integer types in DisplayDuration. + Rename `time` to `duration` in `DisplayDuration`. + Update contrib/devtools/symbol-check.py + contrib/devtools/symbol-check.py: add info about Fedora-based distributions. + Comment and error message cleanups for transaction checks. + Add new copyright entries for build-aux/m4/ax_cxx_compile_stdcxx.m4 + Fix death gtests on macOS by switching to the threadsafe style. + Fix an error reporting bug in "Checksum missing or mismatched ..." + Rename the FS_ZIP214_ECC funding stream to FS_ZIP214_BP. See also https://github.com/zcash/zips/pull/412 . + +Dimitris Apostolou (5): + Remove reference to cargo-checksum.sh + Fix typos + Fix zeromq warning + Remove deprecated init.md + Remove Bitcoin release notes + +Dimitris Tsapakidis (1): + Fixed multiple typos + +Hennadii Stepanov (1): + Enable ShellCheck rules + +Jack Grigg (79): + Assorted small changes to the locked pool manager + wallet: Add ANY_TADDR special string to z_sendmany + Allow multiple nuparams options in config file + depends: Switch to `cargo vendor` for Rust dependencies + QA: Comment out Rust crate checks in updatecheck.py + depends: Ensure that SOURCES_PATH exists before vendoring crates + wallet: Ignore coinbase UTXOs with z_sendmany ANY_TADDR + rpc: Fix comma spacing in example z_sendmany commands + Squashed 'src/leveldb/' changes from 20ca81f08..a31c8aa40 + Squashed 'src/leveldb/' changes from a31c8aa40..196962ff0 + Squashed 'src/leveldb/' changes from 196962ff0..c521b3ac6 + Squashed 'src/leveldb/' changes from c521b3ac6..64052c76c + Squashed 'src/leveldb/' changes from 64052c76c..524b7e36a + Squashed 'src/leveldb/' changes from 524b7e36a..f545dfabf + depends: Remove cargo-checksum.sh + Replace libsodium's crypto_generichash_blake2b with blake2b_simd + blake2b: Allow consuming partial BLAKE2b output + tracing: Correctly override tracing::Span move constructors + build: Remove Rust staticlib naming workaround + depends: Update to latest config.guess & config.sub + build: out-of-tree fixups + leveldb: Assert that ssize_t is the same size as size_t on Windows + LockedPool: Fix LockedPool::free(nullptr) to be a no-op + LockedPool: Make Arena::free and LockedPool::free noexcept + allocators: Apply Allocator named requirements to secure_allocator::deallocate + depends: Update map of GCC canonical hosts to Rust targets + QA: Switch to x86_64-pc-linux-gnu for hard-coded Linux HOST + build: Switch to x86_64-pc-linux-gnu for codecov filtering + gitian: Switch from x86_64-unknown-linux-gnu to x86_64-linux-gnu + util: Remove OpenSSL multithreading infrastructure + Remove remaining OpenSSL references + QA: Remove OpenSSL from updatecheck.py + build: Remove a stray -lcrypto + Squashed 'src/secp256k1/' changes from 6ad5cdb42..8ab24e8da + build: Use the endomorphism optimization for secp256k1 + depends: libevent 2.1.12 + depends: ccache 3.7.11 + depends: googletest 1.8.1 + depends: utfcpp 3.1.2 + depends: Use correct HOST for download-linux target + QA: Fix backporting bugs in httpbasics.py + depends: Boost 1.74.0 + depends: ccache 3.7.12 + cargo update + depends: ZeroMQ 4.3.3 + FFI: Merge librustzcash_init_zksnark_params variants into one function + depends: Postpone current and scheduled Rust releases until 2021 + MOVEONLY: Move logging code from util.{h,cpp} to new files + depends: Add Clang 8.0.0 + depends: Use vendored Clang for native compilation + depends: Use vendored Clang for macOS cross-compilation + depends: Vendor LLD and use it for linking + depends: Add libc++ as a dependency + depends: Don't replace default CXXFLAGS in C++ dependencies + depends: Add multilib paths for Linux cross-compile + build: Statically link libc++ + build: Add missing LIBUNIVALUE to Makefile.bench.include LDADD + depends: Fix "unused variables" warning when compiling zeromq for Windows + depends: Rename Boost libraries to follow MinGW/GCC convention + depends: Fix boost::iostreams usage on Windows with libc++ + build: Compile secp256k1 with C99 + build: Add -lpthread to univalue test LDFLAGS + qa: Disable FORTIFY_SOURCE checks + QA: Add native_clang and libcxx to updatecheck.py + test: Fix various pyflakes warnings + doc: Add Clang and libc++ migration to release notes + build: Update AX_CXX_COMPILE_STDCXX macro + build: Require and build with C++ 17 + depends: Build C++ dependencies with C++ 17 + Switch from std::random_shuffle to std::shuffle + Squashed 'src/secp256k1/' changes from 8ab24e8da..c6b6b8f1b + build: Update secp256k1 configure flags + Improve reject reasons for unmet shielded requirements + Add logging to CCoinsViewCache::HaveShieldedRequirements + utils: Remove unnecessary GetTempPath() + Add txid to "shielded requirements not met" messages + test/lint: Check for working changes before checking scripted diffs + tests: Update chained_joinsplits test for HaveShieldedRequirements API change + scripted-diff: Remove BOOST_STATIC_ASSERT + +Jeffrey Czyz (2): + Fix compilation errors in support/lockedpool.cpp + Fix segfault in allocator_tests/arena_tests + +Jeremy Rubin (1): + Fix subscript[0] potential bugs in key.cpp + +John Newbery (1): + [docs] document scripted-diff + +Jonas Schnelli (2): + NotifyBlockTip signal: switch from hash (uint256) to CBlockIndex* + Move uiInterface.NotifyBlockTip signal above the core/wallet signal + +Kaz Wesley (3): + LockedPool: test handling of invalid allocations + LockedPool: fix explosion for illegal-sized alloc + LockedPool: avoid quadratic-time allocation + +Kris Nuttycombe (14): + Prevent creation of shielded transactions in initial block download. + Revert the move of the `getBalanceZaddr` block for ease of review. + Fix forward declaration. + Remove redundant CheckBlock calls. + Reduce diff complexity. + Apply style suggestions from code review + -ibdskiptxverification must imply -checkpoints + Apply suggestions from code review + Ensure conflicting flags are reported as an error. + Reject incompatible flags in "Step 2" + Rename IBDSkipTxVerification back to ShouldCheckTransaction + Fix command-line help for -ibdskiptxverification + Fix invocation of updatecheck.py in make-release.py + Replace invalid characters in log message decoding. + +Larry Ruane (4): + Flush witness data when consistent (part 2) + performance: auto params = CChainParams::GetConsensus() + allow getaddressutxos if -lightwalletd + add z_gettreestate rpc + +Luke Dashjr (2): + lockedpool: When possible, use madvise to avoid including sensitive information in core dumps + Add MIT license to Makefiles + +Marco Falke (3): + Limit scope of all global std::once_flag + Add extra LevelDB source to Makefile + test: Move linters to test/lint, add readme + +Martin Ankerl (2): + Use best-fit strategy in Arena, now O(log(n)) instead O(n) + fix nits: variable naming, typos + +Mustafa (2): + Add a source file for unit test utils. + Move GetTempPath() to testutil. + +Nate Wilcox (3): + Link the README.md to the specific readthedocs.io page for building on Debian/Ubuntu. + Convert a sed command to a static patch file. + depends: fix a logging bug for multi-archive packages. + +Nick (1): + [RPC] Add transaction size to JSON output + +Pavel Janík (2): + Do not shadow variable, use deprecated MAP_ANON if MAP_ANONYMOUS is not defined. + Do not include env_win.cc on non-Windows systems + +Pieter Wuille (2): + Remove some unused functions and methods + Fail on commit with VERIFY SCRIPT but no scripted-diff + +Sean Bowe (3): + Update Rust to 1.44.1. + cargo update + Update to latest zcash_* and zkcrypto crates. + +Taylor Hornby (3): + Fix buffer overflows in P2PKH tests + Add a missing % to a string interpolation in rpc test framework + Fix undefined behavior in the test_bitcoin tests + +Thomas Snider (1): + [trivial] Switched constants to sizeof() + +Vasil Dimov (1): + lockedpool: avoid sensitive data in core files (FreeBSD) + +Wladimir J. van der Laan (19): + wallet: Change CCrypter to use vectors with secure allocator + wallet: Get rid of LockObject and UnlockObject calls in key.h + support: Add LockedPool + rpc: Add `getmemoryinfo` call + bench: Add benchmark for lockedpool allocation/deallocation + http: Restrict maximum size of request line + headers + Replace scriptnum_test's normative ScriptNum implementation + build: remove libcrypto as internal dependency in libbitcoinconsensus.pc + http: Do a pending c++11 simplification + http: Add log message when work queue is full + http: Change boost::scoped_ptr to std::unique_ptr in HTTPRequest + http: use std::move to move HTTPRequest into HTTPWorkItem + Add fs.cpp/h + Replace includes of boost/filesystem.h with fs.h + Replace uses of boost::filesystem with fs + Use fsbridge for fopen and freopen + torcontrol: Use fs::path instead of std::string for private key path + Remove `namespace fs=fs` + test: Mention commit id in scripted diff error + +fanquake (8): + build: remove SSL lib detection + build: remove OpenSSL detection and libs + depends: remove OpenSSL package + doc: remove OpenSSL from build instructions and licensing info + depends: Disable unused ZeroMQ features + depends: zeromq: disable draft classes and methods + build: only pass --disable-dependency-tracking to packages that understand it + build: pass --enable-option-checking to applicable packages + +mruddy (1): + [depends, zmq, doc] avoid deprecated zeromq api functions + +practicalswift (7): + Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked + Improve readability by removing redundant casts to same type (on all platforms) + tests: Remove OldSetKeyFromPassphrase/OldEncrypt/OldDecrypt + Remove unused Boost includes + Add "export LC_ALL=C" to all shell scripts + Add error handling: exit if cd fails + Use bash instead of POSIX sh. POSIX sh does not support arrays. + +Jack Grigg (9): + Update license headers + leveldb: Fix typo + LockedPool: Switch to HTTPS URLs in licenses and comments + test: Fix LFSR period in comments + httpserver: Code style cleanups + depends: Update packages documentation for Zcash + depends: Add untested note to FreeBSD host + Update example scripted-diff comit in doc/developer-notes.md + Use HTTPS in script license headers + +syd (1): + Add assert_raises_message to the python test framework. + +Ying Tong Lai (9): + Add funding stream addresses to getblocksubsidy RPC output + Fix CScript encoding + Handle shielded address case + Minor cleanups + Only return address instead of CScript + Remove void declaration of ScriptPubKeyToJSON() + Postpone native_ccache 4.0 + make-release.py: Versioning changes for 4.1.0-rc1. + make-release.py: Updated manpages for 4.1.0-rc1. + +ying tong (1): + Apply suggestions from code review + +Benjamin Winston (1): + Postponed dependency updates, refer to core team sync meeting. + diff --git a/depend/zcash/doc/release-notes/release-notes-4.1.0.md b/depend/zcash/doc/release-notes/release-notes-4.1.0.md new file mode 100644 index 000000000..d5d26eb9d --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.1.0.md @@ -0,0 +1,387 @@ +Notable changes +=============== + +Migration to Clang and static libc++ +------------------------------------ + +`zcashd` now builds its C++ (and C) dependencies entirely with a pinned version +of Clang, and statically links libc++ instead of dynamically linking libstdc++. +This migration enables us to reliably use newer C++ features while supporting +older LTS platforms, be more confident in the compiler's optimisations, and +leverage security features such as sanitisers and efficient fuzzing. In future, +this will also allow optimizing across the boundary between Rust and C++. + +The system compiler is still used to compile a few native dependencies (used by +the build machine to then compile `zcashd` for the target machine). These will +likely also be migrated to use the pinned Clang in a future release. + + +Fast sync for initial block download +------------------------------------ + +The `-ibdskiptxverification` flag allows faster synchronization during initial +block sync, by skipping transaction verification and instead verifying only PoW. +Note that this mode requires checkpoints to be enabled, to make sure that each +block under inspection is an ancestor of the latest checkpoint. + +Convenient testing for invalid note plaintexts +---------------------------------------------- + +After the mainnet activation of Canopy (block 1046400), correct wallet software +will no longer produce v1 note plaintexts (with a lead byte of `0x01`). However, +v1 note plaintexts will continue to be accepted for a grace period of 32256 +blocks (about 4 weeks), as specified in [ZIP 212](https://zips.z.cash/zip-0212). +The new `receiveunsafe` log category complains if an invalid note plaintext is +received. + +Additional lightwalletd and light client RPCs +--------------------------------------------- + +- lightwalletd is now able to retrieve all UTXOs related to a t-address through +the `getaddressutxos` RPC. (Previously, this was only available to the Insight +Explorer.) +- The new `z_gettreestate` RPC returns the Sprout and Sapling treestate at a +given block height or block hash. This makes it easier for light clients to +generate checkpoints. + +Update/removal of several cryptographic dependencies +---------------------------------------------------- + +This release updates secp256k1 to enable the GLV endomorphism optimisation by +default, after the recent expiry of the GLV patents. It also removes OpenSSL, +and replaces libsodium BLAKE2b usage with the [blake2b_simd Rust crate](https://github.com/oconnor663/blake2_simd). +Changelog +========= + +Aditya Kulkarni (1): + Add a config option to skip transaction verification in IBD mode + +Ahmad Kazi (1): + [Trivial] Add BITCOIN_FS_H endif footer in fs.h + +Alfredo Garcia (9): + add timestamp to warnings + change order of returned pair, fix compatibility issue + revert result key change, fix calls to getime + add shielded balance to getwalletinfo + Add null check to feof. + allow wallet file to be outside datadir + Apply suggestions from code review + simplify TestBlockValidity + update function comment + +Ben Wilson (4): + Added libtinfo5 to ci builder containers + Added Arch and Centos to script, added libtinfo5 for arch + Fixed Centos and Arch python requirements + Build python for debian9 and ubuntu16.04 + +Carl Dong (3): + depends: Build secondary deps statically. + depends: Purge libtool archives + scripted-diff: Run scripted-diff in subshell + +Cory Fields (8): + leveldb: integrate leveldb into our buildsystem + build: No need to check for leveldb atomics + build: out-of-tree fixups + leveldb: enable runtime-detected crc32 instructions + build: verify that the assembler can handle crc32 functions + httpserver: use a future rather than relying on boost's try_join_for + httpserver: replace boost threads with std + devtools: add script to verify scriptable changes + +Daira Hopwood (30): + CBufferedFile: assert that Fill() is only called when nReadPos == nSrcPos, and simplify based on that assumption. + CBufferedFile: use eof() method rather than feof(src) in error message. + Make some conversions explicit to reduce sanitizer warnings. + Rename z_*_balance fields of getwalletinfo output to shielded_*_balance + Fix grammar in error messages. + Ensure that the absolute path used in the test definitely does not exist. + Line-wrap addition to README.md + Minor additional OpenSSL scouring. + Avoid undefined behaviour in scriptnum tests. + Add assertions for CScriptNum[10] +/- int64_t to avoid the possibility of UB. + It's unnecessary to pass int64_t by const reference. + Cosmetics in CScriptNum code and tests. + Add logging when we receive an invalid note plaintext (using the "receiveunsafe" log category). + Fix a new warning about use of boost::bind placeholders after updating Boost. closes #4774 + Beef up the CoC to address use of dog-whistles. + Fix warnings surfaced by compiling with clang++. + Use the current time as the timestamp if we override a misc warning. + qa/zcash/full_test_suite.py: changes needed for macOS. fixes #4785 + qa/zcash/full_test_suite.py: print immediately if a test fails. + log(x)/log(2.0) can be written as log2(x). + Fix integer types in DisplayDuration. + Rename `time` to `duration` in `DisplayDuration`. + Update contrib/devtools/symbol-check.py + contrib/devtools/symbol-check.py: add info about Fedora-based distributions. + Comment and error message cleanups for transaction checks. + Add new copyright entries for build-aux/m4/ax_cxx_compile_stdcxx.m4 + Fix death gtests on macOS by switching to the threadsafe style. + Fix an error reporting bug in "Checksum missing or mismatched ..." + Rename the FS_ZIP214_ECC funding stream to FS_ZIP214_BP. See also https://github.com/zcash/zips/pull/412 . + Gitian builds: Remove manual CFLAGS and CXXFLAGS from descriptor. + +Dimitris Apostolou (5): + Remove reference to cargo-checksum.sh + Fix typos + Fix zeromq warning + Remove deprecated init.md + Remove Bitcoin release notes + +Dimitris Tsapakidis (1): + Fixed multiple typos + +Hennadii Stepanov (1): + Enable ShellCheck rules + +Jack Grigg (79): + Assorted small changes to the locked pool manager + wallet: Add ANY_TADDR special string to z_sendmany + Allow multiple nuparams options in config file + depends: Switch to `cargo vendor` for Rust dependencies + QA: Comment out Rust crate checks in updatecheck.py + depends: Ensure that SOURCES_PATH exists before vendoring crates + wallet: Ignore coinbase UTXOs with z_sendmany ANY_TADDR + rpc: Fix comma spacing in example z_sendmany commands + Squashed 'src/leveldb/' changes from 20ca81f08..a31c8aa40 + Squashed 'src/leveldb/' changes from a31c8aa40..196962ff0 + Squashed 'src/leveldb/' changes from 196962ff0..c521b3ac6 + Squashed 'src/leveldb/' changes from c521b3ac6..64052c76c + Squashed 'src/leveldb/' changes from 64052c76c..524b7e36a + Squashed 'src/leveldb/' changes from 524b7e36a..f545dfabf + depends: Remove cargo-checksum.sh + Replace libsodium's crypto_generichash_blake2b with blake2b_simd + blake2b: Allow consuming partial BLAKE2b output + tracing: Correctly override tracing::Span move constructors + build: Remove Rust staticlib naming workaround + depends: Update to latest config.guess & config.sub + build: out-of-tree fixups + leveldb: Assert that ssize_t is the same size as size_t on Windows + LockedPool: Fix LockedPool::free(nullptr) to be a no-op + LockedPool: Make Arena::free and LockedPool::free noexcept + allocators: Apply Allocator named requirements to secure_allocator::deallocate + depends: Update map of GCC canonical hosts to Rust targets + QA: Switch to x86_64-pc-linux-gnu for hard-coded Linux HOST + build: Switch to x86_64-pc-linux-gnu for codecov filtering + gitian: Switch from x86_64-unknown-linux-gnu to x86_64-linux-gnu + util: Remove OpenSSL multithreading infrastructure + Remove remaining OpenSSL references + QA: Remove OpenSSL from updatecheck.py + build: Remove a stray -lcrypto + Squashed 'src/secp256k1/' changes from 6ad5cdb42..8ab24e8da + build: Use the endomorphism optimization for secp256k1 + depends: libevent 2.1.12 + depends: ccache 3.7.11 + depends: googletest 1.8.1 + depends: utfcpp 3.1.2 + depends: Use correct HOST for download-linux target + QA: Fix backporting bugs in httpbasics.py + depends: Boost 1.74.0 + depends: ccache 3.7.12 + cargo update + depends: ZeroMQ 4.3.3 + FFI: Merge librustzcash_init_zksnark_params variants into one function + depends: Postpone current and scheduled Rust releases until 2021 + MOVEONLY: Move logging code from util.{h,cpp} to new files + depends: Add Clang 8.0.0 + depends: Use vendored Clang for native compilation + depends: Use vendored Clang for macOS cross-compilation + depends: Vendor LLD and use it for linking + depends: Add libc++ as a dependency + depends: Don't replace default CXXFLAGS in C++ dependencies + depends: Add multilib paths for Linux cross-compile + build: Statically link libc++ + build: Add missing LIBUNIVALUE to Makefile.bench.include LDADD + depends: Fix "unused variables" warning when compiling zeromq for Windows + depends: Rename Boost libraries to follow MinGW/GCC convention + depends: Fix boost::iostreams usage on Windows with libc++ + build: Compile secp256k1 with C99 + build: Add -lpthread to univalue test LDFLAGS + qa: Disable FORTIFY_SOURCE checks + QA: Add native_clang and libcxx to updatecheck.py + test: Fix various pyflakes warnings + doc: Add Clang and libc++ migration to release notes + build: Update AX_CXX_COMPILE_STDCXX macro + build: Require and build with C++ 17 + depends: Build C++ dependencies with C++ 17 + Switch from std::random_shuffle to std::shuffle + Squashed 'src/secp256k1/' changes from 8ab24e8da..c6b6b8f1b + build: Update secp256k1 configure flags + Improve reject reasons for unmet shielded requirements + Add logging to CCoinsViewCache::HaveShieldedRequirements + utils: Remove unnecessary GetTempPath() + Add txid to "shielded requirements not met" messages + test/lint: Check for working changes before checking scripted diffs + tests: Update chained_joinsplits test for HaveShieldedRequirements API change + scripted-diff: Remove BOOST_STATIC_ASSERT + +Jeffrey Czyz (2): + Fix compilation errors in support/lockedpool.cpp + Fix segfault in allocator_tests/arena_tests + +Jeremy Rubin (1): + Fix subscript[0] potential bugs in key.cpp + +John Newbery (1): + [docs] document scripted-diff + +Jonas Schnelli (2): + NotifyBlockTip signal: switch from hash (uint256) to CBlockIndex* + Move uiInterface.NotifyBlockTip signal above the core/wallet signal + +Kaz Wesley (3): + LockedPool: test handling of invalid allocations + LockedPool: fix explosion for illegal-sized alloc + LockedPool: avoid quadratic-time allocation + +Kris Nuttycombe (14): + Prevent creation of shielded transactions in initial block download. + Revert the move of the `getBalanceZaddr` block for ease of review. + Fix forward declaration. + Remove redundant CheckBlock calls. + Reduce diff complexity. + Apply style suggestions from code review + -ibdskiptxverification must imply -checkpoints + Apply suggestions from code review + Ensure conflicting flags are reported as an error. + Reject incompatible flags in "Step 2" + Rename IBDSkipTxVerification back to ShouldCheckTransaction + Fix command-line help for -ibdskiptxverification + Fix invocation of updatecheck.py in make-release.py + Replace invalid characters in log message decoding. + +Larry Ruane (4): + Flush witness data when consistent (part 2) + performance: auto params = CChainParams::GetConsensus() + allow getaddressutxos if -lightwalletd + add z_gettreestate rpc + +Luke Dashjr (2): + lockedpool: When possible, use madvise to avoid including sensitive information in core dumps + Add MIT license to Makefiles + +Marco Falke (3): + Limit scope of all global std::once_flag + Add extra LevelDB source to Makefile + test: Move linters to test/lint, add readme + +Martin Ankerl (2): + Use best-fit strategy in Arena, now O(log(n)) instead O(n) + fix nits: variable naming, typos + +Mustafa (2): + Add a source file for unit test utils. + Move GetTempPath() to testutil. + +Nate Wilcox (3): + Link the README.md to the specific readthedocs.io page for building on Debian/Ubuntu. + Convert a sed command to a static patch file. + depends: fix a logging bug for multi-archive packages. + +Nick (1): + [RPC] Add transaction size to JSON output + +Pavel Janík (2): + Do not shadow variable, use deprecated MAP_ANON if MAP_ANONYMOUS is not defined. + Do not include env_win.cc on non-Windows systems + +Pieter Wuille (2): + Remove some unused functions and methods + Fail on commit with VERIFY SCRIPT but no scripted-diff + +Sean Bowe (6): + Update Rust to 1.44.1. + cargo update + Update to latest zcash_* and zkcrypto crates. + Postpone clang and libc++ dependency updates until after the 4.1.0 release. + make-release.py: Versioning changes for 4.1.0. + make-release.py: Updated manpages for 4.1.0. + +Taylor Hornby (3): + Fix buffer overflows in P2PKH tests + Add a missing % to a string interpolation in rpc test framework + Fix undefined behavior in the test_bitcoin tests + +Thomas Snider (1): + [trivial] Switched constants to sizeof() + +Vasil Dimov (1): + lockedpool: avoid sensitive data in core files (FreeBSD) + +Wladimir J. van der Laan (19): + wallet: Change CCrypter to use vectors with secure allocator + wallet: Get rid of LockObject and UnlockObject calls in key.h + support: Add LockedPool + rpc: Add `getmemoryinfo` call + bench: Add benchmark for lockedpool allocation/deallocation + http: Restrict maximum size of request line + headers + Replace scriptnum_test's normative ScriptNum implementation + build: remove libcrypto as internal dependency in libbitcoinconsensus.pc + http: Do a pending c++11 simplification + http: Add log message when work queue is full + http: Change boost::scoped_ptr to std::unique_ptr in HTTPRequest + http: use std::move to move HTTPRequest into HTTPWorkItem + Add fs.cpp/h + Replace includes of boost/filesystem.h with fs.h + Replace uses of boost::filesystem with fs + Use fsbridge for fopen and freopen + torcontrol: Use fs::path instead of std::string for private key path + Remove `namespace fs=fs` + test: Mention commit id in scripted diff error + +fanquake (8): + build: remove SSL lib detection + build: remove OpenSSL detection and libs + depends: remove OpenSSL package + doc: remove OpenSSL from build instructions and licensing info + depends: Disable unused ZeroMQ features + depends: zeromq: disable draft classes and methods + build: only pass --disable-dependency-tracking to packages that understand it + build: pass --enable-option-checking to applicable packages + +mruddy (1): + [depends, zmq, doc] avoid deprecated zeromq api functions + +practicalswift (7): + Fix out-of-bounds write in case of failing mmap(...) in PosixLockedPageAllocator::AllocateLocked + Improve readability by removing redundant casts to same type (on all platforms) + tests: Remove OldSetKeyFromPassphrase/OldEncrypt/OldDecrypt + Remove unused Boost includes + Add "export LC_ALL=C" to all shell scripts + Add error handling: exit if cd fails + Use bash instead of POSIX sh. POSIX sh does not support arrays. + +Jack Grigg (9): + Update license headers + leveldb: Fix typo + LockedPool: Switch to HTTPS URLs in licenses and comments + test: Fix LFSR period in comments + httpserver: Code style cleanups + depends: Update packages documentation for Zcash + depends: Add untested note to FreeBSD host + Update example scripted-diff comit in doc/developer-notes.md + Use HTTPS in script license headers + +syd (1): + Add assert_raises_message to the python test framework. + +Ying Tong Lai (11): + Add funding stream addresses to getblocksubsidy RPC output + Fix CScript encoding + Handle shielded address case + Minor cleanups + Only return address instead of CScript + Remove void declaration of ScriptPubKeyToJSON() + Postpone native_ccache 4.0 + make-release.py: Versioning changes for 4.1.0-rc1. + make-release.py: Updated manpages for 4.1.0-rc1. + make-release.py: Updated release notes and changelog for 4.1.0-rc1. + Update release-notes-4.1.0-rc1.md + +ying tong (1): + Apply suggestions from code review + +Benjamin Winston (1): + Postponed dependency updates, refer to core team sync meeting. diff --git a/depend/zcash/doc/release-notes/release-notes-4.1.1.md b/depend/zcash/doc/release-notes/release-notes-4.1.1.md new file mode 100644 index 000000000..46793955d --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.1.1.md @@ -0,0 +1,156 @@ +Notable changes +=============== + +Optimize release build +---------------------- +The release build now sets CLAGS/CXXFLAGS to use the -O3 optimization +option, which turns on more optimization flags than the previously used +-O1. This produces a faster build, addressing a performance regression in +v4.1.0. + +Correctly report Founders' Reward amount in `getblocktemplate` +-------------------------------------------------------------- +This release correctly returns the `foundersreward` field from `getblocktemplate` +output pre-Canopy and removes the field post-Canopy. (The Founders' Reward will +expire exactly as Canopy activates, as specified in [ZIP 207](https://zips.z.cash/zip-0207).) +To obtain information about funding stream amounts, use `getblocksubsidy HEIGHT`, +passing in the height returned by the `getblocktemplate` API. + +Changelog +========= + +Akio Nakamura (1): + [script] lint-whitespace: improve print linenumber + +Alfredo Garcia (1): + add myblockhash parameter to getrawtransaction + +Daira Hopwood (3): + Wording improvements to getrawtransaction RPC documentation + GetNextWorkRequired: clarify why this computation is equivalent to that in the protocol spec. refs https://github.com/zcash/zips/pull/418 + Set release CFLAGS/CXXFLAGS to use -O3. + +Dan Raviv (1): + Fix header guards using reserved identifiers + +DesWurstes (1): + Obsolete #!/bin/bash shebang + +Evan Klitzke (1): + Add a lint check for trailing whitespace. + +Jack Grigg (14): + lints: Use Zcash-specific include guards for new files + lints: Update expected Boost imports + lints: Match `export LC_ALL="C"` in lint-shell-locale + test: Fix pyflakes warning in bitcoin-util-test.py + lint: Fix missing or inconsistent include guards + lint: Fix duplicate includes + python: Explicitly set encoding to utf8 when opening text files + lint: Use consistent shebangs + lint: Opt out of locale dependence in Zcash shell scripts + lint: Re-exclude subtrees from lint-include-guards.sh + lint: Apply include guard style to src/rust/include + lint: s/trim/lenTrim in src/crypto/equihash.[cpp,h] + lint: Fix minor shellcheck lints + cargo update + +John Newbery (4): + [contrib] convert test-security-check to python3 + Clean up bctest.py and bitcoin-util-test.py + Improve logging in bctest.py if there is a formatting mismatch + [linter] Strip trailing / in path for git-subtree-check + +João Barbosa (1): + qa: Ignore shellcheck warning SC2236 + +Julian Fleischer (3): + fix locale for lint-shell + use export LC_ALL=C.UTF-8 + Run all lint scripts + +Kris Nuttycombe (6): + Change order of checks to skip IsInitialBlockDownload check if flag is unset. + Correctly report founder's reward amount in getblocktemplate prior to Canopy + Document how to get block subsidy information in getblocktemplate. + Update getblocktemplate documentation. + make-release.py: Versioning changes for 4.1.1. + make-release.py: Updated manpages for 4.1.1. + +Kristaps Kaupe (1): + Make lint-includes.sh work from any directory + +Marco Falke (4): + devtools: Exclude patches from lint-whitespace + Refine travis check for duplicate includes + test: Move linters to test/lint, add readme + Revert "Remove unused variable in shell script" + +MeshCollider (1): + Add tab char lint check and exclude imported dependencies + +Philip Kaufmann (1): + [Trivial] ensure minimal header conventions + +Pieter Wuille (1): + Improve git-subtree-check.sh + +Sjors Provoost (3): + [scripts] lint-whitespace: use perl instead of grep -P + [scripts] lint-whitespace: check last N commits or unstaged changes + doc: improve subtree check instructions + +Vidar Holen (1): + refactor/lint: Add ignored suggestions to an array + +Wladimir J. van der Laan (4): + contrib: Ignore historical release notes for whitespace check + test: Add format-dependent comparison to bctest + test: Explicitly set encoding to utf8 when opening text files + uint256: replace sprintf with HexStr and reverse-iterator + +adityapk00 (1): + Don't compile ehHashState::* if mining is disabled + +isle2983 (1): + [copyright] add MIT license headers to .sh scripts where missing + +jnewbery (5): + Add bitcoin-tx JSON tests + Add option to run bitcoin-util-test.py manually + bitcoin-util-test.py should fail if the output file is empty + add verbose mode to bitcoin-util-test.py + Add logging to bitcoin-util-test.py + +practicalswift (20): + Document include guard convention + Fix missing or inconsistent include guards + Add lint-include-guards.sh which checks include guard consistency + Add Travis check for duplicate includes + Add shell script linting: Check for shellcheck warnings in shell scripts + add lint tool to check python3 shebang + build: Guard against accidental introduction of new Boost dependencies + build: Add linter for checking accidental locale dependence + docs: Mention lint-locale-dependence.sh in developer-notes.md + Add "export LC_ALL=C" to all shell scripts + Add linter: Make sure all shell scripts opt out of locale dependence using "export LC_ALL=C" + Explicitly specify encoding when opening text files in Python code + Add linter: Make sure we explicitly open all text files using UTF-8 or ASCII encoding in Python + macOS fix: Work around empty (sub)expression error when using BSD grep + macOS fix: Add excludes for checks added in the newer shellcheck version installed by brew + Remove repeated suppression. Fix indentation. + Fix warnings introduced in shellcheck v0.6.0 + Remove no longer needed shellcheck suppressions + Follow-up to #13454: Fix broken build by exporting LC_ALL=C + Remove unused variables in shell scripts. + +Jack Grigg (5): + Small documentation fixes + lints: Add a missing copyright header + lint: Allow stoi in src/rpc/blockchain.cpp + lint: Remove some subtrees from exclusion + doc: Adjust subtree developer notes to refer to Zcash + +vim88 (1): + Scripts and tools & Docs: Used #!/usr/bin/env bash instead of obsolete #!/bin/bash, added linting for .sh files shebang and updated the Developer Notes. + diff --git a/depend/zcash/doc/release-notes/release-notes-4.2.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.2.0-rc1.md new file mode 100644 index 000000000..f8d721111 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.2.0-rc1.md @@ -0,0 +1,242 @@ +Notable changes +=============== + +Switch to ed25519-zebra for consensus signature checks +------------------------------------------------------ +This removes the zcashd dependency upon libsodium for ed25519 +signature checks and instead uses the Rust implementation in +ed25519-zebra, which has been active for signature verification +since the Canopy upgrade. For more information on the conditions +that led to this change see https://hdevalence.ca/blog/2020-10-04-its-25519am + +Update default fees according to ZIP-313 +---------------------------------------- +Reduce default fees to 0.00001 ZEC as specified in ZIP-313 and +ensure that transactions paying at least the new minimum fee meet +the transaction relay threshold irrespective of transaction size. + +Improve getblocktemplate rpc performance when using shielded coinbase +--------------------------------------------------------------------- +This change precomputes future block templates to permit miners to +begin working atop newly arrived blocks as quickly as possible, rather +than waiting for a new template to be generated after a block has arrived. +It also reduces the initial the wait time for incorporating new mempool +transactions into a block from 1 minute to 10 seconds; the previous value +was inherited from the upstream bitcoin codebase but is inappropriate for +our block timing. + +Migrate from rpc-tests.sh to rpc-tests.py +----------------------------------------- +This unifies and simplifies the RPC testing framework, as has +been done in the upstream Bitcoin codebase. + +Changelog +========= + +Alex Morcos (2): + Reorder RPC tests for running time + remove obsolete run-bitcoind-for-test.sh + +Alfredo Garcia (1): + add address to z_importviewingkey error + +Casey Rodarmor (1): + Add p2p-fullblocktest.py + +Chun Kuan Lee (2): + gui: get special folder in unicode + refactor: Drop boost::this_thread::interruption_point and boost::thread_interrupted in main thread + +Cory Fields (1): + build: a few ugly hacks to get the rpc tests working out-of-tree + +Daira Hopwood (5): + Windows cross-build generates .lib files, which should be ignored by git and removed by clean. + Partial revert of "Update links". See #4904 + Fix a typo introduced in #4904. + Reduce the default fee for z_* operations, and the "low fee penalty" threshold for mempool limiting, to 1000 zatoshis. + Always allow transactions paying at least DEFAULT_FEE to be relayed, and do not rate-limit them. In other words, make sure that the "minimum relay fee" is no greater than DEFAULT_FEE. + +Daniel Kraft (1): + Fix crash when mining with empty keypool. + +Dimitris Apostolou (5): + Fix typo + readelf is Linux only + Fix readelf configuration + Update links + Remove workaround affecting old Boost version + +Elliot Olds (1): + Check if zmq is installed in tests, update docs + +Eric Lombrozo (1): + Added fPowNoRetargeting field to Consensus::Params that disables nBits recalculation. + +Jack Grigg (32): + test: Use default shielded address in RPC tests where the type is irrelevant + Revert "remove SignatureHash from python rpc tests" + test: Remove FindAndDelete from RPC test framework + test: Fix SignatureHash RPC test helper + test: Set hashFinalSaplingRoot default correctly in create_block + test: Re-enable regtest difficulty adjustment for unit tests that use it + test: Adjust some Zcash RPC tests to work with parallel runner + test: Run rpc-tests.py in full_test_suite.py + lint: Remove boost/foreach.hpp from allowed includes + test: Silence pyflakes unused import warning + test: Run shielding-heavy RPC tests in serial + Fix Hungarian notation nit from Daira + Switch to ed25519-zebra for consensus signature checks + test: Use ed25519_verify in ConsensusTests + Update minimum chain work and set activation block hashes for mainnet + Update minimum chain work and set activation block hashes for testnet + net: Rework CNode spans + rpc: Reload CNode spans after reloading the log filter + rpc: Log the new filter when we set it + mempool: Log all accepted txids at INFO level + Add header to files that will need it + scripted-diff: Migrate from boost::variant to std::variant + Finish migrating to std::variant + Migrate from boost::optional::get to boost::optional::value + Add header to files that will need it + scripted-diff: Migrate from boost::optional to std::optional + Finish migrating to std::optional + lint: Remove boost::variant and boost::optional from allowed includes + test: Fix test_bitcoin compilation on macOS High Sierra + cargo update + tracing: Remove unnecessary tracing_init_inner internal function + tracing: Simplify init logic using optional layers + +James O'Beirne (2): + Add tests for gettxoutsetinfo, CLevelDBBatch, CLevelDBIterator + Add basic coverage reporting for RPC tests + +Jeff Garzik (1): + qa/pull-tester/rpc-tests.py: chmod 0755 + +Jesse Cohen (1): + [doc][trivial] no retargeting in regtest mode + +John Newbery (6): + Use configparser in rpc-tests.py + Use argparse in rpc_tests.py + Improve rpc-tests.py arguments + Refactor rpc-tests.py + Various review markups for rpc-tests.py improvements + Add exclude option to rpc-tests.py + +Jorge Timón (8): + Small preparations for Q_FOREACH, PAIRTYPE and #include removal + scripted-diff: Fully remove BOOST_FOREACH + scripted-diff: Remove PAIRTYPE + Introduce src/reverse_iterator.hpp and include it... + Fix const_reverse_iterator constructor (pass const ptr) + scripted-diff: Remove BOOST_REVERSE_FOREACH + scripted-diff: Remove #include + clang-format: Delete ForEachMacros + +Josh Ellithorpe (1): + Include transaction hex in verbose getblock output + +Kris Nuttycombe (7): + Write down the folklore about nSequence + Prefer explicit passing of CChainParams to the Params() global. + Remove vestigial OSX_SDK_VERSION from darwin build. + Update boost to 1.75, postpone other updates. + Don't log to stdout if a file logger is configured. + make-release.py: Versioning changes for 4.2.0-rc1. + make-release.py: Updated manpages for 4.2.0-rc1. + +Larry Ruane (2): + add more version information to getinfo rpc + improve getblocktemplate performance for shielded coinbase + +Luv Khemani (1): + Add autocomplete to bitcoin-qt's console window. + +Marco Falke (37): + [doc] trivial: fix markdown syntax in qa/rpc-tests/README.md + [rpc-tests] fundrawtransaction: Update fee after minRelayTxFee increase + [rpc-tests] Check return code + [qa] Split README.md to /qa and /qa/rpc-tests + [qa] Extend README.md + [qa] keypool: Fix white space to prepare transition to test framework + [qa] keypool: DRY: Use test framework + [qa] pull-tester: Cleanup (run keypool, tidy stdout) + [qa] Use python2/3 syntax + [qa] rpc-tests: Properly use integers, floats + [qa] mininode: Catch exceptions in got_data + [qa] pull-tester: Don't mute zmq ImportError + [qa] pull-tester: Exit early when no tests are run + [qa] rpc-tests: Fix link in comment and label error msg + [qa] Switch to py3 + [qa] Refactor test_framework and pull tester + [qa] Update README.md + [qa] Stop other nodes, even when one fails to stop + [qa] pull-tester: Adjust comment + [qa] pull-tester: Run rpc test in parallel + [qa] Add option --portseed to test_framework + [qa] Remove hardcoded "4 nodes" from test_framework + [qa] test_framework: Append portseed to tmpdir + [qa] test_framework: Use different rpc_auth_pair for each node + [qa] pull-tester: Fix assertion and check for run_parallel + [qa] pull-tester: Start longest test first + [qa] Adjust timeouts for micro-optimization of run time + [qa] Use single cache dir for chains + [qa] Remove unused code + [qa] pull-tester: Don't mute zmq ImportError + [qa] create_cache: Delete temp dir when done + [qa] Refactor RPCTestHandler to prevent TimeoutExpired + [qa] pull-tester: Only print output when failed + [qa] test_framework: Exit when tmpdir exists + [qa] rpc-tests: Apply random offset to portseed + qa: Set correct path for binaries in rpc tests + util: Replace boost::signals2 with std::function + +Nate Wilcox (1): + configure.ac: Introduce macros to simplify requiring tools. + +Suhas Daftuar (2): + Remove unmaintained example test script_test.py + Tests: add timeout to sync_blocks() and sync_mempools() + +Wladimir J. van der Laan (2): + build: don't distribute tests_config.py + test: don't override BITCOIND and BITCOINCLI if they're set + +fanquake (4): + [doc] Add OS X ZMQ requirement to QA readme + [trivial] Add tests_config.ini to .gitignore + [qa][doc] Correct rpc test options in readme + build: set minimum supported macOS to 10.14 + +furszy (15): + wallet:AvailableCoins fOnlySpendable filtering flag implemented + connected to sendmany async operation. + wallet:AvailableCoins nMinDepth filter implemented + connected to sendmany async operation. + asyncrpcoperation_sendmany::find_utxos removing a redundant coinbase check, coinbases are already being filtered by the AvailableCoins flag. + wallet:AvailableCoins filter by destination/s feature implemented + connected to sendmany async operation. + sendmany::find_utxo removing an unneeded recursive lock, AvailableCoins is already locking cs_main and cs_wallet. + wallet:COutput adding fIsCoinbase member. + COutput: implemented Value() method. + asyncRPCOperation_sendmany:find_utxos, removing a redundant loop over all of the available utxo in the wallet. + sendmany: removing now unused SendManyInputUTXO class. + move-only: asyncOp_sendmany, target amount calculation moved before find inputs (utxos and notes). + sendmany operation: Creating TxValues struct to store the transaction values in a more organized manner. + Improving asyncoperation_sendmany, removing another redundant for loop over all of the available utxos. + rpc_wallet_tests: changed "Insufficient funds" error message to a proper "Insufficient transparent funds". This is because we are now throwing the insufficient transparent balance rpc error inside load_utxo. + asyncOp sendmany: moved inputs total amount check inside load_utxo before the dust validation. + sendmany::find_unspent_notes removing an unneeded recursive lock, GetFilteredNotes is already locking cs_main and cs_wallet. + +isle2983 (1): + [doc] - clarify statement about parallel jobs in rpc-tests.py + +Marshall Gaucher (1): + Update expected fails for Sprout txns flows on Canopy + +ptschip (1): + Migrated rpc-tests.sh to all python rpc-tests.py + +whythat (2): + [qa]: add parsing for ':' argument form to rpc_url() + [qa]: enable rpcbind_test + diff --git a/depend/zcash/doc/release-notes/release-notes-4.2.0.md b/depend/zcash/doc/release-notes/release-notes-4.2.0.md new file mode 100644 index 000000000..aa7ed583f --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.2.0.md @@ -0,0 +1,247 @@ +Notable changes +=============== + +Switch to ed25519-zebra for consensus signature checks +------------------------------------------------------ +This removes the zcashd dependency upon libsodium for ed25519 +signature checks and instead uses the Rust implementation in +ed25519-zebra, which has been active for signature verification +since the Canopy upgrade. For more information on the conditions +that led to this change see https://hdevalence.ca/blog/2020-10-04-its-25519am + +Update default fees according to ZIP-313 +---------------------------------------- +Reduce default fees to 0.00001 ZEC as specified in ZIP-313 and +ensure that transactions paying at least the new minimum fee meet +the transaction relay threshold irrespective of transaction size. + +Improve getblocktemplate rpc performance when using shielded coinbase +--------------------------------------------------------------------- +This change precomputes future block templates to permit miners to +begin working atop newly arrived blocks as quickly as possible, rather +than waiting for a new template to be generated after a block has arrived. +It also reduces the initial the wait time for incorporating new mempool +transactions into a block from 1 minute to 10 seconds; the previous value +was inherited from the upstream bitcoin codebase but is inappropriate for +our block timing. + +Migrate from rpc-tests.sh to rpc-tests.py +----------------------------------------- +This unifies and simplifies the RPC testing framework, as has +been done in the upstream Bitcoin codebase. + +Changelog +========= + +Alex Morcos (2): + Reorder RPC tests for running time + remove obsolete run-bitcoind-for-test.sh + +Alfredo Garcia (1): + add address to z_importviewingkey error + +Casey Rodarmor (1): + Add p2p-fullblocktest.py + +Chun Kuan Lee (2): + gui: get special folder in unicode + refactor: Drop boost::this_thread::interruption_point and boost::thread_interrupted in main thread + +Cory Fields (1): + build: a few ugly hacks to get the rpc tests working out-of-tree + +Daira Hopwood (7): + Windows cross-build generates .lib files, which should be ignored by git and removed by clean. + Partial revert of "Update links". See #4904 + Fix a typo introduced in #4904. + Reduce the default fee for z_* operations, and the "low fee penalty" threshold for mempool limiting, to 1000 zatoshis. + Always allow transactions paying at least DEFAULT_FEE to be relayed, and do not rate-limit them. In other words, make sure that the "minimum relay fee" is no greater than DEFAULT_FEE. + gtest/test_mempoollimit: the test failed to properly ensure that the "low fee penalty" threshold matches the new ZIP 313 fee. + Revert changes in #4916 that assumed arguments represent fees, when they are actually number of confirmations. + +Daniel Kraft (1): + Fix crash when mining with empty keypool. + +Dimitris Apostolou (5): + Fix typo + readelf is Linux only + Fix readelf configuration + Update links + Remove workaround affecting old Boost version + +Elliot Olds (1): + Check if zmq is installed in tests, update docs + +Eric Lombrozo (1): + Added fPowNoRetargeting field to Consensus::Params that disables nBits recalculation. + +Jack Grigg (32): + test: Use default shielded address in RPC tests where the type is irrelevant + Revert "remove SignatureHash from python rpc tests" + test: Remove FindAndDelete from RPC test framework + test: Fix SignatureHash RPC test helper + test: Set hashFinalSaplingRoot default correctly in create_block + test: Re-enable regtest difficulty adjustment for unit tests that use it + test: Adjust some Zcash RPC tests to work with parallel runner + test: Run rpc-tests.py in full_test_suite.py + lint: Remove boost/foreach.hpp from allowed includes + test: Silence pyflakes unused import warning + test: Run shielding-heavy RPC tests in serial + Fix Hungarian notation nit from Daira + Switch to ed25519-zebra for consensus signature checks + test: Use ed25519_verify in ConsensusTests + Update minimum chain work and set activation block hashes for mainnet + Update minimum chain work and set activation block hashes for testnet + net: Rework CNode spans + rpc: Reload CNode spans after reloading the log filter + rpc: Log the new filter when we set it + mempool: Log all accepted txids at INFO level + Add header to files that will need it + scripted-diff: Migrate from boost::variant to std::variant + Finish migrating to std::variant + Migrate from boost::optional::get to boost::optional::value + Add header to files that will need it + scripted-diff: Migrate from boost::optional to std::optional + Finish migrating to std::optional + lint: Remove boost::variant and boost::optional from allowed includes + test: Fix test_bitcoin compilation on macOS High Sierra + cargo update + tracing: Remove unnecessary tracing_init_inner internal function + tracing: Simplify init logic using optional layers + +James O'Beirne (2): + Add tests for gettxoutsetinfo, CLevelDBBatch, CLevelDBIterator + Add basic coverage reporting for RPC tests + +Jeff Garzik (1): + qa/pull-tester/rpc-tests.py: chmod 0755 + +Jesse Cohen (1): + [doc][trivial] no retargeting in regtest mode + +John Newbery (6): + Use configparser in rpc-tests.py + Use argparse in rpc_tests.py + Improve rpc-tests.py arguments + Refactor rpc-tests.py + Various review markups for rpc-tests.py improvements + Add exclude option to rpc-tests.py + +Jorge Timón (8): + Small preparations for Q_FOREACH, PAIRTYPE and #include removal + scripted-diff: Fully remove BOOST_FOREACH + scripted-diff: Remove PAIRTYPE + Introduce src/reverse_iterator.hpp and include it... + Fix const_reverse_iterator constructor (pass const ptr) + scripted-diff: Remove BOOST_REVERSE_FOREACH + scripted-diff: Remove #include + clang-format: Delete ForEachMacros + +Josh Ellithorpe (1): + Include transaction hex in verbose getblock output + +Kris Nuttycombe (10): + Write down the folklore about nSequence + Prefer explicit passing of CChainParams to the Params() global. + Remove vestigial OSX_SDK_VERSION from darwin build. + Update boost to 1.75, postpone other updates. + Don't log to stdout if a file logger is configured. + make-release.py: Versioning changes for 4.2.0-rc1. + make-release.py: Updated manpages for 4.2.0-rc1. + make-release.py: Updated release notes and changelog for 4.2.0-rc1. + make-release.py: Versioning changes for 4.2.0. + make-release.py: Updated manpages for 4.2.0. + +Larry Ruane (2): + add more version information to getinfo rpc + improve getblocktemplate performance for shielded coinbase + +Luv Khemani (1): + Add autocomplete to bitcoin-qt's console window. + +Marco Falke (37): + [doc] trivial: fix markdown syntax in qa/rpc-tests/README.md + [rpc-tests] fundrawtransaction: Update fee after minRelayTxFee increase + [rpc-tests] Check return code + [qa] Split README.md to /qa and /qa/rpc-tests + [qa] Extend README.md + [qa] keypool: Fix white space to prepare transition to test framework + [qa] keypool: DRY: Use test framework + [qa] pull-tester: Cleanup (run keypool, tidy stdout) + [qa] Use python2/3 syntax + [qa] rpc-tests: Properly use integers, floats + [qa] mininode: Catch exceptions in got_data + [qa] pull-tester: Don't mute zmq ImportError + [qa] pull-tester: Exit early when no tests are run + [qa] rpc-tests: Fix link in comment and label error msg + [qa] Switch to py3 + [qa] Refactor test_framework and pull tester + [qa] Update README.md + [qa] Stop other nodes, even when one fails to stop + [qa] pull-tester: Adjust comment + [qa] pull-tester: Run rpc test in parallel + [qa] Add option --portseed to test_framework + [qa] Remove hardcoded "4 nodes" from test_framework + [qa] test_framework: Append portseed to tmpdir + [qa] test_framework: Use different rpc_auth_pair for each node + [qa] pull-tester: Fix assertion and check for run_parallel + [qa] pull-tester: Start longest test first + [qa] Adjust timeouts for micro-optimization of run time + [qa] Use single cache dir for chains + [qa] Remove unused code + [qa] pull-tester: Don't mute zmq ImportError + [qa] create_cache: Delete temp dir when done + [qa] Refactor RPCTestHandler to prevent TimeoutExpired + [qa] pull-tester: Only print output when failed + [qa] test_framework: Exit when tmpdir exists + [qa] rpc-tests: Apply random offset to portseed + qa: Set correct path for binaries in rpc tests + util: Replace boost::signals2 with std::function + +Nate Wilcox (1): + configure.ac: Introduce macros to simplify requiring tools. + +Suhas Daftuar (2): + Remove unmaintained example test script_test.py + Tests: add timeout to sync_blocks() and sync_mempools() + +Wladimir J. van der Laan (2): + build: don't distribute tests_config.py + test: don't override BITCOIND and BITCOINCLI if they're set + +fanquake (4): + [doc] Add OS X ZMQ requirement to QA readme + [trivial] Add tests_config.ini to .gitignore + [qa][doc] Correct rpc test options in readme + build: set minimum supported macOS to 10.14 + +furszy (15): + wallet:AvailableCoins fOnlySpendable filtering flag implemented + connected to sendmany async operation. + wallet:AvailableCoins nMinDepth filter implemented + connected to sendmany async operation. + asyncrpcoperation_sendmany::find_utxos removing a redundant coinbase check, coinbases are already being filtered by the AvailableCoins flag. + wallet:AvailableCoins filter by destination/s feature implemented + connected to sendmany async operation. + sendmany::find_utxo removing an unneeded recursive lock, AvailableCoins is already locking cs_main and cs_wallet. + wallet:COutput adding fIsCoinbase member. + COutput: implemented Value() method. + asyncRPCOperation_sendmany:find_utxos, removing a redundant loop over all of the available utxo in the wallet. + sendmany: removing now unused SendManyInputUTXO class. + move-only: asyncOp_sendmany, target amount calculation moved before find inputs (utxos and notes). + sendmany operation: Creating TxValues struct to store the transaction values in a more organized manner. + Improving asyncoperation_sendmany, removing another redundant for loop over all of the available utxos. + rpc_wallet_tests: changed "Insufficient funds" error message to a proper "Insufficient transparent funds". This is because we are now throwing the insufficient transparent balance rpc error inside load_utxo. + asyncOp sendmany: moved inputs total amount check inside load_utxo before the dust validation. + sendmany::find_unspent_notes removing an unneeded recursive lock, GetFilteredNotes is already locking cs_main and cs_wallet. + +isle2983 (1): + [doc] - clarify statement about parallel jobs in rpc-tests.py + +Marshall Gaucher (1): + Update expected fails for Sprout txns flows on Canopy + +ptschip (1): + Migrated rpc-tests.sh to all python rpc-tests.py + +whythat (2): + [qa]: add parsing for ':' argument form to rpc_url() + [qa]: enable rpcbind_test + diff --git a/depend/zcash/doc/release-notes/release-notes-4.3.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.3.0-rc1.md new file mode 100644 index 000000000..bb43600e5 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.3.0-rc1.md @@ -0,0 +1,320 @@ +Notable changes +=============== + +Reduce download traffic +----------------------- + +We have made several changes to reduce the amount of data downloaded by `zcashd` +during initial block download (IBD): + +- Significant time and bandwidth is spent in issuing `getheaders` P2P requests. + This results in noticeable bandwidth usage due to the large size of Zcash + block headers. + + We now eliminate redundant requests in cases where we already know the last + header in the message. This optimization is enabled by default, but can be + disabled by setting the config option `-no-optimize-getheaders`. + +- Transactions in the mempool are no longer downloaded during IBD (`zcashd` will + only request block data). + +Reduce upload traffic +--------------------- + +A major part of the outbound traffic is caused by serving historic blocks to +other nodes in initial block download state. + +It is now possible to reduce the total upload traffic via the `-maxuploadtarget` +parameter. This is *not* a hard limit but a threshold to minimize the outbound +traffic. When the limit is about to be reached, the uploaded data is cut by not +serving historic blocks (blocks older than one week). +Moreover, any SPV peer is disconnected when they request a filtered block. + +This option can be specified in MiB per day and is turned off by default +(`-maxuploadtarget=0`). +The recommended minimum is 1152 * MAX_BLOCK_SIZE (currently 2304MB) per day. + +Whitelisted peers will never be disconnected, although their traffic counts for +calculating the target. + +A more detailed documentation about keeping traffic low can be found in +[/doc/reduce-traffic.md](/doc/reduce-traffic.md). + +`libzcashconsensus` replaced by `libzcash_script` +------------------------------------------------- + +The `libzcashconsensus` library inherited from upstream has been unusable since +the Overwinter network upgrade in 2018. We made changes to signature digests +similar to those made in Bitcoin's SegWit, which required additional per-input +data that could not be added to the existing APIs without breaking backwards +compatibility. + +Additionally, it has become increasingly inaccurately named; it only covers +(Zcash's subset of) the Bitcoin scripting system, and not the myriad of other +consensus changes: in particular, Zcash's shielded pools. + +We have now renamed the library to `libzcash_script`, and reworked it to instead +focus on transparent script verification: + +- The script verification APIs are altered to take `consensusBranchId` and + `amount` fields. +- New precomputing APIs have been added that enable multiple transparent inputs + on a single transaction to be verified more efficiently. +- Equihash has been removed from the compiled library. The canonical Equihash + validator is the [`equihash` Rust crate](https://crates.io/crates/equihash) + since v3.1.0. + +The C++ library can be built by compiling `zcashd` with the environment variable +`CONFIGURE_FLAGS=--with-libs`. It is also wrapped as the +[`zcash_script` Rust crate](https://crates.io/crates/zcash_script) +(maintained by the Zcash Foundation for use in `zebrad`). + +Other P2P Changes +----------------- + +The list of banned peers is now stored on disk rather than in memory. Restarting +`zcashd` will no longer clear out the list of banned peers; instead the +`clearbanned` RPC call can be used to manually clear the list. The `setban` RPC +call can also be used to manually ban or unban a peer. + +Build system updates +-------------------- + +- We now build with Clang 11 and Rust 1.49. +- We have downgraded Boost to 1.74 to mitigate `statx`-related breakage in some + container environments. + +Changelog +========= + +Alex Wied (3): + Add support for FreeBSD 12 + Set rust_target for all FreeBSD versions + Use parentheses for defined in windows-unused-variables.diff + +Alfredo Garcia (3): + split wallet.py tests + hide password in -stdin `walletpassphrase` command + Apply suggestions from code review + +Bernhard M. Wiedemann (1): + Make tests pass after 2020 + +BtcDrak (1): + Remove bad chain alert partition check + +Carl Dong (13): + build: Add variable printing target to Makefiles + depends: Propagate well-known vars into depends + depends: boost: Specify toolset to bootstrap.sh + depends: boost: Split target-os from toolset + depends: boost: Use clang toolset if clang in CXX + depends: Propagate only specific CLI variables to sub-makes + depends: boost: Refer to version in URL + depends: boost: Split into non-/native packages + depends: boost: Disable all compression + depends: boost: Cleanup architecture/address-model + depends: boost: Cleanup toolset selection + depends: boost: Remove unnecessary _archiver_ + depends: boost: Specify cflags+compileflags + +Casey Rodarmor (3): + Make limited map actually respect max size + Disallow unlimited limited maps + Add limitedmap test + +Cory Fields (6): + depends: fix boost mac cross build with clang 9+ + build: add missing leveldb defines + net: make Ban/Unban/ClearBan functionality consistent + net: No need to export DumpBanlist + net: move CBanDB and CAddrDB out of net.h/cpp + net: Drop CNodeRef for AttemptToEvictConnection + +Daira Hopwood (2): + qa/zcash/updatecheck.py: remove dead code; print instructions to run `cargo outdated` and `cargo update`. + Ensure that `CONFIGURE_FLAGS=--enable-debug` correctly uses -O0 for dependencies and main build. + +Daniel Kraft (1): + doc: add comment explaining initial header request + +Dimitris Apostolou (1): + Discord invite instead of direct link + +Ethan Heilman (1): + Fix de-serialization bug where AddrMan is corrupted after exception * CAddrDB modified so that when de-serialization code throws an exception Addrman is reset to a clean state * CAddrDB modified to make unit tests possible * Regression test created to ensure bug is fixed * StartNode modifed to clear adrman if CAddrDB::Read returns an error code. + +Gregory Maxwell (2): + Return early in IsBanned. + Disconnect on mempool requests from peers when over the upload limit. + +Igor Cota (1): + Define TARGET_OS when host is android + +Jack Grigg (41): + Add JSDescriptionInfo for constructing JSDescriptions + Remove JSDescription::h_sig + prevector: Terminate without logging on failed allocation + Remove init_and_check_sodium from crypto/common.h + Store inputs and outputs by reference in JSDescriptionInfo + depends: Update Rust to 1.49.0 + rust: Use renamed broken_intra_doc_links lint + depends: cargo update + depends: Move to Clang 11 + depends: Fix Boost warnings under Clang 11 + depends: Allow per-host package download paths + depends: Ensure the native_clang download path is for the builder + Revert "Update boost to 1.75, postpone other updates." + qa: Postpone Boost and native_b2 updates + QA: Remove unused update postponements + QA: Postpone BDB update again + depends: ZeroMQ 4.3.4 + depends: Postpone updates that require adding CMake + cargo update + Squashed 'src/univalue/' changes from 9ef5b78c1..98fadc090 + Remove crypto/equihash from libzcashconsensus + Add amount and consensus branch ID to zcashconsensus_verify_script + Rename src/script/zcashconsensus.* -> src/script/zcash_script.* + Rename zcashconsensus_* -> zcash_script_* in APIs + Rename libzcashconsensus.la -> libzcash_script.la + Set up an mdbook in which we can document zcashd's architecture design + Actions: Add a workflow to deploy the zcashd book + Show README as root of zcashd book + Link to zips.z.cash for protocol spec + test: Convert Bech32 test vectors into known-answer test vectors + zcash_script: Add API to verify scripts with precomputed tx data + test: Migrate maxuploadtarget.py to Python 3 + Pass current PoWTargetSpacing() into CNode::OutboundTargetReached() + init: Pass post-Blossom spacing into CNode::SetMaxOutboundTarget() + Fix some typos + zcash_script: Clarify return values in docs + Rename responsible_disclosure.md to SECURITY.md + Add IBD download traffic reduction to release notes + Fill out the rest of the 4.3.0 release notes + make-release.py: Versioning changes for 4.3.0-rc1. + make-release.py: Updated manpages for 4.3.0-rc1. + +Jeremy Rubin (1): + Minimal fix to slow prevector tests as stopgap measure + +Jonas Schnelli (14): + banlist.dat: store banlist on disk + CAddrDB/CBanDB: change filesize variables from int to uint64_t + use CBanEntry as object container for banned nodes + Adding CSubNet constructor over a single CNetAddr + [Qt] add ui signal for banlist changes + [Qt] banlist, UI optimizing and better signal handling + net: use CIDR notation in CSubNet::ToString() + [QA] fix netbase tests because of new CSubNet::ToString() output + Introduce -maxuploadtarget + [doc] add documentation how to reduce traffic + don't enforce maxuploadtargets disconnect for whitelisted peers + [docs] rename reducetraffic.md to reduce-traffic.md + add documentation for exluding whitelistes peer from maxuploadtarget + add (max)uploadtarget infos to getnettotals RPC help + +Josh Lehan (1): + Re-organize -maxconnections option handling + +Karel Bilek (1): + scripted-diff: Use UniValue.pushKV instead of push_back(Pair()) + +Kaz Wesley (4): + fix race that could fail to persist a ban + prevector: destroy elements only via erase() + test prevector::swap + prevector::swap: fix (unreached) data corruption + +Kris Nuttycombe (4): + Skip "tx" messages during initial block download. + Fix pyflakes complaints + Whitespace-only fix in chainparams.cpp + Update the maxuploadtarget.py tests to accommodate zcash. + +Larry Ruane (1): + #4624 improve IBD sync by eliminating getheaders requests + +Marco Falke (3): + [net] Cleanup maxuploadtarget + [doc] Add -maxuploadtarget release notes + [walletdb] Add missing LOCK() in Recover() for dummyWallet + +Marius Kjærstad (3): + Update _COPYRIGHT_YEAR in configure.ac to 2021 + Update COPYRIGHT_YEAR in clientversion.h to 2021 + Update of copyright year to 2021 + +Matt Corallo (6): + Default to defining endian-conversion DECLs in compat w/o config + Make fDisconnect an std::atomic + Make fImporting an std::atomic + Fix AddrMan locking + Remove double brackets in addrman + Fix unlocked access to vNodes.size() + +Patrick Strateman (1): + Avoid recalculating vchKeyedNetGroup in eviction logic. + +Peter Bushnell (1): + depends: Consistent use of package variable + +Peter Todd (1): + Remove LOCK(cs_main) from decodescript + +Philip Kaufmann (4): + banlist: update set dirty to be more fine grained + banlist: better handling of banlist in StartNode() + banlist: add more banlist infos to log / add GUI signal + banlist (bugfix): allow CNode::SweepBanned() to run on interval + +Pieter Wuille (11): + Add SipHash-2-4 primitives to hash + Use SipHash-2-4 for CCoinsCache index + Switch CTxMempool::mapTx to use a hash index for txids + Use SipHash-2-4 for address relay selection + Add extra message to avoid a long 'Loading banlist' + Support SipHash with arbitrary byte writes + Use 64-bit SipHash of netgroups in eviction + Use C++11 thread-safe static initializers + Add ChaCha20 + Switch FastRandomContext to ChaCha20 + Add a FastRandomContext::randrange and use it + +Suhas Daftuar (1): + Add RPC test for -maxuploadtarget + +Taylor Hornby (2): + Move the github API token out of updatecheck.py into an untracked file. + Document the required .updatecheck-token file in the release docs + +Wladimir J. van der Laan (6): + build: Updates for OpenBSD + net: Fix CIDR notation in ToString() + test: Add more test vectors for siphash + timedata: Prevent warning overkill + Always allow getheaders from whitelisted peers + rpc: remove cs_main lock from `createrawtransaction` + +fanquake (2): + [build] Add NETBSD leveldb target to configure.ac + [doc] Improve lanaguge in reducetraffic.md + +kirkalx (1): + peers.dat, banlist.dat recreated when missing + +randy-waterhouse (1): + Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035. + +Jack Grigg (1): + Update URL for Zcash Foundation security policy + +Ying Tong Lai (2): + Cargo update + Postpone dependencies + +tulip (1): + Move time data log print to 'net' category to reduce log noise + +Benjamin Winston (1): + Added foundation to responsible_disclosure.md + diff --git a/depend/zcash/doc/release-notes/release-notes-4.3.0.md b/depend/zcash/doc/release-notes/release-notes-4.3.0.md new file mode 100644 index 000000000..7bfbff125 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.3.0.md @@ -0,0 +1,331 @@ +Notable changes +=============== + +Reduce download traffic +----------------------- + +We have made several changes to reduce the amount of data downloaded by `zcashd` +during initial block download (IBD): + +- Significant time and bandwidth is spent in issuing `getheaders` P2P requests. + This results in noticeable bandwidth usage due to the large size of Zcash + block headers. + + We now eliminate redundant requests in cases where we already know the last + header in the message. This optimization is enabled by default, but can be + disabled by setting the config option `-nooptimize-getheaders`. + +- Transactions in the mempool are no longer downloaded during IBD (`zcashd` will + only request block data). + +Reduce upload traffic +--------------------- + +A major part of the outbound traffic is caused by serving historic blocks to +other nodes in initial block download state. + +It is now possible to reduce the total upload traffic via the `-maxuploadtarget` +parameter. This is *not* a hard limit but a threshold to minimize the outbound +traffic. When the limit is about to be reached, the uploaded data is cut by not +serving historic blocks (blocks older than one week). +Moreover, any SPV peer is disconnected when they request a filtered block. + +This option can be specified in MiB per day and is turned off by default +(`-maxuploadtarget=0`). +The recommended minimum is 1152 * MAX_BLOCK_SIZE (currently 2304MB) per day. + +Whitelisted peers will never be disconnected, although their traffic counts for +calculating the target. + +A more detailed documentation about keeping traffic low can be found in +[/doc/reduce-traffic.md](/doc/reduce-traffic.md). + +`libzcashconsensus` replaced by `libzcash_script` +------------------------------------------------- + +The `libzcashconsensus` library inherited from upstream has been unusable since +the Overwinter network upgrade in 2018. We made changes to signature digests +similar to those made in Bitcoin's SegWit, which required additional per-input +data that could not be added to the existing APIs without breaking backwards +compatibility. + +Additionally, it has become increasingly inaccurately named; it only covers +(Zcash's subset of) the Bitcoin scripting system, and not the myriad of other +consensus changes: in particular, Zcash's shielded pools. + +We have now renamed the library to `libzcash_script`, and reworked it to instead +focus on transparent script verification: + +- The script verification APIs are altered to take `consensusBranchId` and + `amount` fields. +- New precomputing APIs have been added that enable multiple transparent inputs + on a single transaction to be verified more efficiently. +- Equihash has been removed from the compiled library. The canonical Equihash + validator is the [`equihash` Rust crate](https://crates.io/crates/equihash) + since v3.1.0. + +The C++ library can be built by compiling `zcashd` with the environment variable +`CONFIGURE_FLAGS=--with-libs`. It is also wrapped as the +[`zcash_script` Rust crate](https://crates.io/crates/zcash_script) +(maintained by the Zcash Foundation for use in `zebrad`). + +Other P2P Changes +----------------- + +The list of banned peers is now stored on disk rather than in memory. Restarting +`zcashd` will no longer clear out the list of banned peers; instead the +`clearbanned` RPC method can be used to manually clear the list. The `setban` +RPC method can also be used to manually ban or unban a peer. + +Build system updates +-------------------- + +- We now build with Clang 11 and Rust 1.49. +- We have downgraded Boost to 1.74 to mitigate `statx`-related breakage in some + container environments. + +Changelog +========= + +Alex Wied (3): + Add support for FreeBSD 12 + Set rust_target for all FreeBSD versions + Use parentheses for defined in windows-unused-variables.diff + +Alfredo Garcia (3): + split wallet.py tests + hide password in -stdin `walletpassphrase` command + Apply suggestions from code review + +Bernhard M. Wiedemann (1): + Make tests pass after 2020 + +BtcDrak (1): + Remove bad chain alert partition check + +Carl Dong (13): + build: Add variable printing target to Makefiles + depends: Propagate well-known vars into depends + depends: boost: Specify toolset to bootstrap.sh + depends: boost: Split target-os from toolset + depends: boost: Use clang toolset if clang in CXX + depends: Propagate only specific CLI variables to sub-makes + depends: boost: Refer to version in URL + depends: boost: Split into non-/native packages + depends: boost: Disable all compression + depends: boost: Cleanup architecture/address-model + depends: boost: Cleanup toolset selection + depends: boost: Remove unnecessary _archiver_ + depends: boost: Specify cflags+compileflags + +Casey Rodarmor (3): + Make limited map actually respect max size + Disallow unlimited limited maps + Add limitedmap test + +Cory Fields (6): + depends: fix boost mac cross build with clang 9+ + build: add missing leveldb defines + net: make Ban/Unban/ClearBan functionality consistent + net: No need to export DumpBanlist + net: move CBanDB and CAddrDB out of net.h/cpp + net: Drop CNodeRef for AttemptToEvictConnection + +Daira Hopwood (2): + qa/zcash/updatecheck.py: remove dead code; print instructions to run `cargo outdated` and `cargo update`. + Ensure that `CONFIGURE_FLAGS=--enable-debug` correctly uses -O0 for dependencies and main build. + +Daniel Kraft (1): + doc: add comment explaining initial header request + +Dimitris Apostolou (1): + Discord invite instead of direct link + +Ethan Heilman (1): + Fix de-serialization bug where AddrMan is corrupted after exception * CAddrDB modified so that when de-serialization code throws an exception Addrman is reset to a clean state * CAddrDB modified to make unit tests possible * Regression test created to ensure bug is fixed * StartNode modifed to clear adrman if CAddrDB::Read returns an error code. + +Gregory Maxwell (2): + Return early in IsBanned. + Disconnect on mempool requests from peers when over the upload limit. + +Igor Cota (1): + Define TARGET_OS when host is android + +Jack Grigg (46): + Add JSDescriptionInfo for constructing JSDescriptions + Remove JSDescription::h_sig + prevector: Terminate without logging on failed allocation + Remove init_and_check_sodium from crypto/common.h + Store inputs and outputs by reference in JSDescriptionInfo + depends: Update Rust to 1.49.0 + rust: Use renamed broken_intra_doc_links lint + depends: cargo update + depends: Move to Clang 11 + depends: Fix Boost warnings under Clang 11 + depends: Allow per-host package download paths + depends: Ensure the native_clang download path is for the builder + Revert "Update boost to 1.75, postpone other updates." + qa: Postpone Boost and native_b2 updates + QA: Remove unused update postponements + QA: Postpone BDB update again + depends: ZeroMQ 4.3.4 + depends: Postpone updates that require adding CMake + cargo update + Squashed 'src/univalue/' changes from 9ef5b78c1..98fadc090 + Remove crypto/equihash from libzcashconsensus + Add amount and consensus branch ID to zcashconsensus_verify_script + Rename src/script/zcashconsensus.* -> src/script/zcash_script.* + Rename zcashconsensus_* -> zcash_script_* in APIs + Rename libzcashconsensus.la -> libzcash_script.la + Set up an mdbook in which we can document zcashd's architecture design + Actions: Add a workflow to deploy the zcashd book + Show README as root of zcashd book + Link to zips.z.cash for protocol spec + test: Convert Bech32 test vectors into known-answer test vectors + zcash_script: Add API to verify scripts with precomputed tx data + test: Migrate maxuploadtarget.py to Python 3 + Pass current PoWTargetSpacing() into CNode::OutboundTargetReached() + init: Pass post-Blossom spacing into CNode::SetMaxOutboundTarget() + Fix some typos + zcash_script: Clarify return values in docs + Rename responsible_disclosure.md to SECURITY.md + Add IBD download traffic reduction to release notes + Fill out the rest of the 4.3.0 release notes + make-release.py: Versioning changes for 4.3.0-rc1. + make-release.py: Updated manpages for 4.3.0-rc1. + make-release.py: Updated release notes and changelog for 4.3.0-rc1. + cargo update + rust: Pin funty =1.1.0 + make-release.py: Versioning changes for 4.3.0. + make-release.py: Updated manpages for 4.3.0. + +Jeremy Rubin (1): + Minimal fix to slow prevector tests as stopgap measure + +Jonas Schnelli (14): + banlist.dat: store banlist on disk + CAddrDB/CBanDB: change filesize variables from int to uint64_t + use CBanEntry as object container for banned nodes + Adding CSubNet constructor over a single CNetAddr + [Qt] add ui signal for banlist changes + [Qt] banlist, UI optimizing and better signal handling + net: use CIDR notation in CSubNet::ToString() + [QA] fix netbase tests because of new CSubNet::ToString() output + Introduce -maxuploadtarget + [doc] add documentation how to reduce traffic + don't enforce maxuploadtargets disconnect for whitelisted peers + [docs] rename reducetraffic.md to reduce-traffic.md + add documentation for exluding whitelistes peer from maxuploadtarget + add (max)uploadtarget infos to getnettotals RPC help + +Josh Lehan (1): + Re-organize -maxconnections option handling + +Karel Bilek (1): + scripted-diff: Use UniValue.pushKV instead of push_back(Pair()) + +Kaz Wesley (4): + fix race that could fail to persist a ban + prevector: destroy elements only via erase() + test prevector::swap + prevector::swap: fix (unreached) data corruption + +Kris Nuttycombe (4): + Skip "tx" messages during initial block download. + Fix pyflakes complaints + Whitespace-only fix in chainparams.cpp + Update the maxuploadtarget.py tests to accommodate zcash. + +Larry Ruane (1): + #4624 improve IBD sync by eliminating getheaders requests + +Marco Falke (3): + [net] Cleanup maxuploadtarget + [doc] Add -maxuploadtarget release notes + [walletdb] Add missing LOCK() in Recover() for dummyWallet + +Marius Kjærstad (3): + Update _COPYRIGHT_YEAR in configure.ac to 2021 + Update COPYRIGHT_YEAR in clientversion.h to 2021 + Update of copyright year to 2021 + +Marshall Gaucher (1): + add libxml2 + +Matt Corallo (6): + Default to defining endian-conversion DECLs in compat w/o config + Make fDisconnect an std::atomic + Make fImporting an std::atomic + Fix AddrMan locking + Remove double brackets in addrman + Fix unlocked access to vNodes.size() + +Patrick Strateman (1): + Avoid recalculating vchKeyedNetGroup in eviction logic. + +Peter Bushnell (1): + depends: Consistent use of package variable + +Peter Todd (1): + Remove LOCK(cs_main) from decodescript + +Philip Kaufmann (4): + banlist: update set dirty to be more fine grained + banlist: better handling of banlist in StartNode() + banlist: add more banlist infos to log / add GUI signal + banlist (bugfix): allow CNode::SweepBanned() to run on interval + +Pieter Wuille (11): + Add SipHash-2-4 primitives to hash + Use SipHash-2-4 for CCoinsCache index + Switch CTxMempool::mapTx to use a hash index for txids + Use SipHash-2-4 for address relay selection + Add extra message to avoid a long 'Loading banlist' + Support SipHash with arbitrary byte writes + Use 64-bit SipHash of netgroups in eviction + Use C++11 thread-safe static initializers + Add ChaCha20 + Switch FastRandomContext to ChaCha20 + Add a FastRandomContext::randrange and use it + +Suhas Daftuar (1): + Add RPC test for -maxuploadtarget + +Taylor Hornby (2): + Move the github API token out of updatecheck.py into an untracked file. + Document the required .updatecheck-token file in the release docs + +Wladimir J. van der Laan (6): + build: Updates for OpenBSD + net: Fix CIDR notation in ToString() + test: Add more test vectors for siphash + timedata: Prevent warning overkill + Always allow getheaders from whitelisted peers + rpc: remove cs_main lock from `createrawtransaction` + +fanquake (2): + [build] Add NETBSD leveldb target to configure.ac + [doc] Improve lanaguge in reducetraffic.md + +kirkalx (1): + peers.dat, banlist.dat recreated when missing + +Marshall Gaucher (1): + add zstd package + +randy-waterhouse (1): + Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e035. + +Jack Grigg (1): + Update URL for Zcash Foundation security policy + +Ying Tong Lai (2): + Cargo update + Postpone dependencies + +tulip (1): + Move time data log print to 'net' category to reduce log noise + +Benjamin Winston (1): + Added foundation to responsible_disclosure.md + diff --git a/depend/zcash/doc/release-notes/release-notes-4.4.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.4.0-rc1.md new file mode 100644 index 000000000..6a84fc879 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.4.0-rc1.md @@ -0,0 +1,187 @@ +Notable changes +=============== + +Prometheus metrics +------------------ + +`zcashd` can now be configured to optionally expose an HTTP server that acts as +a Prometheus scrape endpoint. The server will respond to `GET` requests on any +request path. + +To enable the endpoint, add `-prometheusport=` to your `zcashd` +configuration (either in `zcash.conf` or on the command line). After +restarting `zcashd` you can then test the endpoint by querying it with e.g. +`curl http://127.0.0.1:`. + +By default, access is restricted to localhost. This can be expanded with +`-metricsallowip=`, which can specify IPs or subnets. Note that HTTPS is not +supported, and therefore connections to the endpoint are not encrypted or +authenticated. Access to the endpoint should be assumed to compromise the +privacy of node operations, by the provided metrics and/or by timing side +channels. Non-localhost access is **strongly discouraged** if the node has a +wallet holding live funds. + +The specific metrics names may change in subsequent releases, in particular to +improve interoperability with `zebrad`. + +Changelog +========= + +Cory Fields (3): + net: rearrange so that socket accesses can be grouped together + net: add a lock around hSocket + net: fix a few races. Credit @TheBlueMatt + +Daira Hopwood (6): + Fix regression introduced in e286250ce49309bfa931b622fabfc37100246266 by adding #include . fixes #5014 + native_rust: don't install Rust docs. This speeds up builds, especially native builds on macOS. fixes #5042 + Delete spare mainnet Founders' Reward addresses that will never be used. + configure.ac: Add check for ntdll on Windows. + configure.ac: tidy up spacing. + Cleanup: get the definition of ENABLE_VIRTUAL_TERMINAL_PROCESSING from wincon.h. + +Gregory Maxwell (5): + Replace setInventoryKnown with a rolling bloom filter. + Remove mruset as it is no longer used. + Actually only use filterInventoryKnown with MSG_TX inventory messages. + Add whitelistforcerelay to control forced relaying. + Blacklist -whitelistalwaysrelay; replaced by -whitelistrelay. + +Jack Grigg (39): + Squashed 'src/secp256k1/' changes from c6b6b8f1bb..3967d96bf1 + Squashed 'src/secp256k1/' changes from 3967d96bf1..a4abaab793 + CI: Correctly build zcashd book + cargo update + rust: zcash_{primitives, proofs} 0.5.0 + depends: Update Rust to 1.51.0 + qa: Update BerkeleyDB downloads page URL + rust: Implement FFI interface to metrics crate + rust: Add a Prometheus metrics exporter + Add some metrics that match existing zebrad metrics + metrics: Add documentation and example configs + tracing: Merge TracingSpanFields macro into TracingSpan + rust: Move helper macros into rust/helpers.h + metrics: Add support for labels + metrics: Expose binary metadata + Add more detailed metrics + rust: Use consistent include guards in header files + rust: Check for invalid UTF-8 in -prometheusmetrics argument + Add -prometheusmetrics to release notes + Mention in release notes that metrics names may still change + metrics: Implement IP access control on Prometheus scrape endpoint + rust: Pin hyper 0.14.2 + metrics: Move documentation into zcashd book + metrics: Enable gauges with fully-static labels + metrics: Use labels for pool statistics + metrics: Rename metrics with consistent naming scheme + metrics: Remove zcash.sync.* metrics + metrics: Rework pool metrics in anticipation of transparent pool + net: Clear CNode::strSendCommand if a message is aborted + rust: Add license header to metrics_ffi::prometheus + book: Fix typo in metrics documentation + metrics: Don't assert that the Sprout tree is accessible + Remove usage of local from fetch-params.sh + lint: Fix false positive + qa: Point univalue update checker at correct upstream + qa: Postpone updates that require CMake in the build system + qa: Postpone Boost 1.75.0 + make-release.py: Versioning changes for 4.4.0-rc1. + make-release.py: Updated manpages for 4.4.0-rc1. + +Jeremy Rubin (2): + Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. + Add CheckQueue Tests + +Jonas Schnelli (1): + Move -blocksonly parameter interaction to the new ParameterInteraction() function + +Kaz Wesley (2): + lock cs_main for State/Misbehaving + lock cs_main for chainActive + +Kris Nuttycombe (14): + Ignore temporary build artifacts. + Add feature flagging infrastructure to consensus parameters. + Relocate contextual Sapling version checks + Add TxVersionInfo for feature/future-base transaction construction. + Move sapling version group checks back inside of saplingActive check. + Add future version group & version checks + Use SPROUT_MAX_CURRENT_VERSION + Apply suggestions from code review + Add feature flagging tests. + Document FeatureSet type. + Document UPGRADE_ZFUTURE + Ensure that Sapling version range checks are always guarded by SAPLING_VERSION_GROUP_ID + Address review comments. + CurrentTxVersionInfo should return SPROUT_MIN_CURRENT_VERSION pre-overwinter. + +Marco Falke (2): + Move blocksonly parameter interaction to InitParameterInteraction() + doc: Mention blocksonly in reduce-traffic.md, unhide option + +Matt Corallo (13): + Fix race when accessing std::locale::classic() + Lock mapArgs/mapMultiArgs access in util + Ensure cs_vNodes is held when using the return value from FindNode + Access WorkQueue::running only within the cs lock. + Make nTimeConnected const in CNode + Avoid copying CNodeStats to make helgrind OK with buggy std::string + Access fRelayTxes with cs_filter lock in copyStats + Make nStartingHeight atomic + Make nServices atomic + Move [clean|str]SubVer writes/copyStats into a lock + Make nTimeBestReceived atomic + Move CNode::addrName accesses behind locked accessors + Move CNode::addrLocal access behind locked accessors + +Patick Strateman (13): + Add blocksonly mode + Do not process tx inv's in blocksonly mode + Add whitelistalwaysrelay option + Add help text for blocksonly and whitelistalwaysrelay + Use DEFAULT_BLOCKSONLY and DEFAULT_WHITELISTALWAYSRELAY constants + Display DEFAULT_WHITELISTALWAYSRELAY in help text + Fix fRelayTxs comment + Fix comment for blocksonly parameter interactions + Fix relay mechanism for whitelisted peers under blocks only mode. + Bail early in processing transactions in blocks only mode. + Improve log messages for blocks only violations. + Rename setInventoryKnown filterInventoryKnown + Only use filterInventoryKnown with MSG_TX inventory messages. + +Patrick Strateman (1): + Make nWalletDBUpdated atomic to avoid a potential race. + +Pavel Janík (2): + Notify other serviceQueue thread we are finished to prevent deadlocks. + Do not shadow LOCK's criticalblock variable for LOCK inside LOCK + +Peter Todd (1): + Add relaytxes status to getpeerinfo + +Pieter Wuille (2): + Clean up lockorder data of destroyed mutexes + Fix some locks + +Russell Yanofsky (1): + Add missing cs_wallet lock that triggers new lock held assertion + +Sjors Provoost (1): + [doc] mention whitelist is inbound, and applies to blocksonly + +Steven Smith (1): + Adding base NU5 declarations and logic + +Yuri Zhykin (1): + Fix for incorrect locking in GetPubKey() (keystore.cpp) + +glowang (1): + Update -blocksonly documentation + +plutoforever (1): + removed bashisms from build scripts + +Jack Grigg (2): + Add security warnings for -prometheusmetrics option + Clean up comment + diff --git a/depend/zcash/doc/release-notes/release-notes-4.4.0.md b/depend/zcash/doc/release-notes/release-notes-4.4.0.md new file mode 100644 index 000000000..2bae0c2c7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.4.0.md @@ -0,0 +1,197 @@ +Notable changes +=============== + +Prometheus metrics +------------------ + +`zcashd` can now be configured to optionally expose an HTTP server that acts as +a Prometheus scrape endpoint. The server will respond to `GET` requests on any +request path. + +To enable the endpoint, add `-prometheusport=` to your `zcashd` +configuration (either in `zcash.conf` or on the command line). After +restarting `zcashd` you can then test the endpoint by querying it with e.g. +`curl http://127.0.0.1:`. + +By default, access is restricted to localhost. This can be expanded with +`-metricsallowip=`, which can specify IPs or subnets. Note that HTTPS is not +supported, and therefore connections to the endpoint are not encrypted or +authenticated. Access to the endpoint should be assumed to compromise the +privacy of node operations, by the provided metrics and/or by timing side +channels. Non-localhost access is **strongly discouraged** if the node has a +wallet holding live funds. + +The specific metrics names may change in subsequent releases, in particular to +improve interoperability with `zebrad`. + +Changelog +========= + +Cory Fields (3): + net: rearrange so that socket accesses can be grouped together + net: add a lock around hSocket + net: fix a few races. Credit @TheBlueMatt + +Daira Hopwood (6): + Fix regression introduced in e286250ce49309bfa931b622fabfc37100246266 by adding #include . fixes #5014 + native_rust: don't install Rust docs. This speeds up builds, especially native builds on macOS. fixes #5042 + Delete spare mainnet Founders' Reward addresses that will never be used. + configure.ac: Add check for ntdll on Windows. + configure.ac: tidy up spacing. + Cleanup: get the definition of ENABLE_VIRTUAL_TERMINAL_PROCESSING from wincon.h. + +Gregory Maxwell (5): + Replace setInventoryKnown with a rolling bloom filter. + Remove mruset as it is no longer used. + Actually only use filterInventoryKnown with MSG_TX inventory messages. + Add whitelistforcerelay to control forced relaying. + Blacklist -whitelistalwaysrelay; replaced by -whitelistrelay. + +Jack Grigg (49): + Squashed 'src/secp256k1/' changes from c6b6b8f1bb..3967d96bf1 + Squashed 'src/secp256k1/' changes from 3967d96bf1..a4abaab793 + CI: Correctly build zcashd book + cargo update + rust: zcash_{primitives, proofs} 0.5.0 + depends: Update Rust to 1.51.0 + qa: Update BerkeleyDB downloads page URL + rust: Implement FFI interface to metrics crate + rust: Add a Prometheus metrics exporter + Add some metrics that match existing zebrad metrics + metrics: Add documentation and example configs + tracing: Merge TracingSpanFields macro into TracingSpan + rust: Move helper macros into rust/helpers.h + metrics: Add support for labels + metrics: Expose binary metadata + Add more detailed metrics + rust: Use consistent include guards in header files + rust: Check for invalid UTF-8 in -prometheusmetrics argument + Add -prometheusmetrics to release notes + Mention in release notes that metrics names may still change + metrics: Implement IP access control on Prometheus scrape endpoint + rust: Pin hyper 0.14.2 + metrics: Move documentation into zcashd book + metrics: Enable gauges with fully-static labels + metrics: Use labels for pool statistics + metrics: Rename metrics with consistent naming scheme + metrics: Remove zcash.sync.* metrics + metrics: Rework pool metrics in anticipation of transparent pool + net: Clear CNode::strSendCommand if a message is aborted + rust: Add license header to metrics_ffi::prometheus + book: Fix typo in metrics documentation + metrics: Don't assert that the Sprout tree is accessible + Remove usage of local from fetch-params.sh + lint: Fix false positive + qa: Point univalue update checker at correct upstream + qa: Postpone updates that require CMake in the build system + qa: Postpone Boost 1.75.0 + make-release.py: Versioning changes for 4.4.0-rc1. + make-release.py: Updated manpages for 4.4.0-rc1. + make-release.py: Updated release notes and changelog for 4.4.0-rc1. + scripted-diff: Remove direct usages of boost::filesystem + Remove duplicate / unused includes + Fix include guards + python: Use UTF-8 encodings for opened files + clean.sh: Remove secp256k1 test log + Postpone Clang 12 + book: Fix comment in metrics example, and clarify usage + make-release.py: Versioning changes for 4.4.0. + make-release.py: Updated manpages for 4.4.0. + +Jeremy Rubin (2): + Fix CCheckQueue IsIdle (potential) race condition and remove dangerous constructors. + Add CheckQueue Tests + +Jonas Schnelli (1): + Move -blocksonly parameter interaction to the new ParameterInteraction() function + +Kaz Wesley (2): + lock cs_main for State/Misbehaving + lock cs_main for chainActive + +Kris Nuttycombe (14): + Ignore temporary build artifacts. + Add feature flagging infrastructure to consensus parameters. + Relocate contextual Sapling version checks + Add TxVersionInfo for feature/future-base transaction construction. + Move sapling version group checks back inside of saplingActive check. + Add future version group & version checks + Use SPROUT_MAX_CURRENT_VERSION + Apply suggestions from code review + Add feature flagging tests. + Document FeatureSet type. + Document UPGRADE_ZFUTURE + Ensure that Sapling version range checks are always guarded by SAPLING_VERSION_GROUP_ID + Address review comments. + CurrentTxVersionInfo should return SPROUT_MIN_CURRENT_VERSION pre-overwinter. + +Marco Falke (2): + Move blocksonly parameter interaction to InitParameterInteraction() + doc: Mention blocksonly in reduce-traffic.md, unhide option + +Matt Corallo (13): + Fix race when accessing std::locale::classic() + Lock mapArgs/mapMultiArgs access in util + Ensure cs_vNodes is held when using the return value from FindNode + Access WorkQueue::running only within the cs lock. + Make nTimeConnected const in CNode + Avoid copying CNodeStats to make helgrind OK with buggy std::string + Access fRelayTxes with cs_filter lock in copyStats + Make nStartingHeight atomic + Make nServices atomic + Move [clean|str]SubVer writes/copyStats into a lock + Make nTimeBestReceived atomic + Move CNode::addrName accesses behind locked accessors + Move CNode::addrLocal access behind locked accessors + +Patick Strateman (13): + Add blocksonly mode + Do not process tx inv's in blocksonly mode + Add whitelistalwaysrelay option + Add help text for blocksonly and whitelistalwaysrelay + Use DEFAULT_BLOCKSONLY and DEFAULT_WHITELISTALWAYSRELAY constants + Display DEFAULT_WHITELISTALWAYSRELAY in help text + Fix fRelayTxs comment + Fix comment for blocksonly parameter interactions + Fix relay mechanism for whitelisted peers under blocks only mode. + Bail early in processing transactions in blocks only mode. + Improve log messages for blocks only violations. + Rename setInventoryKnown filterInventoryKnown + Only use filterInventoryKnown with MSG_TX inventory messages. + +Patrick Strateman (1): + Make nWalletDBUpdated atomic to avoid a potential race. + +Pavel Janík (2): + Notify other serviceQueue thread we are finished to prevent deadlocks. + Do not shadow LOCK's criticalblock variable for LOCK inside LOCK + +Peter Todd (1): + Add relaytxes status to getpeerinfo + +Pieter Wuille (2): + Clean up lockorder data of destroyed mutexes + Fix some locks + +Russell Yanofsky (1): + Add missing cs_wallet lock that triggers new lock held assertion + +Sjors Provoost (1): + [doc] mention whitelist is inbound, and applies to blocksonly + +Steven Smith (1): + Adding base NU5 declarations and logic + +Yuri Zhykin (1): + Fix for incorrect locking in GetPubKey() (keystore.cpp) + +glowang (1): + Update -blocksonly documentation + +plutoforever (1): + removed bashisms from build scripts + +Jack Grigg (2): + Add security warnings for -prometheusmetrics option + Clean up comment + diff --git a/depend/zcash/doc/release-notes/release-notes-4.4.1-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.4.1-rc1.md new file mode 100644 index 000000000..5c65bb924 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.4.1-rc1.md @@ -0,0 +1,128 @@ +Notable changes +=============== + +Build system changes +-------------------- + +- Cross-compilation support for Windows XP, Windows Vista, and 32-bit Windows + binaries, has been removed. Cross-compiled Windows binaries are now 64-bit + only, and target a minimum of Windows 7. + +Changelog +========= + +251 (1): + Removes unsed `CBloomFilter` constructor. + +Akio Nakamura (1): + Prevent mutex lock fail even if --enable-debug + +Anthony Towns (1): + doc: clarify CRollingBloomFilter size estimate + +Ben Woosley (1): + Drop defunct Windows compat fixes + +Chun Kuan Lee (3): + windows: Set _WIN32_WINNT to 0x0601 (Windows 7) + windows: Call SetProcessDEPPolicy directly + build: Remove WINVER pre define in Makefile.leveldb.inlcude + +Cory Fields (2): + rpc: work-around an upstream libevent bug + rpc: further constrain the libevent workaround + +Jack Grigg (7): + build: Link to libbcrypt on Windows + doc: Add Windows version support change to release notes + Postpone dependency updates until after 4.4.1 + Fix Rust dependency name in postponed-updates.txt + Postpone native_ccache 4.3 + make-release.py: Versioning changes for 4.4.1-rc1. + make-release.py: Updated manpages for 4.4.1-rc1. + +João Barbosa (5): + bench: Add benchmark for CRollingBloomFilter::reset + refactor: Improve CRollingBloomFilter::reset by using std::fill + wallet: Remove unnecessary mempool lock in ReacceptWalletTransactions + [rpc] Reduce scope of cs_main and cs_wallet locks in listtransactions + [wallet] Make CWallet::ListCoins atomic + +Karl-Johan Alm (1): + Refactor: Remove using namespace from src/*.cpp. + +Larry Ruane (1): + when rewinding, set pindexBestHeader to the highest-work block index + +Luke Dashjr (2): + depends: Patch libevent build to fix IPv6 -rpcbind on Windows + Move Win32 defines to configure.ac to ensure they are globally defined + +Marko Bencun (1): + keystore GetKeys(): return result instead of writing to reference + +Martin Ankerl (1): + replace modulus with FastMod + +Matt Corallo (4): + Add ability to assert a lock is not held in DEBUG_LOCKORDER + Remove redundant pwallet nullptr check + Hold mempool.cs for the duration of ATMP. + Add braces to meet code style on line-after-the-one-changed. + +MeshCollider (1): + Make fUseCrypto atomic + +Pavel Janík (1): + Do not shadow variables + +Pieter Wuille (3): + Switch to a more efficient rolling Bloom filter + Fix formatting of NOPs for generated script tests + More efficient bitsliced rolling Bloom filter + +Robert McLaughlin (1): + trivial: fix bloom filter init to isEmpty = true + +Russell Yanofsky (1): + Acquire cs_main lock before cs_wallet during wallet initialization + +S. Matthew English (1): + unification of Bloom filter representation + +Sebastian Falbesoner (2): + refactor: Remove unused methods CBloomFilter::reset()/clear() + net: remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix + +Wladimir J. van der Laan (3): + http: Join worker threads before deleting work queue + http: Remove WaitExit from WorkQueue + http: Remove numThreads and ThreadCounter + +fanquake (6): + build: remove WINDOWS_BITS from build system + build: remove configure checks for win libraries we don't link against + build: remove --large-address-aware linker flag + build: don't pass -w when building for Windows + build: enforce minimum required Windows version (7) + build: pass _WIN32_WINNT=0x0601 when building libevent for Windows + +kobake (2): + Fix msvc compiler error C4146 (minus operator applied to unsigned type) + Fix msvc compiler error C4146 (unary minus operator applied to unsigned type) + +Marshall Gaucher (3): + Add Debian 11 ci-builder + clean up ubuntu 18.04 and 20.04 commands + add tekton build/worker docker, organize legacy buildbot docker + +practicalswift (2): + addrman: Add missing lock in Clear() (CAddrMan) + Add missing cs_main locks when calling blockToJSON/blockheaderToJSON + +Jack Grigg (1): + doc: Add removal of 32-bit Windows binaries to release notes + +ロãƒãƒ³ ダル (1): + param variables made const + diff --git a/depend/zcash/doc/release-notes/release-notes-4.4.1.md b/depend/zcash/doc/release-notes/release-notes-4.4.1.md new file mode 100644 index 000000000..8cc5f3224 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.4.1.md @@ -0,0 +1,156 @@ +Notable changes +=============== + +Fixed chain sync stall bug +-------------------------- + +The 4.3.0 release included a change to prevent redundant `getheaders` P2P +requests, to reduce node bandwith usage. This behaviour could be disabled by +setting the config option `-nooptimize-getheaders`. + +It turns out that these redundant requests were masking an unrelated bug in the +chain-rewinding logic that is used when the node detects a change to the +consensus rules (for example, if a user forgets to upgrade their `zcashd` node +before a network upgrade activates, and temporarily follows an un-upgraded chain +before restarting with the latest version). + +In certain uncommon scenarios, a node could end up in a situation where it would +believe that the best header it knew about was more than 160 blocks behind its +actual best-known block. The redundant `getheaders` requests meant that this did +not cause an issue, because the node would continue requesting headers until it +found new blocks. After the `getheaders` optimizations, if a peer returned a +`headers` message that was entirely known to the node, it would stop requesting +more headers from that peer; this eventually caused node synchronization to +stall. Restarting with the `-nooptimize-getheaders` config option would enable +the node to continue syncing. + +This release fixes the bug at its source, but the `-nooptimize-getheaders` +config option remains available if necessary. + +Build system changes +-------------------- + +- Cross-compilation support for Windows XP, Windows Vista, and 32-bit Windows + binaries, has been removed. Cross-compiled Windows binaries are now 64-bit + only, and target a minimum of Windows 7. + +Changelog +========= + +251 (1): + Removes unsed `CBloomFilter` constructor. + +Akio Nakamura (1): + Prevent mutex lock fail even if --enable-debug + +Anthony Towns (1): + doc: clarify CRollingBloomFilter size estimate + +Ben Woosley (1): + Drop defunct Windows compat fixes + +Chun Kuan Lee (3): + windows: Set _WIN32_WINNT to 0x0601 (Windows 7) + windows: Call SetProcessDEPPolicy directly + build: Remove WINVER pre define in Makefile.leveldb.inlcude + +Cory Fields (2): + rpc: work-around an upstream libevent bug + rpc: further constrain the libevent workaround + +Jack Grigg (10): + build: Link to libbcrypt on Windows + doc: Add Windows version support change to release notes + Postpone dependency updates until after 4.4.1 + Fix Rust dependency name in postponed-updates.txt + Postpone native_ccache 4.3 + make-release.py: Versioning changes for 4.4.1-rc1. + make-release.py: Updated manpages for 4.4.1-rc1. + make-release.py: Updated release notes and changelog for 4.4.1-rc1. + make-release.py: Versioning changes for 4.4.1. + make-release.py: Updated manpages for 4.4.1. + +João Barbosa (5): + bench: Add benchmark for CRollingBloomFilter::reset + refactor: Improve CRollingBloomFilter::reset by using std::fill + wallet: Remove unnecessary mempool lock in ReacceptWalletTransactions + [rpc] Reduce scope of cs_main and cs_wallet locks in listtransactions + [wallet] Make CWallet::ListCoins atomic + +Karl-Johan Alm (1): + Refactor: Remove using namespace from src/*.cpp. + +Larry Ruane (1): + when rewinding, set pindexBestHeader to the highest-work block index + +Luke Dashjr (2): + depends: Patch libevent build to fix IPv6 -rpcbind on Windows + Move Win32 defines to configure.ac to ensure they are globally defined + +Marko Bencun (1): + keystore GetKeys(): return result instead of writing to reference + +Martin Ankerl (1): + replace modulus with FastMod + +Matt Corallo (4): + Add ability to assert a lock is not held in DEBUG_LOCKORDER + Remove redundant pwallet nullptr check + Hold mempool.cs for the duration of ATMP. + Add braces to meet code style on line-after-the-one-changed. + +MeshCollider (1): + Make fUseCrypto atomic + +Pavel Janík (1): + Do not shadow variables + +Pieter Wuille (3): + Switch to a more efficient rolling Bloom filter + Fix formatting of NOPs for generated script tests + More efficient bitsliced rolling Bloom filter + +Robert McLaughlin (1): + trivial: fix bloom filter init to isEmpty = true + +Russell Yanofsky (1): + Acquire cs_main lock before cs_wallet during wallet initialization + +S. Matthew English (1): + unification of Bloom filter representation + +Sebastian Falbesoner (2): + refactor: Remove unused methods CBloomFilter::reset()/clear() + net: remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix + +Wladimir J. van der Laan (3): + http: Join worker threads before deleting work queue + http: Remove WaitExit from WorkQueue + http: Remove numThreads and ThreadCounter + +fanquake (6): + build: remove WINDOWS_BITS from build system + build: remove configure checks for win libraries we don't link against + build: remove --large-address-aware linker flag + build: don't pass -w when building for Windows + build: enforce minimum required Windows version (7) + build: pass _WIN32_WINNT=0x0601 when building libevent for Windows + +kobake (2): + Fix msvc compiler error C4146 (minus operator applied to unsigned type) + Fix msvc compiler error C4146 (unary minus operator applied to unsigned type) + +Marshall Gaucher (3): + Add Debian 11 ci-builder + clean up ubuntu 18.04 and 20.04 commands + add tekton build/worker docker, organize legacy buildbot docker + +practicalswift (2): + addrman: Add missing lock in Clear() (CAddrMan) + Add missing cs_main locks when calling blockToJSON/blockheaderToJSON + +Jack Grigg (1): + doc: Add removal of 32-bit Windows binaries to release notes + +ロãƒãƒ³ ダル (1): + param variables made const diff --git a/depend/zcash/doc/release-notes/release-notes-4.5.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.5.0-rc1.md new file mode 100644 index 000000000..c91384283 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.5.0-rc1.md @@ -0,0 +1,311 @@ +Changelog +========= + +Aditya Kulkarni (1): + Sort taddr txns by txindex in addition to height + +Alex Morcos (4): + Store the total sig op count of a tx. + Add a score index to the mempool. + Add TxPriority class and comparator + tidy up CInv::GetCommand + +Daira Hopwood (8): + Improve error message when a block would overfill the Orchard commitment tree. + More precise terminology: "lock free" -> "unlocked" + ZIP 339 support. + Update URL for Boost source download (from dl.bintray.com to boostorg.jfrog.io). + Cargo.toml: use librustzcash after the merge of https://github.com/zcash/librustzcash/pull/424 . + Update unified address test data to take account of HRPs in padding (https://github.com/zcash/librustzcash/pull/419). + Avoid need to cast away const in the C caller of zip339_free_phrase. + Update authors of librustzcash to everyone currently and formerly on Core team (in alphabetical order). + +Eric Lombrozo (2): + Removed ppszTypeName from protocol.cpp + getdata enum issue fix + +Ethan Heilman (1): + Fix typo adddrman to addrman as requested in #8070 + +Ethan Heilman (1): + Remove non-determinism which is breaking net_tests #8069 + +Gregory Maxwell (4): + Eliminate TX trickle bypass, sort TX invs for privacy and priority. + Move bloom and feerate filtering to just prior to tx sending. + Do not use mempool for GETDATA for tx accepted after the last mempool req. + Defer inserting into maprelay until just before relaying. + +Jack Grigg (109): + Re-include reading blocks from disk in block connection benchmark + cargo update + Migrate to latest zcash_* crates + metrics 0.16 and metrics-exporter-prometheus 0.5 + Implement ZIP 216 consensus rules + Extract SpendDescriptionV5 and OutputDescriptionV5 classes + rust: Enable C++ streams to be passed into Rust code + ZIP 225 tx format constants + v5 transaction format parser + contrib: Add BOSL to contrib/debian/copyright + Remove early return logic from transaction parsing + rust: Document read_callback_t and write_callback_t + CTransaction: Make new ZIP 225 fields non-const and private + ZIP 244 transaction digests + ZIP 244 signature digests + ZIP 244 hashAuthDataRoot computation + Fix tests that assume CTxOuts can be "null" + test: Generate valid Sapling types + test: Small fixes to sighash test vector generation + test: Regenerate sighash.json after generator fixes + Throw an exception instead of asserting if Rust tx parser fails + CI: Publish correct book directory + CI: Build book with latest mdbook + rust: Documentation improvements to FFI methods + Implement Orchard authorization batch validator + Implement Orchard signature validation consensus rules + rust: Fix patched dependencies + book: Add dev guide page about Rust dependencies + Rename hashLightClientRoot to hashBlockCommitments in block header + ZIP 244 hashBlockCommitments implementation + test: Check for valid hashBlockCommitments construction post-NU5 + Skip hashBlockCommitments check when testing block templates + test: Check hashBlockCommitments before, at, and after NU5 activation + ConnectBlock: Check NU activation when deriving block commitments + Copy authDigest in CTransaction::operator=(const CTransaction &tx) + rust: Move history tree FFI logic into a module + rust: Migrate to zcash_history with versioned trees + rust: Move history tree FFI declarations into a separate header + test: Use valid consensus branch IDs in history tree tests + Use V2 history trees from NU5 onward + test: Check history trees across Canopy and NU5 activations + rpc: Document getblock RPC finalorchardroot field, omit before NU5 + rust: Document some requirements for history tree FFI methods + test: Add test case for popping from an empty history tree + Implement Orchard pool value tracking + rust: Load Orchard circuit parameters at startup + Check Orchard bundle-specific consensus rules, i.e. proofs + test: Update CCoinsViewTest with changes to CCoinsView interface + Include Orchard bundle in transaction dynamic usage + ZIP 203: Enforce coinbase nExpiryHeight consensus rule from NU5 + test: Check for updated empty-tx reject messages in transaction tests + test: Fix OverwinterExpiryHeight test after ZIP 203 contextual changes + miner: Set coinbase expiry height to block height from NU5 activation + Introduce libzcash::RawAddress type + Use `libzcash::RawAddress` in `CWallet::GetFilteredNotes` + Use a visitor for handling -mineraddress config option + Add support for decoding and encoding Unified Addresses + Pass network type through to UA address handling logic + CI: Add workflow that runs general lints + CI: Check scripted diffs + CI: Add Rust lints + Document why a nested call to ExtractMinerAddress is not recursive + Add constants for UA typecodes + Postpone dependency updates we aren't doing in this release + depends: Update Rust to 1.54.0 + depends: Update Clang / libcxx to LLVM 12 + depends: Update utfcpp to 3.2.1 + depends: Fix issue cross-compiling BDB to Windows with Clang 12 + rust: cargo update + rust: metrics 0.17 + CI: Use Rust 1.54 for lints + cargo fmt + test: Wait for transaction propagation in shorter_block_times RPC test + test: Fix race condition in p2p_txexpiringsoon + Revert "Remove reference to -reindex-chainstate" + test: Flush wallet in WriteCryptedSaplingZkeyDirectToDb before reopening + qa: Bump `sync_mempool` timeout for `prioritisetransaction.py` + ProcessGetData(): Rework IsExpiringSoon check + test: Print reject reason if RPC test block rejected instead of accepted + test: Fix pyflakes warnings + CI: Ignore errors from general lints we don't yet have passing + lint: remove duplicate include + lint: Add missing include guards + test: Add NU5 test cases to existing RPC tests + builder: Generate v5 transactions from NU5 activation + Print `nConsensusBranchId` in `CTransaction::ToString` + Separate the consensus and internal consistency checks for branch ID + Parse consensus branch ID when reading v5 transaction format + test: Use correct field of getnetworkinfo to read protocol version + CI: Add Dependabot config to keep Actions up-to-date + Introduce a WTxId struct + Implement CInv message type MSG_WTX + test: Fix bugs in mininode transaction parser + test: Add v5 tx support to mininode + ProcessGetData: Respond to MSG_WTX requests + Add MSG_WTX support to inv messages + Use wtxid for peer state management + test: Implement CInv.__eq__() for mininode to simplify RPC test + Postpone dependency updates that require CMake + depends: Update Rust to 1.54.0 + test: Fix bug in mininode.SpendDescription.deserialize + Add named constants for legacy tx authDigest placeholder value + qa: Boost 1.77.0 + cargo update + Migrate to latest revisions of Zcash Rust crates + test: Set up mininodes at the start of feature_zip239 + net: Reject unknown CInv message types + make-release.py: Versioning changes for 4.5.0-rc1. + make-release.py: Updated manpages for 4.5.0-rc1. + +John Newbery (10): + [tests] Remove wallet accounts test + [wallet] GetBalance can take an isminefilter filter. + [wallet] Factor out GetWatchOnlyBalance() + [wallet] deduplicate GetAvailableCredit logic + [wallet] factor out GetAvailableWatchOnlyBalance() + [wallet] GetBalance can take a min_depth argument. + [RPC] [wallet] allow getbalance to use min_conf and watch_only without accounts. + [wallet] Remove wallet account RPCs + [wallet] Kill accounts + [net] split PushInventory() + +Jonas Schnelli (1): + fix locking issue with new mempool limiting + +Kris Nuttycombe (46): + Update transaction auth commitments for pre-v5 transactions. + Move OrchardBundle to its own header file. + Implement the Rust side of the incremental merkle tree FFI. + Orchard changes to coins & consensus. + Return std::optional for GetAnchor + Check nullifiers length against bundle actions length. + Add Orchard bundle commitments to merkle tree. + Add Orchard merkle tree anchor tests. + Documentation cleanup. + Update orchard dependency. + Update to released version of incrementalmerkletree + Apply suggestions from code review + Apply suggestions from code review + Fix Orchard incremental Merkle tree empty root. + Fix header guards for incremental_sinsemilla_tree.h + Apply style suggestions. + Consistently panic on null commitment tree pointers. + Fix implmentation of OrchardMerkleTree.DynamicMemoryUsage + Document source of Orchard merkle tree test data. + Apply suggestions from code review + Add consensus check for duplicate Orchard nullifiers within a single transaction. + Add Orchard nullifiers to nullifiers cache. + Apply suggestions from code review + Ensure Sapling versions are valid after NU5 + Make CTransaction::nConsensusBranchId a std::optional + Add NU5 upper bound check on nSpendsSapling, nOutputsSapling, nActionsOrchard + Check consensus branch ID for V5 transactions. + Rename tx.valueBalance -> tx.valueBalanceSapling + Make valueBalanceSapling a private non-const member of CTransaction. + Add Orchard value balance checks. + Account for Orchard balance in GetValueOut and GetShieldedValueIn. + Retract partial Orchard test support. + Add check that v5 transactions have empty Sprout joinsplits. + Prevent undefined behaviour in `CTransaction::GetValueOut()` + ZIP 213: Add checks to support Orchard shielded coinbase outputs. + Add check for consistency between nActionsOrchard and Orchard flags. + Ensure that the Orchard note commitment tree does not exceed its maximum size. + Update Orchard commitment tree hashes to use total MerkleCRH^Orchard. + Apply suggestions from code review + Make Sapling Spend and Ouput count, and Orchard Action count checks be noncontextual. + Use DOS level 100 for noncontextual checks. + Fix error strings to correctly reflect context. + Remove unused account-related wallet methods. + Use manual serialization for Merkle frontiers rather than bincode. + Fix clippy complaints. + Lock the wallet in SetBestChainINTERNAL + +Larry Ruane (1): + ZIP 225: v5 transaction check rules + +Luke Dashjr (1): + Optimisation: Store transaction list order in memory rather than compute it every need + +Marco Falke (1): + [qa] py2: Unfiddle strings into bytes explicitly + +Matt Corallo (4): + Fix calling mempool directly, instead of pool, in ATMP + Track (and define) ::minRelayTxFee in CTxMemPool + Add CFeeRate += operator + Print mempool size in KB when adding txn + +Patrick Strateman (5): + Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk + Add CWallet::ListAccountCreditDebit + Add CWallet::ReorderTransactions and use in accounting_tests.cpp + Move CWalletDB::ReorderTransactions to CWallet + Move GetAccountBalance from rpcwallet.cpp into CWallet::GetAccountBalance + +Pieter Wuille (16): + Replace trickle nodes with per-node/message Poisson delays + Change mapRelay to store CTransactions + Make ProcessNewBlock dbp const and update comment + Switch reindexing to AcceptBlock in-loop and ActivateBestChain afterwards + Optimize ActivateBestChain for long chains + Add -reindex-chainstate that does not rebuild block index + Report reindexing progress in GUI + Split up and optimize transaction and block inv queues + Handle mempool requests in send loop, subject to trickle + Return mempool queries in dependency order + Add support for unique_ptr and shared_ptr to memusage + Switch CTransaction storage in mempool to std::shared_ptr + Optimize the relay map to use shared_ptr's + Optimization: don't check the mempool at all if no mempool req ever + Optimization: use usec in expiration and reuse nNow + Get rid of CTxMempool::lookup() entirely + +Russell Yanofsky (2): + [wallet] Add GetLegacyBalance method to simplify getbalance RPC + [wallet] Remove unneeded legacy getbalance code + +Shaul Kfir (1): + Add absurdly high fee message to validation state (for RPC propagation) + +Suhas Daftuar (3): + Use txid as key in mapAlreadyAskedFor + Reverse the sort on the mempool's feerate index + Only use AddInventoryKnown for transactions + +Technetium (1): + add missing aarch64 build deps + +Wladimir J. van der Laan (17): + streams: Add data() method to CDataStream + streams: Remove special cases for ancient MSVC + dbwrapper: Use new .data() method of CDataStream + wallet: Use CDataStream.data() + net: Consistent checksum handling + net: Hardcode protocol sizes and use fixed-size types + protocol.h: Move MESSAGE_START_SIZE into CMessageHeader + protocol.h: Make enums in GetDataMsg concrete values + Add assertion and cast before sending reject code + Add debug message to CValidationState for optional extra information + Introduce REJECT_INTERNAL codes for local AcceptToMempool errors + Add function to convert CValidationState to a human-readable message + Remove most logging from transaction validation + Add information to errors in ConnectBlock, CheckBlock + Move mempool rejections to new debug category + net: Fix sent reject messages for blocks and transactions + test: Add basic test for `reject` code + +hexabot (2): + Update depends/packages/native_clang.mk + Update depends/packages/native_rust.mk + +Marshall Gaucher (5): + Remove sprout funding flow logic + Add fix and note for timing issue + Update funding logic bug + Add usage documentation for manual and faucet driven tests + Update funding logic + +Jack Grigg (12): + Document next_pow2 effects and algorithm source + Improvements to CBlock::BuildAuthDataMerkleTree + rust: Explicitly return null hash for pre-v5 auth digests + book: Note that cargo patches work with absolute paths + Improve docs about setting CBlockIndex hash fields + test: Cleanups to ZIP 221 Python test code + Minor fixes to documentation and formatting + Fix typo in method documentation + Track lengths when copying receiver data from C++ to Rust + depends: Greatly simplify the Clang 12 patch + Adjust code comments to remove topological-sort references + Fix typos + diff --git a/depend/zcash/doc/release-notes/release-notes-4.5.0.md b/depend/zcash/doc/release-notes/release-notes-4.5.0.md new file mode 100644 index 000000000..94453bd74 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.5.0.md @@ -0,0 +1,387 @@ +Notable changes +=============== + +Network Upgrade 5 +----------------- + +The code preparations for the Network Upgrade 5 consensus rules are finished and +included in this release. The following ZIPs are being deployed: + +- [ZIP 216: Require Canonical Jubjub Point Encodings](https://zips.z.cash/zip-0216) +- [ZIP 224: Orchard Shielded Protocol](https://zips.z.cash/zip-0224) +- [ZIP 225: Version 5 Transaction Format](https://zips.z.cash/zip-0225) +- [ZIP 239: Relay of Version 5 Transactions](https://zips.z.cash/zip-0239) +- [ZIP 244: Transaction Identifier Non-Malleability](https://zips.z.cash/zip-0244) + +NU5 will activate on testnet at height **1,590,000**, and can also be activated +at a specific height in regtest mode by setting the config option +`-nuparams=f919a198:HEIGHT`. + +The testnet activation of NU5, and `zcashd` v4.5.0 itself, is aimed at enabling +existing Zcash users to test their software and make the necessary changes to be +compatible with the new consensus rules. In particular: + +- Wallets should start adding support for v5 transactions. +- Miners and mining pools should ensure that their software is compatible with + the semantic change to the block header specified in + [ZIP 244](https://zips.z.cash/zip-0244#block-header-changes) + +A subsequent v4.5.1 release in the coming weeks will add support for generating +and using Unified Addresses ([ZIP 316](https://zips.z.cash/zip-0316)), which +will enable `zcashd` wallets to interact with the Orchard shielded pool. + +As with previous network upgrades, it is possible that backwards-incompatible +changes might be made to the consensus rules in this testing phase, prior to +setting the mainnet activation height. In the event that this happens, testnet +will be rolled back in v5.0.0 and a second testnet activation will occur. + +See [ZIP 252](https://zips.z.cash/zip-0252) for additional information about the +deployment process for NU5. + +Rejecting unknown `CInv` message types +-------------------------------------- + +Previously, if `zcashd` received an `inv` or `getdata` message containing +unknown `CInv` message types, it would ignore them and process the remainder of +the message. Starting with v4.5.0, `zcashd` will instead drop the entire `inv` +or `getdata` message and reply with a `reject` message. This will enable node +operators to discover whether their nodes are sending unexpected `CInv` types; +in particular, node operators should ensure their software does not produce the +`MSG_WTX` CInv message type intended for the Bitcoin network, which is +incompatible with the `MSG_WTX` CInv message type defined in ZIP 239 (which will +be used from NU5 activation for advertising v5 transactions). + +Deprecated or removed RPCs +-------------------------- + +- The 'account' API inherited from Bitcoin Core has been disabled since the + launch of Zcash. Following its deprecation in Bitcoin Core v0.17 and removal + in Bitcoin Core v0.18, we have now removed the API from `zcashd`. + + +Changelog +========= + +Aditya Kulkarni (1): + Sort taddr txns by txindex in addition to height + +Alex Morcos (4): + Store the total sig op count of a tx. + Add a score index to the mempool. + Add TxPriority class and comparator + tidy up CInv::GetCommand + +Daira Hopwood (8): + Improve error message when a block would overfill the Orchard commitment tree. + More precise terminology: "lock free" -> "unlocked" + ZIP 339 support. + Update URL for Boost source download (from dl.bintray.com to boostorg.jfrog.io). + Cargo.toml: use librustzcash after the merge of https://github.com/zcash/librustzcash/pull/424 . + Update unified address test data to take account of HRPs in padding (https://github.com/zcash/librustzcash/pull/419). + Avoid need to cast away const in the C caller of zip339_free_phrase. + Update authors of librustzcash to everyone currently and formerly on Core team (in alphabetical order). + +Eric Lombrozo (2): + Removed ppszTypeName from protocol.cpp + getdata enum issue fix + +Ethan Heilman (1): + Fix typo adddrman to addrman as requested in #8070 + +Ethan Heilman (1): + Remove non-determinism which is breaking net_tests #8069 + +Gregory Maxwell (4): + Eliminate TX trickle bypass, sort TX invs for privacy and priority. + Move bloom and feerate filtering to just prior to tx sending. + Do not use mempool for GETDATA for tx accepted after the last mempool req. + Defer inserting into maprelay until just before relaying. + +Jack Grigg (124): + Re-include reading blocks from disk in block connection benchmark + cargo update + Migrate to latest zcash_* crates + metrics 0.16 and metrics-exporter-prometheus 0.5 + Implement ZIP 216 consensus rules + Extract SpendDescriptionV5 and OutputDescriptionV5 classes + rust: Enable C++ streams to be passed into Rust code + ZIP 225 tx format constants + v5 transaction format parser + contrib: Add BOSL to contrib/debian/copyright + Remove early return logic from transaction parsing + rust: Document read_callback_t and write_callback_t + CTransaction: Make new ZIP 225 fields non-const and private + ZIP 244 transaction digests + ZIP 244 signature digests + ZIP 244 hashAuthDataRoot computation + Fix tests that assume CTxOuts can be "null" + test: Generate valid Sapling types + test: Small fixes to sighash test vector generation + test: Regenerate sighash.json after generator fixes + Throw an exception instead of asserting if Rust tx parser fails + CI: Publish correct book directory + CI: Build book with latest mdbook + rust: Documentation improvements to FFI methods + Implement Orchard authorization batch validator + Implement Orchard signature validation consensus rules + rust: Fix patched dependencies + book: Add dev guide page about Rust dependencies + Rename hashLightClientRoot to hashBlockCommitments in block header + ZIP 244 hashBlockCommitments implementation + test: Check for valid hashBlockCommitments construction post-NU5 + Skip hashBlockCommitments check when testing block templates + test: Check hashBlockCommitments before, at, and after NU5 activation + ConnectBlock: Check NU activation when deriving block commitments + Copy authDigest in CTransaction::operator=(const CTransaction &tx) + rust: Move history tree FFI logic into a module + rust: Migrate to zcash_history with versioned trees + rust: Move history tree FFI declarations into a separate header + test: Use valid consensus branch IDs in history tree tests + Use V2 history trees from NU5 onward + test: Check history trees across Canopy and NU5 activations + rpc: Document getblock RPC finalorchardroot field, omit before NU5 + rust: Document some requirements for history tree FFI methods + test: Add test case for popping from an empty history tree + Implement Orchard pool value tracking + rust: Load Orchard circuit parameters at startup + Check Orchard bundle-specific consensus rules, i.e. proofs + test: Update CCoinsViewTest with changes to CCoinsView interface + Include Orchard bundle in transaction dynamic usage + ZIP 203: Enforce coinbase nExpiryHeight consensus rule from NU5 + test: Check for updated empty-tx reject messages in transaction tests + test: Fix OverwinterExpiryHeight test after ZIP 203 contextual changes + miner: Set coinbase expiry height to block height from NU5 activation + Introduce libzcash::RawAddress type + Use `libzcash::RawAddress` in `CWallet::GetFilteredNotes` + Use a visitor for handling -mineraddress config option + Add support for decoding and encoding Unified Addresses + Pass network type through to UA address handling logic + CI: Add workflow that runs general lints + CI: Check scripted diffs + CI: Add Rust lints + Document why a nested call to ExtractMinerAddress is not recursive + Add constants for UA typecodes + Postpone dependency updates we aren't doing in this release + depends: Update Rust to 1.54.0 + depends: Update Clang / libcxx to LLVM 12 + depends: Update utfcpp to 3.2.1 + depends: Fix issue cross-compiling BDB to Windows with Clang 12 + rust: cargo update + rust: metrics 0.17 + CI: Use Rust 1.54 for lints + cargo fmt + test: Wait for transaction propagation in shorter_block_times RPC test + test: Fix race condition in p2p_txexpiringsoon + Revert "Remove reference to -reindex-chainstate" + test: Flush wallet in WriteCryptedSaplingZkeyDirectToDb before reopening + qa: Bump `sync_mempool` timeout for `prioritisetransaction.py` + ProcessGetData(): Rework IsExpiringSoon check + test: Print reject reason if RPC test block rejected instead of accepted + test: Fix pyflakes warnings + CI: Ignore errors from general lints we don't yet have passing + lint: remove duplicate include + lint: Add missing include guards + test: Add NU5 test cases to existing RPC tests + builder: Generate v5 transactions from NU5 activation + Print `nConsensusBranchId` in `CTransaction::ToString` + Separate the consensus and internal consistency checks for branch ID + Parse consensus branch ID when reading v5 transaction format + test: Use correct field of getnetworkinfo to read protocol version + CI: Add Dependabot config to keep Actions up-to-date + Introduce a WTxId struct + Implement CInv message type MSG_WTX + test: Fix bugs in mininode transaction parser + test: Add v5 tx support to mininode + ProcessGetData: Respond to MSG_WTX requests + Add MSG_WTX support to inv messages + Use wtxid for peer state management + test: Implement CInv.__eq__() for mininode to simplify RPC test + Postpone dependency updates that require CMake + depends: Update Rust to 1.54.0 + test: Fix bug in mininode.SpendDescription.deserialize + Add named constants for legacy tx authDigest placeholder value + qa: Boost 1.77.0 + cargo update + Migrate to latest revisions of Zcash Rust crates + test: Set up mininodes at the start of feature_zip239 + net: Reject unknown CInv message types + make-release.py: Versioning changes for 4.5.0-rc1. + make-release.py: Updated manpages for 4.5.0-rc1. + make-release.py: Updated release notes and changelog for 4.5.0-rc1. + Migrate to latest revisions of orchard and the zcash_* crates + contrib: Add script for generating a graph of our Rust dependencies + cargo update + build: Add primitives/orchard.h to list of header files + build: Ensure that cargo uses vendored dependencies for git repos + build: Add missing source file to zcash_gtest_SOURCES + rust: Move Orchard batch logic into BatchValidator methods + wallet: Batch-validate all Orchard signatures in the wallet on load + rust: Skip running the Orchard batch validator on an empty batch + bench: Add Orchard logic to zcbenchmarks + cargo update + Update halo2 and orchard dependencies with BOSL Zcash exception + make-release.py: Versioning changes for 4.5.0. + make-release.py: Updated manpages for 4.5.0. + +John Newbery (10): + [tests] Remove wallet accounts test + [wallet] GetBalance can take an isminefilter filter. + [wallet] Factor out GetWatchOnlyBalance() + [wallet] deduplicate GetAvailableCredit logic + [wallet] factor out GetAvailableWatchOnlyBalance() + [wallet] GetBalance can take a min_depth argument. + [RPC] [wallet] allow getbalance to use min_conf and watch_only without accounts. + [wallet] Remove wallet account RPCs + [wallet] Kill accounts + [net] split PushInventory() + +Jonas Schnelli (1): + fix locking issue with new mempool limiting + +Kris Nuttycombe (46): + Update transaction auth commitments for pre-v5 transactions. + Move OrchardBundle to its own header file. + Implement the Rust side of the incremental merkle tree FFI. + Orchard changes to coins & consensus. + Return std::optional for GetAnchor + Check nullifiers length against bundle actions length. + Add Orchard bundle commitments to merkle tree. + Add Orchard merkle tree anchor tests. + Documentation cleanup. + Update orchard dependency. + Update to released version of incrementalmerkletree + Apply suggestions from code review + Apply suggestions from code review + Fix Orchard incremental Merkle tree empty root. + Fix header guards for incremental_sinsemilla_tree.h + Apply style suggestions. + Consistently panic on null commitment tree pointers. + Fix implmentation of OrchardMerkleTree.DynamicMemoryUsage + Document source of Orchard merkle tree test data. + Apply suggestions from code review + Add consensus check for duplicate Orchard nullifiers within a single transaction. + Add Orchard nullifiers to nullifiers cache. + Apply suggestions from code review + Ensure Sapling versions are valid after NU5 + Make CTransaction::nConsensusBranchId a std::optional + Add NU5 upper bound check on nSpendsSapling, nOutputsSapling, nActionsOrchard + Check consensus branch ID for V5 transactions. + Rename tx.valueBalance -> tx.valueBalanceSapling + Make valueBalanceSapling a private non-const member of CTransaction. + Add Orchard value balance checks. + Account for Orchard balance in GetValueOut and GetShieldedValueIn. + Retract partial Orchard test support. + Add check that v5 transactions have empty Sprout joinsplits. + Prevent undefined behaviour in `CTransaction::GetValueOut()` + ZIP 213: Add checks to support Orchard shielded coinbase outputs. + Add check for consistency between nActionsOrchard and Orchard flags. + Ensure that the Orchard note commitment tree does not exceed its maximum size. + Update Orchard commitment tree hashes to use total MerkleCRH^Orchard. + Apply suggestions from code review + Make Sapling Spend and Ouput count, and Orchard Action count checks be noncontextual. + Use DOS level 100 for noncontextual checks. + Fix error strings to correctly reflect context. + Remove unused account-related wallet methods. + Use manual serialization for Merkle frontiers rather than bincode. + Fix clippy complaints. + Lock the wallet in SetBestChainINTERNAL + +Larry Ruane (1): + ZIP 225: v5 transaction check rules + +Luke Dashjr (1): + Optimisation: Store transaction list order in memory rather than compute it every need + +Marco Falke (1): + [qa] py2: Unfiddle strings into bytes explicitly + +Matt Corallo (4): + Fix calling mempool directly, instead of pool, in ATMP + Track (and define) ::minRelayTxFee in CTxMemPool + Add CFeeRate += operator + Print mempool size in KB when adding txn + +Patrick Strateman (5): + Fix insanity of CWalletDB::WriteTx and CWalletTx::WriteToDisk + Add CWallet::ListAccountCreditDebit + Add CWallet::ReorderTransactions and use in accounting_tests.cpp + Move CWalletDB::ReorderTransactions to CWallet + Move GetAccountBalance from rpcwallet.cpp into CWallet::GetAccountBalance + +Pieter Wuille (16): + Replace trickle nodes with per-node/message Poisson delays + Change mapRelay to store CTransactions + Make ProcessNewBlock dbp const and update comment + Switch reindexing to AcceptBlock in-loop and ActivateBestChain afterwards + Optimize ActivateBestChain for long chains + Add -reindex-chainstate that does not rebuild block index + Report reindexing progress in GUI + Split up and optimize transaction and block inv queues + Handle mempool requests in send loop, subject to trickle + Return mempool queries in dependency order + Add support for unique_ptr and shared_ptr to memusage + Switch CTransaction storage in mempool to std::shared_ptr + Optimize the relay map to use shared_ptr's + Optimization: don't check the mempool at all if no mempool req ever + Optimization: use usec in expiration and reuse nNow + Get rid of CTxMempool::lookup() entirely + +Russell Yanofsky (2): + [wallet] Add GetLegacyBalance method to simplify getbalance RPC + [wallet] Remove unneeded legacy getbalance code + +Shaul Kfir (1): + Add absurdly high fee message to validation state (for RPC propagation) + +Suhas Daftuar (3): + Use txid as key in mapAlreadyAskedFor + Reverse the sort on the mempool's feerate index + Only use AddInventoryKnown for transactions + +Technetium (1): + add missing aarch64 build deps + +Wladimir J. van der Laan (17): + streams: Add data() method to CDataStream + streams: Remove special cases for ancient MSVC + dbwrapper: Use new .data() method of CDataStream + wallet: Use CDataStream.data() + net: Consistent checksum handling + net: Hardcode protocol sizes and use fixed-size types + protocol.h: Move MESSAGE_START_SIZE into CMessageHeader + protocol.h: Make enums in GetDataMsg concrete values + Add assertion and cast before sending reject code + Add debug message to CValidationState for optional extra information + Introduce REJECT_INTERNAL codes for local AcceptToMempool errors + Add function to convert CValidationState to a human-readable message + Remove most logging from transaction validation + Add information to errors in ConnectBlock, CheckBlock + Move mempool rejections to new debug category + net: Fix sent reject messages for blocks and transactions + test: Add basic test for `reject` code + +hexabot (2): + Update depends/packages/native_clang.mk + Update depends/packages/native_rust.mk + +Marshall Gaucher (5): + Remove sprout funding flow logic + Add fix and note for timing issue + Update funding logic bug + Add usage documentation for manual and faucet driven tests + Update funding logic + +Jack Grigg (12): + Document next_pow2 effects and algorithm source + Improvements to CBlock::BuildAuthDataMerkleTree + rust: Explicitly return null hash for pre-v5 auth digests + book: Note that cargo patches work with absolute paths + Improve docs about setting CBlockIndex hash fields + test: Cleanups to ZIP 221 Python test code + Minor fixes to documentation and formatting + Fix typo in method documentation + Track lengths when copying receiver data from C++ to Rust + depends: Greatly simplify the Clang 12 patch + Adjust code comments to remove topological-sort references + Fix typos + diff --git a/depend/zcash/doc/release-notes/release-notes-4.5.1-1.md b/depend/zcash/doc/release-notes/release-notes-4.5.1-1.md new file mode 100644 index 000000000..f7847c3bc --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.5.1-1.md @@ -0,0 +1,46 @@ +Notable changes +=============== + +Added v5 transactions to standard rules +--------------------------------------- + +In v4.5.0 we added the v5 transaction format to the NU5 consensus rules for +testnet. However, it was omitted from the standard rules, which meant that +`zcashd` testnet nodes would not accept v5 transactions into their mempools, +causing them to not be propagated or mined. This release updates the `zcashd` +standard rules to accept v5 transactions alongside v4 transactions. + +New `listaddresses` RPC method +------------------------------ + +The `listaddresses` endpoint has been added to the RPC API. This method +allows the caller to obtain addresses managed by the wallet, grouped +by the source of the address, including both those addresses generated +by the wallet and those associated with imported viewing or spending +keys. This provides functionality that replaces and subsumes the +previously-removed `getaddressesbyaccount` method. + +Changelog +========= + +Jack Grigg (6): + Mark v5 transaction format as standard for NU5 + Fix comment + cargo update + depends: Postpone dependency updates + make-release.py: Versioning changes for 4.5.1-1. + make-release.py: Updated manpages for 4.5.1-1. + +Kris Nuttycombe (11): + Add `listaddresses` RPC method. + Categorize listaddresses result by source type. + Correctly handle imported Sapling addresses + Apply suggestions from code review + Apply suggestions from code review + Group legacy_hdseed Sapling addresses by account ID. + Update release notes for v4.5.1-1 to reflect the addition of `listaddresses` + Include `ImportedWatchOnly` as a PaymentAddressSource result. + Add listaddresses check to wallet_addresses.py + Consistently group Sapling addresses by IVK for every source. + Use lowerCamelCase for listaddresses JSON + diff --git a/depend/zcash/doc/release-notes/release-notes-4.5.1.md b/depend/zcash/doc/release-notes/release-notes-4.5.1.md new file mode 100644 index 000000000..c0229a5e7 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.5.1.md @@ -0,0 +1,80 @@ +Notable changes +=============== + +Fixed bugs in the testnet Orchard circuit +----------------------------------------- + +In the `zcashd v4.5.0` release notes we indicated that a testnet rollback might +occur to update the consensus rules, if we needed to make backwards-incompatible +changes. Shortly after `zcashd v4.5.0` was released, during another internal +review of the Orchard circuit, we identified two bugs that would affect the +upcoming testnet activation of NU5: + +- The diversifier base `g_d_old`, for the note being spent, is required to be a + non-identity point. A note created from a payment address with `g_d` set to + the identity (via collaboration between sender and recipient) could be spent + multiple times with different nullifiers (corresponding to different `ivk`s). + The code outside the circuit correctly enforced the non-identity requirement, + but the circuit did not correctly constrain this, and allowed the prover to + witness the identity. + +- SinsemillaCommit can be modeled as a Pedersen commitment to an output of + SinsemillaHash: `SinsemillaCommit(r, M) = SinsemillaHashToPoint(M) + [r] R`. + The specification used incomplete addition here, matching its use inside + SinsemillaHash. However, unlike in SinsemillaHash, an exceptional case can be + produced here when `r = 0`. The derivations of `rivk` (for computing `ivk`) + and `rcm` (for computing the note commitment) normally ensure that `r = 0` + can only occur with negligible probability, but these derivations are not + checked by the circuit for efficiency; thus SinsemillaCommit needs to use + complete addition. + +These bugs do not affect mainnet, as `zcashd v4.5.0` only set the activation +height for NU5 on testnet for testing purposes. Nevertheless, in the interest of +keeping the testnet environment as close to mainnet as possible, we are fixing +these bugs immediately. This means a change to the NU5 consensus rules, and a +new testnet activation height for NU5. + +To this end, the following changes are made in `zcashd v4.5.1`: + +- The consensus branch ID for NU5 is changed to `0x37519621`. +- The protocol version indicating NU5-aware testnet nodes is set to `170015`. +- The testnet activation height for NU5 is set to **1,599,200**. + +Testnet nodes that upgrade to `zcashd v4.5.1` prior to block height 1,590,000 +will follow the new testnet network upgrade. Testnet nodes that are running +`zcashd v4.5.0` at that height will need to upgrade to `v4.5.1` and then run +with `-reindex`. + +As always, it is possible that further backwards-incompatible changes might be +made to the NU5 consensus rules in this testing phase, prior to setting the +mainnet activation height, as we continue to conduct additional internal review. +In the event that this happens, testnet will be rolled back in (or prior to) +v5.0.0, and a new testnet activation will occur. + +Fixed regression in `getbalance` RPC method +------------------------------------------- + +`zcashd v4.5.0` removed the account API from the wallet, following its +deprecation and removal in upstream Bitcoin Core. As part of the upstream +changes, the `getbalance` RPC method was altered from using two custom balance +computation methods, to instead relying on `CWallet::GetBalance`. This method +internally relies on `CWalletTx::IsFromMe` as part of identifying "trusted" +zero-confirmation transactions to include in the balance calculation. + +There is an equivalent and closely-named `CWallet::IsFromMe` method, which is +used throughout the wallet, and had been updated before Zcash launched to be +aware of spent shielded notes. The change to `getbalance` exposed a bug: +`CWalletTx::IsFromMe` had not been similarly updated, which caused `getbalance` +to ignore wallet-internal (sent between two addresses in the node's wallet) +unshielding transactions with zero confirmations. This release fixes the bug. + +Changelog +========= + +Jack Grigg (5): + wallet: Check spent shielded notes in CWalletTx::IsFromMe + Fix bugs in testnet Orchard circuit + depends: Postpone native_ccache 4.4.2 + make-release.py: Versioning changes for 4.5.1. + make-release.py: Updated manpages for 4.5.1. + diff --git a/depend/zcash/doc/release-notes/release-notes-4.6.0-1.md b/depend/zcash/doc/release-notes/release-notes-4.6.0-1.md new file mode 100644 index 000000000..975376aa1 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.6.0-1.md @@ -0,0 +1,37 @@ +`getblocktemplate` regression fix +================================= + +We added support for the NU5 consensus rules in v4.5.0, which alters the +block header to contain a `hashBlockCommitments` value instead of the +chain history root. However, the output of `getblocktemplate` wasn't +returning this value; once NU5 activated, the `blockcommitmentshash` +field was being set to "null" (all-zeroes). + +In v4.6.0 we added full NU5 support to `getblocktemplate`, by adding a +`defaultroots` field that gave default values for `hashBlockCommitments` +and the components required to derive it. However, in doing so we +introduced a regression in the (now-deprecated) legacy fields, where +prior to NU5 activation they contained nonsense. + +This release fixes the output of `getblocktemplate` to have the intended +semantics for all fields: + +- The `blockcommitmentshash` and `authdataroot` fields in `defaultroots` + are now omitted from block templates for heights before NU5 activation. + +- The legacy fields now always contain the default value to be placed + into the block header (regaining their previous semantics). + +Changelog +========= + +Jack Grigg (3): + rpc: Fix regression in getblocktemplate output + make-release.py: Versioning changes for 4.6.0-1. + make-release.py: Updated manpages for 4.6.0-1. + +Larry Ruane (3): + assert that the return value of submitblock is None + test: check getblocktemplate output before and after NU5 + test: Fix ZIP 244 implementation + diff --git a/depend/zcash/doc/release-notes/release-notes-4.6.0-2.md b/depend/zcash/doc/release-notes/release-notes-4.6.0-2.md new file mode 100644 index 000000000..ae6f649f5 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.6.0-2.md @@ -0,0 +1,47 @@ +This is a bugfix release that also bumps the End-of-Support height to May 16th. +It backports bugfixes from v4.7.0-rc1, including a `getblocktemplate` deadlock +fix, and several portability fixes. + +Debian 9 "Stretch" is no longer supported from v4.6.0-2, due to its +[end-of-life](https://wiki.debian.org/LTS/Stretch) on June 30th, 2022. This will +allow us to direct more resources to supporting Debian 11 Bullseye, other Linux +distributions, and other platforms such as Windows and macOS. + +Changelog +========= + +Charlie O'Keefe (2): + Update base image used by Dockerfile from debian 10 to debian 11 + Remove stretch (debian 9), add bullseye (debian 11) in gitian descriptor + +Daira Hopwood (4): + Avoid a warning by explicitly calling drop. + Replace call to drop with zeroization. + qa/zcash/updatecheck.py: print status code and response of failed http requests. + Postpone native_clang and libcxx 14.0.0. + +Jack Grigg (9): + qa: Bump all postponed dependencies + qa: Postpone recent CCache release + depends: Update Rust to 1.59.0 + depends: Update Clang / libcxx to LLVM 13.0.1 + rust: Fix clippy lint + depends: Revert to `libc++ 13.0.0-3` for Windows cross-compile + qa: Exclude `native_libtinfo` from dependency update checks + make-release.py: Versioning changes for 4.6.0-2. + make-release.py: Updated manpages for 4.6.0-2. + +Larry Ruane (1): + document global variables + +Pieter Wuille (2): + Fix csBestBlock/cvBlockChange waiting in rpc/mining + Modernize best block mutex/cv/hash variable naming + +Taylor Hornby (1): + Untested, not working yet, use libtinfo from the debian packages + +sasha (2): + on Arch only, use Debian's libtinfo5_6.0 to satisfy clang + remove superfluous space at end of native_packages line + diff --git a/depend/zcash/doc/release-notes/release-notes-4.6.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.6.0-rc1.md new file mode 100644 index 000000000..1bfd543d0 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.6.0-rc1.md @@ -0,0 +1,111 @@ +Notable changes +=============== + +Wallet +------ + +From this release, newly-created wallets will save the chain name ("Zcash") and +network identifier (e.g. "main") to the `wallet.dat` file. This will enable the +`zcashd` node to check on subsequent starts that the `wallet.dat` file matches +the node's configuration. Existing wallets will start saving this information in +a later release. + +`libzcash_script` +----------------- + +Two new APIs have been added to this library (`zcash_script_legacy_sigop_count` +and `zcash_script_legacy_sigop_count_precomputed`), for counting the number of +signature operations in the transparent inputs and outputs of a transaction. +The presence of these APIs is indicated by a library API version of 2. + +Updated RPCs +------------ + +- Fixed an issue where `ERROR: spent index not enabled` would be logged + unnecessarily on nodes that have either insightexplorer or lightwalletd + configuration options enabled. + +- The `getmininginfo` RPC now omits `currentblockize` and `currentblocktx` + when a block was never assembled via RPC on this node during its current + process instantiation. (#5404) + +Changelog +========= + +Alex Wied (1): + Update support for FreeBSD + +Charlie O'Keefe (1): + Add buster to the list of suites used by gitian + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (22): + contrib: Update Debian copyright file to follow the v1 format + contrib: Add license information for libc++ and libevent + cargo update + tracing-subscriber 0.3 + Bump all postponed dependencies + depends: Update Rust to 1.56.1 + depends: Update Clang / libcxx to LLVM 13 + rust: Move `incremental_sinsemilla_tree_ffi` into crate root + CI: Add Pyflakes to lints workflow + cargo update + ed25519-zebra 3 + cargo update + cargo update + depends: Update Boost to 1.78.0 + depends Update Rust to 1.57.0 + qa: Postpone recent CCache releases + Revert "lint: Fix false positive" + rust: Remove misleading log message + Migrate to latest revisions of Zcash Rust crates + Update release notes + make-release.py: Versioning changes for 4.6.0-rc1. + make-release.py: Updated manpages for 4.6.0-rc1. + +Janito Vaqueiro Ferreira Filho (1): + Move `CurrentTxVersionInfo` into a new file + +Kris Nuttycombe (7): + Add BIP 44 coin type to persisted wallet state. + Persist network id string instead of bip44 coin type. + Add a check to test that wallet load fails if we're on the wrong network. + Remove unused `AddDestData` method. + Fix wallet-related wording in doc/reduce-traffic.md + Rename OrchardMerkleTree -> OrchardMerkleFrontier + Batch-verify Orchard transactions at the block level. + +Larry Ruane (6): + add TestSetIBD(bool) for testing + Disable IBD for all boost tests + better wallet network info error handling + test: automatically add missing nuparams + Don't log 'ERROR: spent index not enabled' + getblocktemplate: add NU5 commitments to new `defaultroots` section + +Marco Falke (1): + [rpc] mining: Omit uninitialized currentblockweight, currentblocktx + +Marshall Gaucher (1): + Update entrypoint.sh + +Sasha (1): + fix typo in docker run's volume argument + +sgmoore (1): + Update reduce-traffic.md - add one word + +Jack Grigg (1): + contrib: Add space between URL and period + +teor (7): + Add sigop count functions to zcash_script library + Increment the zcash_script API version + Remove an unused header + Use correct copyright header + Remove redundant variable + Explain UINT_MAX error return value + Explain how to get rid of a tiny duplicated function + diff --git a/depend/zcash/doc/release-notes/release-notes-4.6.0.md b/depend/zcash/doc/release-notes/release-notes-4.6.0.md new file mode 100644 index 000000000..26e1f3652 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.6.0.md @@ -0,0 +1,126 @@ +Notable changes +=============== + +Wallet +------ + +From this release, newly-created wallets will save the chain name ("Zcash") and +network identifier (e.g. "main") to the `wallet.dat` file. This will enable the +`zcashd` node to check on subsequent starts that the `wallet.dat` file matches +the node's configuration. Existing wallets will start saving this information in +a later release. + +`libzcash_script` +----------------- + +Two new APIs have been added to this library (`zcash_script_legacy_sigop_count` +and `zcash_script_legacy_sigop_count_precomputed`), for counting the number of +signature operations in the transparent inputs and outputs of a transaction. +The presence of these APIs is indicated by a library API version of 2. + +Updated RPCs +------------ + +- The `getblocktemplate` RPC method output now includes a `defaultroots` field, + which provides various tree roots and block commitments matching the contents + of the block template. If any part of the block template marked as `mutable` + in the RPC method output is mutated, these roots may need to be recomputed. + For more information on the derivation process, see the block header changes + in [ZIP 244](https://zips.z.cash/zip-0244#block-header-changes). + +- Fixed an issue where `ERROR: spent index not enabled` would be logged + unnecessarily on nodes that have either `-insightexplorer` or `-lightwalletd` + configuration options enabled. + +- The `getmininginfo` RPC now omits `currentblocksize` and `currentblocktx` + when a block was never assembled via RPC on this node during its current + process instantiation. (#5404) + +Changelog +========= + +Alex Wied (1): + Update support for FreeBSD + +Charlie O'Keefe (2): + Add buster to the list of suites used by gitian + Add libtinfo5 to gitian packages list + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (23): + contrib: Update Debian copyright file to follow the v1 format + contrib: Add license information for libc++ and libevent + cargo update + tracing-subscriber 0.3 + Bump all postponed dependencies + depends: Update Rust to 1.56.1 + depends: Update Clang / libcxx to LLVM 13 + rust: Move `incremental_sinsemilla_tree_ffi` into crate root + CI: Add Pyflakes to lints workflow + cargo update + ed25519-zebra 3 + cargo update + cargo update + depends: Update Boost to 1.78.0 + depends Update Rust to 1.57.0 + qa: Postpone recent CCache releases + Revert "lint: Fix false positive" + rust: Remove misleading log message + Migrate to latest revisions of Zcash Rust crates + Update release notes + make-release.py: Versioning changes for 4.6.0-rc1. + make-release.py: Updated manpages for 4.6.0-rc1. + make-release.py: Updated release notes and changelog for 4.6.0-rc1. + +Janito Vaqueiro Ferreira Filho (1): + Move `CurrentTxVersionInfo` into a new file + +Kris Nuttycombe (7): + Add BIP 44 coin type to persisted wallet state. + Persist network id string instead of bip44 coin type. + Add a check to test that wallet load fails if we're on the wrong network. + Remove unused `AddDestData` method. + Fix wallet-related wording in doc/reduce-traffic.md + Rename OrchardMerkleTree -> OrchardMerkleFrontier + Batch-verify Orchard transactions at the block level. + +Larry Ruane (8): + add TestSetIBD(bool) for testing + Disable IBD for all boost tests + better wallet network info error handling + test: automatically add missing nuparams + Don't log 'ERROR: spent index not enabled' + getblocktemplate: add NU5 commitments to new `defaultroots` section + test: fix bugs in test framework + test: Use result of getblocktemplate to submitblock + +Marco Falke (1): + [rpc] mining: Omit uninitialized currentblockweight, currentblocktx + +Marshall Gaucher (1): + Update entrypoint.sh + +Sasha (5): + fix typo in docker run's volume argument + update hash for librustzcash + only librustzcash in config.offline + make-release.py: Versioning changes for 4.6.0. + make-release.py: Updated manpages for 4.6.0. + +sgmoore (1): + Update reduce-traffic.md - add one word + +Jack Grigg (1): + contrib: Add space between URL and period + +teor (7): + Add sigop count functions to zcash_script library + Increment the zcash_script API version + Remove an unused header + Use correct copyright header + Remove redundant variable + Explain UINT_MAX error return value + Explain how to get rid of a tiny duplicated function + diff --git a/depend/zcash/doc/release-notes/release-notes-4.7.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-4.7.0-rc1.md new file mode 100644 index 000000000..d428fa1d1 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.7.0-rc1.md @@ -0,0 +1,538 @@ +Notable changes +=============== + +Mnemonic Recovery Phrases +------------------------- + +The zcashd wallet has been modified to support BIP 39, which describes how to +derive the wallet's HD seed from a mnemonic phrase. The mnemonic phrase will +be generated on load of the wallet, or the first time the wallet is unlocked, +and is available via the `z_exportwallet` RPC call. All new addresses produced +by the wallet are now derived from this seed using the HD wallet functionality +described in ZIP 32 and ZIP 316. For users upgrading an existing Zcashd wallet, +it is recommended that the wallet be backed up prior to upgrading to the 4.7.0 +Zcashd release. + +Following the upgrade to 4.7.0, Zcashd will require that the user confirm that +they have backed up their new emergency recovery phrase, which may be obtained +from the output of the `z_exportwallet` RPC call. This confirmation can be +performed manually using the `zcashd-wallet-tool` utility that is supplied +with this release (built or installed in the same directory as `zcashd`). +The wallet will not allow the generation of new addresses until this +confirmation has been performed. It is recommended that after this upgrade, +that funds tied to preexisting addresses be migrated to newly generated +addresses so that all wallet funds are recoverable using the emergency +recovery phrase going forward. If you choose not to migrate funds in this +fashion, you will continue to need to securely back up the entire `wallet.dat` +file to ensure that you do not lose access to existing funds; EXISTING FUNDS +WILL NOT BE RECOVERABLE USING THE EMERGENCY RECOVERY PHRASE UNLESS THEY HAVE +BEEN MOVED TO A NEWLY GENERATED ADDRESS FOLLOWING THE 4.7.0 UPGRADE. + +New RPC Methods +--------------- + +- 'walletconfirmbackup' This newly created API checks a provided emergency + recovery phrase against the wallet's emergency recovery phrase; if the phrases + match then it updates the wallet state to allow the generation of new addresses. + This backup confirmation workflow can be disabled by starting zcashd with + `-requirewalletbackup=false` but this is not recommended unless you know what + you're doing (and have otherwise backed up the wallet's recovery phrase anyway). + For security reasons, this RPC method is not intended for use via zcash-cli + but is provided to enable `zcashd-wallet-tool` and other third-party wallet + interfaces to satisfy the backup confirmation requirement. Use of the + `walletconfirmbackup` API via zcash-cli would risk that the recovery phrase + being confirmed might be leaked via the user's shell history or the system + process table; `zcashd-wallet-tool` is specifically provided to avoid this + problem. +- 'z_getbalanceforviewingkey' This newly created API allows a user to obtain + balance information for funds visible to a Sapling or Unified full + viewing key; if a Sprout viewing key is provided, this method allows + retrieval of the balance only in the case that the wallet controls the + corresponding spending key. + +RPC Changes +----------- + +- The results of the 'dumpwallet' and 'z_exportwallet' RPC methods have been modified + to now include the wallet's newly generated emergency recovery phrase as part of the + exported data. + +- The results of the 'getwalletinfo' RPC have been modified to return two new fields: + `mnemonic_seedfp` and `legacy_seedfp`, the latter of which replaces the field that + was previously named `seedfp`. + +Wallet +------ + +'z_sendmany' +------------ + +- The 'z_sendmany' RPC call no longer permits Sprout recipients in the + list of recipient addresses. Transactions spending Sprout funds will + still result in change being sent back into the Sprout pool, but no + other `Sprout->Sprout` transactions will be constructed by the Zcashd + wallet. + +- The restriction that prohibited `Sprout->Sapling` transactions has been + lifted; however, since such transactions reveal the amount crossing + pool boundaries, they must be explicitly enabled via a parameter to + the 'z_sendmany' call. + +- A new string parameter, `privacyPolicy`, has been added to the list of + arguments accepted by `z_sendmany`. This parameter enables the caller to + control what kind of information they permit `zcashd` to reveal when creating + the transaction. If the transaction can only be created by revealing more + information than the given strategy permits, `z_sendmany` will return an + error. The parameter defaults to `LegacyCompat`, which applies the most + restrictive strategy `FullPrivacy` when a Unified Address is present as the + sender or a recipient, and otherwise preserves existing behaviour (which + corresponds to the `AllowFullyTransparent` policy). + +- Since Sprout outputs are no longer created (with the exception of change) + 'z_sendmany' no longer generates payment disclosures (which were only + available for Sprout outputs) when the `-paymentdisclosure` experimental + feature flag is set. + +Changelog +========= + +Charlie O'Keefe (2): + Update base image used by Dockerfile from debian 10 to debian 11 + Remove stretch (debian 9), add bullseye (debian 11) in gitian descriptor + +Conrado Gouvea (1): + Add comment to zcash_script_new_precomputed_tx about references to input buffers + +Daira Hopwood (25): + Avoid a warning by explicitly calling drop. + Replace call to drop with zeroization. + contrib/devtools/rust-deps-graph.sh: allow overriding the arguments to `cargo deps`. + Cosmetic whitespace change + Make a zcashd-wallet-tool executable. + Attempt to fix linking problem on ARM. + Add some text about choosing location of the physical backup. Add TODO for better handling of file not found and permission errors. + Move `wallet_tool.rs` from `src/rust/src` into `src/rust/bin`. Also add a brief description of `zcashd-wallet-tool` to `src/rust/README.md`. + Improved error handling. + The recovery phrase confirmation and `zcashd-wallet-tool` are being introduced in zcashd v4.7.0. + Refactor use of `export_path` as suggested. + Tweak the wording of the fallback messages when the terminal cannot be automatically cleared. + Simplify extraction of recovery phrase. + Improve memory hygiene, and use -stdin to pass the recovery phrase to the child zcash-cli process. + Cleanups to error handling for the first invocation of zcash-cli. + Use the tracing crate for debugging. + Improve error message when the config file cannot be found, taking into account -conf and -datadir. + Ensure the buffer used in `prompt` is zeroized even on error. + Document that '~' cannot be used in `-datadir` (see #5661). + Set `meta` for `-datadir` option. + Simplify debug tracing. + Correct the fallback instruction for how to clear the terminal on macOS: pressing Command + K also clears scrollback. + Include $(bin_SCRIPTS) in `check-symbols`, `check-security`, and `clean` targets. Checking for stack canaries in `check-security` is disabled for Rust executables (Rust does support `-Z stack-protector=all` but only for the nightly compiler). + qa/zcash/full_test_suite.py: enable `test_rpath_runpath` for Rust binaries, and reenable `test_fortify_source` for C++ binaries. + Tweaks to message text. + +Dimitris Apostolou (1): + Fix typos + +Jack Grigg (65): + wallet: Implement `z_getnewaccount` + wallet: Implement `z_getaddressforaccount` + wallet: Implement `z_listunifiedreceivers` + wallet: Show UAs owned by the wallet in `z_viewtransaction` + wallet: Reverse order of arguments to z_getaddressforaccount + rust: Add missing Orchard receiver check in UA parsing + rust: Add missing checks for shielded UFVK items + rust: Add missing checks for transparent UFVK items + wallet: Implement `z_getbalanceforaccount` + wallet: Fix account generation bug + wallet: Implement `z_getbalanceforaddress` + wallet: Don't show Sapling receivers from UAs in `z_listaddresses` + wallet: Show UAs instead of Sapling receivers in `z_listunspent` + wallet: Remove `CWallet::GetKeyFromPool` + wallet: Store internal transparent keys in the keypool + wallet: Separate counters for external and internal transparent keys + Add Orchard recipient support to the transaction builder + Make `TransactionBuilder::AddOrchardOutput` memo optional + Return UFVK from `CWallet::GenerateNewUnifiedSpendingKey` + Rename to `ZcashdUnifiedSpendingKey::GetSaplingKey` for consistency + Trial-decrypt candidate Sapling receivers with all wallet UFVKs + Add mappings from Orchard receivers to IVKs to the wallet + Add Orchard to default UA receiver types + Fix semantic merge conflicts + Select Orchard receivers preferentially from UAs + Regenerate `TxDigests` after rebuilding tx with Orchard bundle + qa: Bump all postponed dependencies + qa: Postpone recent CCache release + depends: Update Rust to 1.59.0 + depends: Update Clang / libcxx to LLVM 13.0.1 + cargo update + rust: Fix clippy lint + Ensure the view's best Orchard anchor matches the previous block + Add missing `view.PopAnchor(_, ORCHARD)` in `DisconnectBlock` + Add RPC test for the Orchard commitment tree bug on first NU5 testnet + Use `std::optional` in `CValidationInterface::GetAddressForMining` + Select Orchard receivers from UA miner addresses once NU5 activates + miner: Manually add dummy Orchard output with Orchard miner address + rpc: Handle keypool exhaustion separately in `generate` RPC + depends: Revert to `libc++ 13.0.0-3` for Windows cross-compile + Add Orchard spend support to the transaction builder + wallet: Alter `OrchardWallet::GetSpendInfo` to return the spending key + Improve FFI interface documentation + Refactor `CWallet::GenerateChangeAddressForAccount` + Add unit tests for `SpendableInputs::LimitToAmount` + Fix bug in `SpendableInputs::LimitToAmount` + Select spendable inputs based on recipient and change pool types + Implement opportunistic shielding in `SpendableInputs::LimitToAmount` + Add Orchard cases to note selection logic + Add Orchard to change address generation + Add support for sending Orchard funds in `z_sendmany` + Set default Orchard anchor confirmations to 1 + build: Fix `zcash/address/orchard.hpp` filename in `src/Makefile.am` + z_sendmany: Replace `allowRevealedAmount` with `privacyStrategy` + z_sendmany: Expand `privacyPolicy` cases + build: Add missing `util/match.h` to `src/Makefile.am` + wallet: Add seedfp to transparent keys in dumpwallet / z_exportwallet + Fix bugs in wallet_addresses RPC test + wallet: Fix bugs in `listaddresses` + wallet: Fix Sapling address bug in `listaddresses` + wallet: Fix expected `listaddresses` sources in `rpc_wallet_tests` + qa: Exclude `native_libtinfo` from dependency update checks + cargo update + make-release.py: Versioning changes for 4.7.0-rc1. + make-release.py: Updated manpages for 4.7.0-rc1. + +John Newbery (1): + Log calls to getblocktemplate + +Jonas Schnelli (1): + [Wallet] add HD xpriv to dumpwallet + +Kris Nuttycombe (243): + Derive random HD seeds from ZIP-339 seed phrases. + Add support for externally searching for valid Sapling diversifiers. + Adds basic unified spending key derivation. + Add unified full viewing keys and Zcash-internal unified addresses. + Use the default UA-based Sapling address for the saplingmigration tool. + Fix tests for wallet operations on legacy Sapling keys. + Remove unused forward declaration. + Update librustzcash dependency version. + Apply suggestions from code review + Derive transparent keys from mnemonic seed. + Generate legacy Sapling addresses from the mnemonic seed. + Replace account ID with ZIP-0032 key path in listaddresses output. + Use legacy address for Sapling migration until UA functionality is available to the RPC tests. + Revert change to the type of GenerateNewKey + Fix wallet import/export test + Use 0x7FFFFFFF for the legacy account ID. + Require backup of the emergency recovery phrase. + Use hardened derivation for the legacy Sapling key at the address index level. + Address comments from code review. + Restore legacy HD seed storage & retrieval tests. + Fix spurious test passage. + Move CKeyMetadata back to wallet.h + Clean up format of recovery information in the wallet dump. + Use SecureString for mnemonic phrase. + Apply suggestions from code review + Fix diversifier_index_t less than operator. + Restore FindAddress comment + Fix transparent BIP-44 keypaths. + Fix naming of unified spending & full viewing keys + Fix max transparent diversifier index. + Clean up handling of mnemonic seed metadata. + Restore legacy HDSeed encryption tests. + Style fix in BIP 32 path account parsing test. + Do not strip quotes when verifying mnemonic seed. + Apply suggestions from code review + Fix name of menmonic entropy length constant. + Fix polymorphism of string serialization. + Document mnemonic-seed-related RPC method changes & update changelog. + Minor cleanup of the code that searches for a valid transparent key. + Generalize keypath parsing over account id. + Update documentation for GenerateNewSeed. + Use MnemonicSeed instead of HDSeed where appropriate. + Add diversifier_index_t::ToTransparentChildIndex + Only maintain CKeyID for the transparent part of ZcashdUnifiedAddress + Minor naming fixes + Parameterize HD keypath parsing by coin type. + Fix error message text to refer to zcashd-wallet-tool rather than the RPC method. + Apply suggestions from code review + Minor textual fixes to release notes. + Improve documentation of the `-walletrequirebackup` zcashd wallet configuration option. + Add libzcash::AccountId type. + Adds Orchard Address, IncomingViewingKey, FullViewingKey, and SpendingKey types. + Apply suggestions from code review + Update orchard & librustzcash dependency versions. + Remove incorrect FFI method documentation. + Remove Orchard spending key equality implementation. + Refine structure of Zcash address generation. + Use CKeyID and CScriptID instead of new P2PKH/P2SHAddress classes. + Remove ZcashdUnifiedAddress in favor of UnifiedAddress + Update to ufvk zcash_address build. + Adds SaplingDiversifiableFullViewingKey + Add Rust FFI components for unified full viewing keys. + Add UnifiedFullViewingKey type. + Apply suggestions from code review + Add tests for ufvk roundtrip serialization. + Apply suggestions from code review + Apply suggestions from code review + Apply suggestions from code review + Add functions for generating BIP-44 and ZIP-32 keypaths + Check the output of zip339_phrase_to_seed in MnemonicSeed initialization. + Compute key id for UFVKs. + Add ZcashdUnifiedKeyMetadata and libzcash::ReceiverType + Add unified key components to the transparent & Sapling wallet parts. + Store ufvks to the wallet database. + Add unified address tracking to KeyStore + Load unified full viewing keys from the walletdb. + Add key metadata to walletdb. + Add unified address generation. + AddTransparentSecretKey does not need to take a CExtKey + Add newly generated transparent UA receivers to the wallet. + Add CWallet::GetUnifiedForReceiver + Add tests for keystore storage and retrieval of UFVKs. + Add test for wallet UA generation & detection. + Add test for CKeyStore::AddUnifiedAddress + Fix handling of unified full viewing key metadata. + Apply suggestions from code review + Only derive ZcashdUnifiedFullViewingKey from UnifiedFullViewingKey + Rename `ZcashdUnifiedSpendingKeyMetadata` -> `ZcashdUnifiedAccount` + Remove unused ufvkid argument from AddTransparentSecretKey + Ensure that unified address metadata is always correctly populated. + Apply suggestions from code review + Make `FindAddress` correctly check for maximum transparent child index. + Use Bip44TransparentAccountKeyPath() for Bip44AccountChains keypath construction. + Improve documentation of UFVK/UA metadata storage semantics. + Apply suggestions from code review + Fix encoding order of unified addresses. + Remove the `InvalidEncoding` type from key & address variants. + Use CKeyID and CScriptID instead of new P2PKH/P2SHAddress classes. + Remove spurious uses of HaveSpendingKeyForPaymentAddress + Add raw transparent address types to PaymentAddress + Remove spurious variant from asyncrpcoperation_sendmany + Remove `RawAddress` + Replace `DecodeDestination` in `GetMinerAddress` with `DecodePaymentAddress` + Remove uses of KeyIO::DecodeDestination + Remove a use of KeyIO::DecodeDestination in z_shieldcoinbase + Use libzcash::PaymentAddress instead of std::string in mergetoaddress + Improve error messages in the case of taddr decoding failure. + Apply suggestions from code review + Apply suggestions from code review + Use transaction builder for asyncrpcoperation_sendmany. + Transaction builder must not set consensus branch ID for V4 transactions. + Fix conditions around dust thresholds. + Require an explicit flag to allow cross-pool transfers in z_sendmany. + Apply suggestions from code review + Return z_sendmany errors synchronously when possible. + Update release notes to reflect z_sendmany changes + Move FindSpendableInputs to CWallet + Replace the badly-named `PaymentSource` with `ZTXOSelector` + Add support for unified addresses to CWallet::ToZTXOSelector + Replace `HaveSpendingKeyForAddress` with checks at ZTXOSelector construction. + Modify CWallet::FindSpendableInputs to use ZTXOSelector + Add CWallet::FindAccountForSelector + Add RecipientAddress type. + Use libzcash::RecipientAddress for z_sendmany recipients. + Apply suggestions from code review + Rename ZTXOSelector::SpendingKeysAvailable -> RequireSpendingKeys + Make `FindSpendableInputs` respect `ZTXOSelector::RequireSpendingKeys()` + Clarify documentation of CWallet::FindAccountForSelector + Use `ZTXOSelector::IncludesSapling` rather than selector internals. + Add documentation for `UnifiedAddress::GetPreferredRecipientAddress` + Add correct selection of change addresses to z_sendmany + Add a first-class type for transparent full viewing keys. + Implement OVK selection for z_sendmany. + Implement derivation of the internal Sapling spending key. + Use a BIP 44 change address for change when sending from legacy t-addrs. + Add a check for internal vs. external outputs to wallet_listreceived test. + Fix z_sendmany handling of transparent OVK derivation in the ANY_TADDR case. + Simplify determination of valid change types. + Add failing tests for z_sendmany ANY_TADDR -> UA and UA -> + Add gtest for change address derivation. + Fix variable shadowing in change address derivation & add change IVK to the keystore. + GenerateLegacySaplingZKey only needs to return an address, not an extfvk. + Rename AddSaplingIncomingViewingKey -> AddSaplingPaymentAddress + Do not add Sapling addresses to the wallet by default when adding extfvks. + Fix a bug in the generation of addresses from UFVKs + Add accessor method for Sapling IVKs to SaplingDiversifiableFullViewingKey + Address TODOs in rpc-tests/wallet-accounts.py + Add a few additional cases to z_sendmany RPC tests. + Update librustzcash dependency. + Fix nondeterministic test error (checking for the wrong error case). + Use z_shieldcoinbase for Sprout funds in wallet_listreceived tests. + Apply suggestions from code review + Apply suggestions from code review. + Fix nondeterministic test failure in wallet_listreceivedby.py + Fix locking in z_getbalanceforaddress and z_getbalanceforaccount + Replace z_getbalanceforaddress with z_getbalanceforviewingkey + Clarify documentation of z_getbalanceforviewingkey for Sprout viewing keys. + Implement PaymentAddressBelongsToWallet for unified addresses. + Add unified address support to GetSourceForPaymentAddress + Address comments from review. + Add change field to z_listreceivedbyaddress for transparent addrs. + Fix missing std::variant header that was breaking Darwin builds. + Add test vectors for UFVK derivation + Rename sapling-specific zip32 FFI methods. + Make SaveRecipientMappings polymorphic in RecipientMapping type. + Add Rust backend for Orchard components of the wallet. + Add GetFilteredNotes to Orchard wallet. + Add test for Orchard wallet note detection. + Move parsing of unified addresses to UnifiedAddress. + Remove txid field from TxNotes + Apply suggestions from code review + Add various bits of documentation + Add Orchard components to unified address + Add Orchard components to unified full viewing keys + Add Orchard components to unified spending keys + Remove OrchardSpendingKey serialization code + Select Orchard notes in FindSpendableInputs + GenerateNewKey must be guarded by a cs_wallet lock + Filter returned Orchard notes by minimum confirmations. + Log outpoint for failed Sapling witness lookup. + Add a roundtrip test for Orchard merkle frontier serialization from the C++ side. + Add test for Orchard contribution to z_gettotalbalance + Respect minDepth argument for Orchard notes in GetFilteredNotes + Update MSRV for lints. + Update incrementalmerkletree version + Split LoadWalletTx from AddToWallet + Fix missing locks for GenerateNewUnifiedSpendingKey tests. + Record when notes are detected as being spent in the Orchard wallet. + Reset Orchard wallet state when rescanning from below NU5 activation. + Check wallet latest anchor against hashFinalOrchardRoot in ChainTip. + Remove assertions that require Orchard wallet persistence to satisfy. + Add a test for Orchard note detection. + Assert we never attempt to checkpoint the Orchard wallet at a negative block height. + Apply suggestions from code review + Add an `InPoint` type to the Orchard wallet to fix incorrect conflict data. + Apply suggestions from code review + Fix missing update to `last_checkpoint` on rewind. + Track mined-ness instead of spent-ness of notes in the Orchard wallet. + Apply suggestions from code review + Respect maxDepth for Orchard notes in GetFilteredNotes + Set number of confirmations for Orchard notes returned by FindSpendableInputs + Update walletTx with decrypted Orchard action metadata. + Persist Orchard action index/IVK mappings in CWalletTx + Restore decrypted notes to the wallet. + Update tests with rollback checks. + Apply suggestions from code review + Restore mined block heights when restoring decrypted notes. + Apply suggestions from code review + Return std::optional from CExtKey::Master + Ensure that Orchard spentness information is repopulated by LoadUnifiedCaches. + Modify `join_network` in tests to skip mempool resync. + Address suggestions from code review on #5637 + Apply suggestions from code review + Serialize the Orchard note commitment tree to the wallet. + Update orchard_wallet_add_notes_from_bundle documentation. + Derive the new mnemonic seed from the legacy HD seed, if one is available. + Fix indentation. + Apply suggestions from code review + Explicitly specify the change address in the Sapling migration. + Add TODO for Orchard z_listunspent integration. + Document that z_getnewaccount and z_getaddressforaccount replace z_getnewaddress. + Add orchard support to z_getnotescount + Document that Orchard keys are not supported in z_importkey help + Return the correct error for `z_getbalance` if a UA does not correspond to an account in the wallet.. + Update documentation of z_importviewingkey and z_exportviewingkey to address unified keys. + Add UnifiedAddress variant to ZTXOSelector + Eliminate redundancy between the wallet and the keystore. + Simplify retrieval of unified account by address. + Add OrchardWallet::GetTxActions + Apply suggestions from code review + Update z_viewtransaction documentation to correctly represent field names. + Add debug printing for receivers and recipient addresses. + Correctly report change outputs in z_viewtransaction. + Return the default unified address if we have the UFVK but no address metadata. + Fix missing AllowRevealedSenders flag in test. + Uncomment addtional tests that depend on z_viewtransaction. + Minor rename & documentation improvement. + Add RecipientType to GetPaymentAddressForRecipient result. + Make CWallet::DefaultReceiverTypes height-dependent. + Return failure rather than asserting on WriteRecipientMapping failure. + Lock cs_main for accesses to chainActive in GetPaymentAddressForRecipient. + Fix legacy address handling in CWallet::GetPaymentAddressForRecipient + Documentation fix for UnifiedAddressForReciever (+ spelling corrections.) + +Larry Ruane (12): + add ParseArbitraryInt() for diversifier index + add -orchardwallet experimental feature flag + Add new and modify existing Orchard RPCs, non-functional + mining: submitblock: log detailed equihash solution error + allow UA as z_shieldcoinbase destination + fix minconf parsing for z_getbalanceforaccount and z_getbalanceforaddress + Update z_listreceivedbyaddress to support unified addresses (5467) + fix wallet_listreceived.py, add blockdata to taddr output + z_listreceivedbyaddress: reject UA component addr (#5537) + add functional test + document global variables + update listaddresses RPC for UAs, Orchard + +Marius Kjærstad (1): + Update copyright year to 2022 + +Pieter Wuille (2): + Fix csBestBlock/cvBlockChange waiting in rpc/mining + Modernize best block mutex/cv/hash variable naming + +Sean Bowe (5): + wallet: consolidate unified key/address/account map reconstruction + wallet: restore Orchard secret keys from mnemonic seed + wallet: restore orchard address to IVK mappings during wallet loading + wallet: rather than assert, error in case of inconsistency between FVK and address + wallet: add logging for failure cases in unified cache loading + +Steven Smith (8): + Lock cs_main prior to calling blockToJSON + Mark z_gettotalbalance and dumpwallet as deprecated + Add Orchard support to the z_gettreestate RPC + Update transaction size estimation to include V5 transactions + Extend uniqueness check in z_sendmany to UA receivers + Load previously persisted sent transaction recipient metadata back into the wallet. + Add Orchard & unified address support to z_viewtransaction. + Ensure z_viewtransaction returns Orchard details + +Taylor Hornby (1): + Untested, not working yet, use libtinfo from the debian packages + +sasha (12): + on Arch only, use Debian's libtinfo5_6.0 to satisfy clang + explain the 0x0f0f[..]0f0f powLimit constant for regtest + remove superfluous space at end of native_packages line + gtests ordering: change wallet filename in WriteZkeyDirectToDb + gtests ordering: ContextualCheckBlockTest's TearDown deactivates Blossom + gtests ordering: CheckBlock.VersionTooLow calls SelectParams(MAIN) + implement AtomicTimer::zeroize() that resets start_time and total_time + gtests ordering: make Metrics.GetLocalSolPS idempotent + gtests ordering: clean up wallet files before each WalletZkeysTest + make librustzcash_init_zksnark_params idempotent + move proof parameter loading out of gtest/main.cpp and into utiltest.cpp + Call LoadProofParameters() in gtests that need proofs + +Ying Tong Lai (18): + Move SendManyRecipient to wallet.h and introduce optional ua field. + SendTransaction: Introduce recipients argument. + Implement read and write for (txid, recipient) -> ua mapping. + z_sendmany: Only get ua if decoded is ua variant. + ShieldToAddress: Factor out static shieldToAddress() helper. + Docfixes. + CSerializeRecipientAddress: add Read method and make constructor private. + WriteRecipientMapping: Check that receiver exists in UA. + wallet_sendmany_any_taddr.py: Test sending from a change taddr. + wallet_sendmany_any_taddr.py: Test sending output from expired tx. + FindSpendableInputs: Add nDepth < 0 check. + wallet_sendmany_any_taddr.py: Expect expired tx to be ignored. + Orchard: invalidate mempool transactions that use orphaned anchors. + coins_tests.cpp: Add Orchard nullifier to TxWithNullifiers(). + coins_tests: Update tests to include Orchard case. + CWallet::GetConflictS: Handle conflicting Orchard spends. + z_getbalance: Handle Unified Address case. + Adapt RPC tests to use z_getbalance for UAs. + +ying tong (2): + Apply docfixes from code review + Style improvements in RPC tests. + +Zancas Wilcox (4): + blake2b/s is integrated into hashlib, drop external python package dependency + update doctest in gtest suite to prefer hashlib + enforce usage of the get_tests comptool interface as ComparisonTestFramework method + All implementations of ComparisonTestFramework were overriding num_nodes + diff --git a/depend/zcash/doc/release-notes/release-notes-4.7.0.md b/depend/zcash/doc/release-notes/release-notes-4.7.0.md new file mode 100644 index 000000000..cd8da43c8 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-4.7.0.md @@ -0,0 +1,869 @@ +Notable changes +=============== + +Changes to Testnet NU5 Consensus Rules +-------------------------------------- + +NOTE: All testnet nodes that have been running on testnet above height 1,599,200 will need +to upgrade to `v4.7.0` and then run with `-reindex` and `-rescan`. + +- In order to better support hardware wallets, transparent signature hash construction as + defined in [ZIP 244](https://zips.z.cash/zip-0244) has been modified to include a hash + of the serialization of the amounts of all outputs being spent, along with a hash of all + spent outputs `scriptPubKeys` values, except in the case that the `ANYONECANPAY` flag is + set. This allows hardware wallet devices to verify the UTXO amounts without having to + stream all the previous transactions containing the outputs being spent to the device. + Also as part of these changes, the transparent signature hash digest now commits + directly, rather than implicitly, to the sighash type, and the sighash type is + restricted to a fixed set of valid values. The change to ZIP 244 can be seen + [here](https://github.com/zcash/zips/commit/ac9dd97f77869b9191dc9592faa3ebf45475c341). +- This release fixes a bug in `v4.6.0` that caused a consensus failure on the Zcash + testnet at height `1,779,200`. For details see + . +- There have been changes to the Halo2 proving system to improve consistency between the + specification and the implementation, and these may break compatibility. See for example + . +- There have been numerous changes to the Orchard circuit implementation since `v4.6.0`. + See + for a complete list. +- A potential Faerie Gold vulnerability affecting the previous activation of NU5 on + testnet and existing since `v4.6.0` has been mitigated. + +NU5 Testnet Reactivation +------------------------ + +To support the aforementioned testnet consensus changes, the following changes are made in +`zcashd v4.7.0`: + +- The consensus branch ID for NU5 is changed to `0xC2D6D0B4`. +- The protocol version indicating NU5-aware testnet nodes is set to `170050`. +- The testnet reactivation height for NU5 is set to **1,842,420**. + +As mentioned above, all testnet nodes that have been running on testnet above height +1,599,200 will need to upgrade to `v4.7.0` and then run with `-reindex` and `-rescan`. + +Emergency Recovery Phrases +-------------------------- + +The zcashd wallet has been modified to support BIP 39, which describes how to derive the +wallet's HD seed from a mnemonic phrase, hereafter known as the wallet's "emergency +recovery phrase". The emergency recovery phrase will be generated on load of the wallet, +or the first time the wallet is unlocked, and is available via the `z_exportwallet` RPC +call. All new addresses produced by the wallet are now derived from this seed using the HD +wallet functionality described in ZIP 32 and ZIP 316. For users upgrading an existing +Zcashd wallet, it is recommended that the wallet be backed up prior to upgrading to the +4.7.0 Zcashd release. In the remainder of this document, the HD seed derived from the +emergency recovery phrase will be termed the wallet's "mnemonic seed". + +Following the upgrade to 4.7.0, Zcashd will require that the user confirm that they have +backed up their new emergency recovery phrase, which may be obtained from the output of +the `z_exportwallet` RPC call. This confirmation can be performed manually using the +`zcashd-wallet-tool` utility that is supplied with this release (built or installed in the +same directory as `zcashd`). The wallet will not allow the generation of new addresses +until this confirmation has been performed. It is recommended that after this upgrade, +funds tied to preexisting addresses be migrated to newly generated addresses so that all +wallet funds are recoverable using the emergency recovery phrase going forward. If you +choose not to migrate funds in this fashion, you will continue to need to securely back up +the entire `wallet.dat` file to ensure that you do not lose access to existing funds; +EXISTING FUNDS WILL NOT BE RECOVERABLE USING THE EMERGENCY RECOVERY PHRASE UNLESS THEY +HAVE BEEN MOVED TO A NEWLY GENERATED ADDRESS FOLLOWING THE 4.7.0 UPGRADE. + +In the case that your wallet previously contained a Sapling HD seed, the emergency +recovery phrase is constructed using the bytes of that seed, such that it is possible to +reconstruct keys generated using that legacy seed if you know the emergency recovery +phrase. HOWEVER, THIS RECONSTRUCTION DOES NOT FOLLOW THE NORMAL PROCESS OF DERIVATION FROM +THE EMERGENCY RECOVERY PHRASE. Instead, to recover a legacy Sapling key from the emergency +recovery phrase, it is necessary to reconstruct the bytes of the legacy seed by conversion +of the phrase back to its source randomness instead of by hashing as is specified in BIP +39. Only keys and addresses produced after the upgrade can be obtained by normal +derivation of a ZIP 32 or BIP 32 master seed using BIP 39. + +Wallet Updates +-------------- + +The zcashd wallet now supports the Orchard shielded protocol. + +The zcashd wallet has been modified to alter the way that change is handled. In the case +that funds are being spent from a unified account, change is sent to a wallet-internal +change address for that account instead of sending change amounts back to the original +address where a note being spent was received. The rationale for this change is that it +improves the security that is provided to the user of the wallet when supplying incoming +viewing keys to third parties; previously, an incoming viewing key could effectively be +used to detect when a note was spent (hence violating the "incoming" restriction) by +observing change outputs that were sent back to the address where the spent note was +originally received. + +New RPC Methods +--------------- + +- `walletconfirmbackup` This newly created API checks a provided emergency recovery phrase + against the wallet's emergency recovery phrase; if the phrases match then it updates the + wallet state to allow the generation of new addresses. This backup confirmation + workflow can be disabled by starting zcashd with `-walletrequirebackup=false` but this + is not recommended unless you know what you're doing (and have otherwise backed up the + wallet's emergency recovery phrase anyway). For security reasons, this RPC method is + not intended for use via `zcash-cli` but is provided to enable `zcashd-wallet-tool` and + other third-party wallet interfaces to satisfy the backup confirmation requirement. Use + of the `walletconfirmbackup` API via `zcash-cli` would risk that the emergency recovery + phrase being confirmed might be leaked via the user's shell history or the system + process table; `zcashd-wallet-tool` is provided specifically to avoid this problem. +- `z_getnewaccount` This API allows for creation of new BIP 44 / ZIP 32 accounts using HD + derivation from the wallet's mnemonic seed. Each account represents a separate spending + authority and source of funds. A single account may contain funds in the Sapling and + Orchard shielded pools, as well as funds held in transparent addresses. +- `z_listaccounts` This API returns the list of BIP 44 / ZIP 32 accounts that are being + tracked by the wallet. +- `z_getaddressforaccount` This API allows for creation of diversified unified addresses + under a single account. Each call to this API will, by default, create a new diversified + unified address containing transparent p2pkh, Sapling, and Orchard receivers. Additional + arguments to this API may be provided to request the address to be created with a + user-specified set of receiver types and diversifier index. +- `z_getbalanceforaccount` This API makes it possible to obtain balance information on a + per-account basis. +- `z_getbalanceforviewingkey` This API allows a user to obtain balance + information for funds visible to a Sapling or Unified full viewing key; if a Sprout + viewing key is provided, this method allows retrieval of the balance only in the case + that the wallet controls the corresponding spending key. This API has been added to + supplement (and largely supplant) `z_getbalance`. Querying for balance by a single + address returns only the amount received by that address, and omits value sent to other + diversified addresses derived from the same full viewing key; by using + `z_getbalanceforviewingkey` it is possible to obtain a correct balance that includes all + amounts controlled by a single spending key, including both those sent to external + diversified addresses and to wallet-internal change addresses. +- `z_listunifiedreceivers` This API allows the caller to extract the individual component + receivers from a unified address. This is useful if one needs to provide a bare Sapling + or transparent p2pkh address to a service that does not yet support unified addresses. + +RPC Changes +----------- + +- The result type for the `listaddresses` endpoint has been modified: + - The `keypool` source type has been removed; it was reserved but not used. + - In the `sapling` address results, the `zip32AccountId` attribute has been removed in + favor of `zip32KeyPath`. This is to allow distinct key paths to be reported for + addresses derived from the legacy account under different child spending authorities, + as are produced by `z_getnewaddress`. + - Addresses derived from the wallet's mnemonic seed are now included in + `listaddresses` output. +- The results of the `dumpwallet` and `z_exportwallet` RPC methods have been modified + to now include the wallet's newly generated emergency recovery phrase as part of the + exported data. Also, the seed fingerprint and HD keypath information are now included in + the output of these methods for all HD-derived keys. +- The results of the `getwalletinfo` RPC have been modified to return two new fields: + `mnemonic_seedfp` and `legacy_seedfp`, the latter of which replaces the field that + was previously named `seedfp`. +- A new `pool` attribute has been added to each element returned by `z_listunspent` to + indicate which value pool the unspent note controls funds in. +- `z_listreceivedbyaddress` + - A `pool` attribute has been added to each result to indicate what pool the received + funds are held in. + - A boolean-valued `change` attribute has been added to indicate whether the output is + change. + - Block metadata attributes `blockheight`, `blockindex`, and `blocktime` have been + added to the result. +- `z_viewtransaction` has been updated to include attributes that provide information + about Orchard components of the transaction. Also, the `type` attribute for spend and + output values has been deprecated and replaced by the `pool` attribute. +- `z_getnotescount` now also returns information for Orchard notes. +- The output format of `z_exportwallet` has been changed. The exported file now includes + the mnemonic seed for the wallet, and HD keypaths are now exported for transparent + addresses when available. +- The result value for `z_importviewingkey` now includes an `address_type` field that + replaces the now-deprecated `type` key. +- `z_listunspent` has been updated to render unified addresses for Sapling and + Orchard outputs when those outputs are controlled by unified spending keys. Outputs + received by unified internal addresses do not include the `address` field. +- Legacy transparent address generation using `getnewaddress` no longer uses a + preallocated keypool, but instead performs HD derivation from the wallet's mnemonic seed + according to BIP 39 and BIP 44 under account ID `0x7FFFFFFF`. +- `z_gettreestate` has been updated to include information about the Orchard note + commitment tree. + +### 'z_sendmany' + +- The `z_sendmany` RPC call no longer permits Sprout recipients in the list of recipient + addresses. Transactions spending Sprout funds will still result in change being sent + back into the Sprout pool, but no other `Sprout->Sprout` transactions will be + constructed by the Zcashd wallet. +- The restriction that prohibited `Sprout->Sapling` transactions has been lifted; however, + since such transactions reveal the amount crossing pool boundaries, they must be + explicitly enabled via a parameter to the `z_sendmany` call. +- A new string parameter, `privacyPolicy`, has been added to the list of arguments + accepted by `z_sendmany`. This parameter enables the caller to control what kind of + information they permit `zcashd` to reveal on-chain when creating the transaction. If the + transaction can only be created by revealing more information than the given strategy + permits, `z_sendmany` will return an error. The parameter defaults to `LegacyCompat`, + which applies the most restrictive strategy `FullPrivacy` when a Unified Address is + present as the sender or a recipient, and otherwise preserves existing behaviour (which + corresponds to the `AllowFullyTransparent` policy). In cases where it is possible to do + so without revealing additional information, and where it is permitted by the privacy + policy, the wallet will now opportunistically shield funds to the most current pool. +- Since Sprout outputs are no longer created (with the exception of change) + `z_sendmany` no longer generates payment disclosures (which were only available for + Sprout outputs) when the `-paymentdisclosure` experimental feature flag is set. +- Outgoing viewing keys used for shielded outputs are now produced as + described in [ZIP 316](https://zips.z.cash/zip-0316#usage-of-outgoing-viewing-keys) +- When sending from or to one or more unified addresses, change outputs + are now always sent to addresses controlled by the wallet's internal spending keys, as + described in [ZIP 316](https://zips.z.cash/zip-0316#deriving-internal-keys). These + addresses are not returned by any RPC API, as they are intended to never be shared with + any third party, and are for wallet-internal use only. This change improves the privacy + properties that may be maintained when sharing a unified internal viewing key for an + account in the wallet. +- In cases where `z_sendmany` might produce transparent change UTXOs, those UTXOs are + sent to addresses derived from the wallet's mnemonic seed via the BIP 44 `change` + derivation path. + +RPC Deprecations +---------------- + +- `z_getnewaddress` has been deprecated in favor of `z_getnewaccount` and + `z_getaddressforaccount`. +- `z_listaddresses` has been deprecated. Use `listaddresses` instead. +- `z_getbalance` has been deprecated. Use `z_getbalanceforviewingkey` instead. + See the discussion of how change is now handled under the `Wallet` heading for + additional background. +- `z_gettotalbalance` has been deprecated. Use `z_getbalanceforaccount` instead. +- `dumpwallet` has been deprecated. Use `z_exportwallet` instead. + +Build System +------------ + +- Clang has been updated to use LLVM 13.0.1. +- libc++ has been updated to use LLVM 13.0.1, except on Windows where it uses 13.0.0-3. +- The Rust toolchain dependency has been updated to version 1.59.0. + +Platform Support +---------------- + +- Debian 9 has been removed from the list of supported platforms. +- Debian 11 (Bullseye) has been added to the list of supported platforms. +- A build issue (a missing header file) has been fixed for macOS targets. +- On Arch Linux only, a copy of Debian's libtinfo5_6.0 is used to fix a build + regression. + +Mining +------ + +- Mining to Orchard recipients is now supported on testnet. +- It is now possible to mine to a Sapling receiver of a unified address. +- Concurrency bugs related to `getblocktemplate` have been fixed via backports from + Bitcoin Core. + +Licenses +-------- + +- License information in `contrib/debian/copyright` has been updated to be more accurate. + +Changelog +========= + +Alfredo Garcia (3): + change error message + fix grammar in message + remove final dot from error msg + +Charlie O'Keefe (2): + Update base image used by Dockerfile from debian 10 to debian 11 + Remove stretch (debian 9), add bullseye (debian 11) in gitian descriptor + +Conrado Gouvea (2): + Add comment to zcash_script_new_precomputed_tx about references to input buffers + Add zcash_script V5 functions + +Daira Hopwood (42): + Avoid a warning by explicitly calling drop. + Replace call to drop with zeroization. + contrib/devtools/rust-deps-graph.sh: allow overriding the arguments to `cargo deps`. + Cosmetic whitespace change + Make a zcashd-wallet-tool executable. + Attempt to fix linking problem on ARM. + Add some text about choosing location of the physical backup. Add TODO for better handling of file not found and permission errors. + Move `wallet_tool.rs` from `src/rust/src` into `src/rust/bin`. Also add a brief description of `zcashd-wallet-tool` to `src/rust/README.md`. + Improved error handling. + The recovery phrase confirmation and `zcashd-wallet-tool` are being introduced in zcashd v4.7.0. + Refactor use of `export_path` as suggested. + Tweak the wording of the fallback messages when the terminal cannot be automatically cleared. + Simplify extraction of recovery phrase. + Improve memory hygiene, and use -stdin to pass the recovery phrase to the child zcash-cli process. + Cleanups to error handling for the first invocation of zcash-cli. + Use the tracing crate for debugging. + Improve error message when the config file cannot be found, taking into account -conf and -datadir. + Ensure the buffer used in `prompt` is zeroized even on error. + Document that '~' cannot be used in `-datadir` (see #5661). + Set `meta` for `-datadir` option. + Simplify debug tracing. + Correct the fallback instruction for how to clear the terminal on macOS: pressing Command + K also clears scrollback. + Include $(bin_SCRIPTS) in `check-symbols`, `check-security`, and `clean` targets. Checking for stack canaries in `check-security` is disabled for Rust executables (Rust does support `-Z stack-protector=all` but only for the nightly compiler). + qa/zcash/full_test_suite.py: enable `test_rpath_runpath` for Rust binaries, and reenable `test_fortify_source` for C++ binaries. + Tweaks to message text. + zcashd-wallet-tool: add man page generation. fixes #5729 + zcashd-wallet-tool: warn that wallet.dat needs to be backed up. fixes #5704 + zcashd-wallet-tool: adjust man page to correct copyright information. + Start with an empty banlist if -reindex is set. fixes #5739 + contrib/debian/copyright: add license entries for Libtool macros. + contrib/debian/copyright: minor corrections and formatting + contrib/debian/copyright: add licenses of Rust dependencies that do not have Expat/MIT as an option. + contrib/debian/copyright: add license for Apache-2.0. + Switch Jack Grigg's copyright on src/rust/{include/tracing.h, src/tracing_ffi.rs} to the Zcash developers (with his permission). + Repair `feature_zip239` RPC test by checking the debug log of node 0 rather than its stderr. + qa/zcash/updatecheck.py: print status code and response of failed http requests. + Postpone native_clang and libcxx 14.0.0. + Fix an incorrect preprocessor symbol. Also repair the lint-includes-guards.sh script that was checking for the incorrect symbol. + .gitignore: add files temporarily created by autoconf. + This check done for Sprout and Sapling (which is separate from consensus nullifier checks) was not being done for Orchard. + AcceptToMemoryPool: Remove initial nullifier checks for Sprout and Sapling (within the mempool only), that are redundant with checks in HaveShieldedRequirements. The latter take into account nullifiers in the chain (using CCoinsViewMemPool::GetNullifier) and include Orchard. + Revert "rpc: Reload CNode spans after reloading the log filter". fixes #5863 + +Dimitris Apostolou (2): + Fix typos + Fix typos + +Jack Grigg (111): + wallet: Implement `z_getnewaccount` + wallet: Implement `z_getaddressforaccount` + wallet: Implement `z_listunifiedreceivers` + wallet: Show UAs owned by the wallet in `z_viewtransaction` + wallet: Reverse order of arguments to z_getaddressforaccount + rust: Add missing Orchard receiver check in UA parsing + rust: Add missing checks for shielded UFVK items + rust: Add missing checks for transparent UFVK items + wallet: Implement `z_getbalanceforaccount` + wallet: Fix account generation bug + wallet: Implement `z_getbalanceforaddress` + wallet: Don't show Sapling receivers from UAs in `z_listaddresses` + wallet: Show UAs instead of Sapling receivers in `z_listunspent` + wallet: Remove `CWallet::GetKeyFromPool` + wallet: Store internal transparent keys in the keypool + wallet: Separate counters for external and internal transparent keys + Move shielded signature checks out of `ContextualCheckTransaction` + Make `PrecomputedTransactionData` a required argument of `SignatureHash` + Update ZIP 244 test vectors + Add Orchard recipient support to the transaction builder + Update ZIP 244 implementation + Enforce ZIP 244 consensus rules on sighash type + Make `TransactionBuilder::AddOrchardOutput` memo optional + Enforce length constraints on allPrevOutputs + ZIP 244: Address review comments + Return UFVK from `CWallet::GenerateNewUnifiedSpendingKey` + Rename to `ZcashdUnifiedSpendingKey::GetSaplingKey` for consistency + Trial-decrypt candidate Sapling receivers with all wallet UFVKs + Add mappings from Orchard receivers to IVKs to the wallet + Add Orchard to default UA receiver types + Fix semantic merge conflicts + Select Orchard receivers preferentially from UAs + Regenerate `TxDigests` after rebuilding tx with Orchard bundle + Migrate to `orchard` crate revision with circuit changes + qa: Bump all postponed dependencies + qa: Postpone recent CCache release + depends: Update Rust to 1.59.0 + depends: Update Clang / libcxx to LLVM 13.0.1 + cargo update + rust: Fix clippy lint + Ensure the view's best Orchard anchor matches the previous block + Add missing `view.PopAnchor(_, ORCHARD)` in `DisconnectBlock` + Add RPC test for the Orchard commitment tree bug on first NU5 testnet + Use `std::optional` in `CValidationInterface::GetAddressForMining` + Select Orchard receivers from UA miner addresses once NU5 activates + miner: Manually add dummy Orchard output with Orchard miner address + rpc: Handle keypool exhaustion separately in `generate` RPC + libzcash_script: Add more granular errors to the new APIs + depends: Revert to `libc++ 13.0.0-3` for Windows cross-compile + Add Orchard spend support to the transaction builder + wallet: Alter `OrchardWallet::GetSpendInfo` to return the spending key + Improve FFI interface documentation + Refactor `CWallet::GenerateChangeAddressForAccount` + Add unit tests for `SpendableInputs::LimitToAmount` + Fix bug in `SpendableInputs::LimitToAmount` + Select spendable inputs based on recipient and change pool types + Implement opportunistic shielding in `SpendableInputs::LimitToAmount` + Add Orchard cases to note selection logic + Add Orchard to change address generation + Add support for sending Orchard funds in `z_sendmany` + Set default Orchard anchor confirmations to 1 + build: Fix `zcash/address/orchard.hpp` filename in `src/Makefile.am` + z_sendmany: Replace `allowRevealedAmount` with `privacyStrategy` + z_sendmany: Expand `privacyPolicy` cases + build: Add missing `util/match.h` to `src/Makefile.am` + wallet: Add seedfp to transparent keys in dumpwallet / z_exportwallet + Fix bugs in wallet_addresses RPC test + wallet: Fix bugs in `listaddresses` + wallet: Fix Sapling address bug in `listaddresses` + wallet: Fix expected `listaddresses` sources in `rpc_wallet_tests` + qa: Exclude `native_libtinfo` from dependency update checks + cargo update + make-release.py: Versioning changes for 4.7.0-rc1. + make-release.py: Updated manpages for 4.7.0-rc1. + make-release.py: Updated release notes and changelog for 4.7.0-rc1. + Migrate to latest `zcash/librustzcash` revision + Fix logical merge conflicts after merging 4.7.0-rc1 + builder: Use correct `PrecomputedTransactionData` for transparent sigs + Set NU5 protocol version for regtest to 170040, bump protocol version + qa: Remove hard-coded consensus branch IDs from RPC tests + qa: Remove pinned action indices from wallet_listreceived + Test Orchard shielded coinbase rules + test: Print all logged errors to stdout during gtests + builder: Handle `std::ios_base::failure` exceptions during sighash + test: Improve gtest handling of `TransactionBuilderResult::GetTxOrThrow` + rust: Improve `PrecomputedTransactionData` construction errors + test: Fix `WalletTests.GetConflictedOrchardNotes` gtest + qa: Add RPC test testing Orchard note position persistence + wallet: Move Orchard note position data into a separate map + wallet: Persist Orchard note positions with the witness tree + wallet: Add version information to Orchard commitment tree data + wallet: Persist Orchard tx height alongside note positions + qa: Add test for Orchard support in `z_listunspent` + wallet: Treat `mnemonichdchain` records as key material + wallet: Initialise ThreadNotifyWallets with wallet's best block + Apply `HaveShieldedRequirements` to coinbase transactions + mempool: Remove duplicated anchor and nullifier assertions + AcceptToMemoryPool: Re-add missing code comment + wallet: Rename `CWallet::GetBestBlock` to `GetPersistedBestBlock` + Add trace-level logging to the Orchard wallet + wallet: Add assertions during Orchard wallet bundle appends + wallet: Remove duplicate nullifier insertion into Orchard wallet + lint: Add check that every Cargo patch has a matching replacement + qa: Postpone update to Rust 1.60 + wallet: Bump a trace log message to error in `Wallet::checkpoint` + rpc: Document that enabling trace-level logging is unsafe + test: Capture gtest log output and only print on error + qa: Update Berkeley DB release listener regex + cargo update + depends: Remove `hyper 0.14.2` pin + depends: Remove direct `tokio` dependency + +John Newbery (1): + Log calls to getblocktemplate + +Jonas Schnelli (1): + [Wallet] add HD xpriv to dumpwallet + +Kris Nuttycombe (303): + Derive random HD seeds from ZIP-339 seed phrases. + Add support for externally searching for valid Sapling diversifiers. + Adds basic unified spending key derivation. + Add unified full viewing keys and Zcash-internal unified addresses. + Use the default UA-based Sapling address for the saplingmigration tool. + Fix tests for wallet operations on legacy Sapling keys. + Remove unused forward declaration. + Update librustzcash dependency version. + Apply suggestions from code review + Derive transparent keys from mnemonic seed. + Generate legacy Sapling addresses from the mnemonic seed. + Replace account ID with ZIP-0032 key path in listaddresses output. + Use legacy address for Sapling migration until UA functionality is available to the RPC tests. + Revert change to the type of GenerateNewKey + Fix wallet import/export test + Use 0x7FFFFFFF for the legacy account ID. + Require backup of the emergency recovery phrase. + Use hardened derivation for the legacy Sapling key at the address index level. + Address comments from code review. + Restore legacy HD seed storage & retrieval tests. + Fix spurious test passage. + Move CKeyMetadata back to wallet.h + Clean up format of recovery information in the wallet dump. + Use SecureString for mnemonic phrase. + Apply suggestions from code review + Fix diversifier_index_t less than operator. + Restore FindAddress comment + Fix transparent BIP-44 keypaths. + Fix naming of unified spending & full viewing keys + Fix max transparent diversifier index. + Clean up handling of mnemonic seed metadata. + Restore legacy HDSeed encryption tests. + Style fix in BIP 32 path account parsing test. + Do not strip quotes when verifying mnemonic seed. + Apply suggestions from code review + Fix name of menmonic entropy length constant. + Fix polymorphism of string serialization. + Document mnemonic-seed-related RPC method changes & update changelog. + Minor cleanup of the code that searches for a valid transparent key. + Generalize keypath parsing over account id. + Update documentation for GenerateNewSeed. + Use MnemonicSeed instead of HDSeed where appropriate. + Add diversifier_index_t::ToTransparentChildIndex + Only maintain CKeyID for the transparent part of ZcashdUnifiedAddress + Minor naming fixes + Parameterize HD keypath parsing by coin type. + Fix error message text to refer to zcashd-wallet-tool rather than the RPC method. + Apply suggestions from code review + Minor textual fixes to release notes. + Improve documentation of the `-walletrequirebackup` zcashd wallet configuration option. + Add libzcash::AccountId type. + Adds Orchard Address, IncomingViewingKey, FullViewingKey, and SpendingKey types. + Apply suggestions from code review + Update orchard & librustzcash dependency versions. + Remove incorrect FFI method documentation. + Remove Orchard spending key equality implementation. + Refine structure of Zcash address generation. + Use CKeyID and CScriptID instead of new P2PKH/P2SHAddress classes. + Remove ZcashdUnifiedAddress in favor of UnifiedAddress + Update to ufvk zcash_address build. + Adds SaplingDiversifiableFullViewingKey + Add Rust FFI components for unified full viewing keys. + Add UnifiedFullViewingKey type. + Apply suggestions from code review + Add tests for ufvk roundtrip serialization. + Apply suggestions from code review + Apply suggestions from code review + Apply suggestions from code review + Add functions for generating BIP-44 and ZIP-32 keypaths + Check the output of zip339_phrase_to_seed in MnemonicSeed initialization. + Compute key id for UFVKs. + Add ZcashdUnifiedKeyMetadata and libzcash::ReceiverType + Add unified key components to the transparent & Sapling wallet parts. + Store ufvks to the wallet database. + Add unified address tracking to KeyStore + Load unified full viewing keys from the walletdb. + Add key metadata to walletdb. + Add unified address generation. + AddTransparentSecretKey does not need to take a CExtKey + Add newly generated transparent UA receivers to the wallet. + Add CWallet::GetUnifiedForReceiver + Add tests for keystore storage and retrieval of UFVKs. + Add test for wallet UA generation & detection. + Add test for CKeyStore::AddUnifiedAddress + Fix handling of unified full viewing key metadata. + Apply suggestions from code review + Only derive ZcashdUnifiedFullViewingKey from UnifiedFullViewingKey + Rename `ZcashdUnifiedSpendingKeyMetadata` -> `ZcashdUnifiedAccount` + Remove unused ufvkid argument from AddTransparentSecretKey + Ensure that unified address metadata is always correctly populated. + Apply suggestions from code review + Make `FindAddress` correctly check for maximum transparent child index. + Use Bip44TransparentAccountKeyPath() for Bip44AccountChains keypath construction. + Improve documentation of UFVK/UA metadata storage semantics. + Apply suggestions from code review + Fix encoding order of unified addresses. + Remove the `InvalidEncoding` type from key & address variants. + Use CKeyID and CScriptID instead of new P2PKH/P2SHAddress classes. + Remove spurious uses of HaveSpendingKeyForPaymentAddress + Add raw transparent address types to PaymentAddress + Remove spurious variant from asyncrpcoperation_sendmany + Remove `RawAddress` + Replace `DecodeDestination` in `GetMinerAddress` with `DecodePaymentAddress` + Remove uses of KeyIO::DecodeDestination + Remove a use of KeyIO::DecodeDestination in z_shieldcoinbase + Use libzcash::PaymentAddress instead of std::string in mergetoaddress + Improve error messages in the case of taddr decoding failure. + Apply suggestions from code review + Apply suggestions from code review + Use transaction builder for asyncrpcoperation_sendmany. + Transaction builder must not set consensus branch ID for V4 transactions. + Fix conditions around dust thresholds. + Require an explicit flag to allow cross-pool transfers in z_sendmany. + Apply suggestions from code review + Return z_sendmany errors synchronously when possible. + Update release notes to reflect z_sendmany changes + Move FindSpendableInputs to CWallet + Replace the badly-named `PaymentSource` with `ZTXOSelector` + Add support for unified addresses to CWallet::ToZTXOSelector + Replace `HaveSpendingKeyForAddress` with checks at ZTXOSelector construction. + Modify CWallet::FindSpendableInputs to use ZTXOSelector + Add CWallet::FindAccountForSelector + Add RecipientAddress type. + Use libzcash::RecipientAddress for z_sendmany recipients. + Apply suggestions from code review + Rename ZTXOSelector::SpendingKeysAvailable -> RequireSpendingKeys + Make `FindSpendableInputs` respect `ZTXOSelector::RequireSpendingKeys()` + Clarify documentation of CWallet::FindAccountForSelector + Use `ZTXOSelector::IncludesSapling` rather than selector internals. + Add documentation for `UnifiedAddress::GetPreferredRecipientAddress` + Add correct selection of change addresses to z_sendmany + Add a first-class type for transparent full viewing keys. + Implement OVK selection for z_sendmany. + Implement derivation of the internal Sapling spending key. + Use a BIP 44 change address for change when sending from legacy t-addrs. + Add a check for internal vs. external outputs to wallet_listreceived test. + Fix z_sendmany handling of transparent OVK derivation in the ANY_TADDR case. + Simplify determination of valid change types. + Add failing tests for z_sendmany ANY_TADDR -> UA and UA -> + Add gtest for change address derivation. + Fix variable shadowing in change address derivation & add change IVK to the keystore. + GenerateLegacySaplingZKey only needs to return an address, not an extfvk. + Rename AddSaplingIncomingViewingKey -> AddSaplingPaymentAddress + Do not add Sapling addresses to the wallet by default when adding extfvks. + Fix a bug in the generation of addresses from UFVKs + Add accessor method for Sapling IVKs to SaplingDiversifiableFullViewingKey + Address TODOs in rpc-tests/wallet-accounts.py + Add a few additional cases to z_sendmany RPC tests. + Update librustzcash dependency. + Fix nondeterministic test error (checking for the wrong error case). + Use z_shieldcoinbase for Sprout funds in wallet_listreceived tests. + Apply suggestions from code review + Apply suggestions from code review. + Fix nondeterministic test failure in wallet_listreceivedby.py + Fix locking in z_getbalanceforaddress and z_getbalanceforaccount + Replace z_getbalanceforaddress with z_getbalanceforviewingkey + Clarify documentation of z_getbalanceforviewingkey for Sprout viewing keys. + Implement PaymentAddressBelongsToWallet for unified addresses. + Add unified address support to GetSourceForPaymentAddress + Address comments from review. + Add change field to z_listreceivedbyaddress for transparent addrs. + Fix missing std::variant header that was breaking Darwin builds. + Add test vectors for UFVK derivation + Rename sapling-specific zip32 FFI methods. + Make SaveRecipientMappings polymorphic in RecipientMapping type. + Add Rust backend for Orchard components of the wallet. + Add GetFilteredNotes to Orchard wallet. + Add test for Orchard wallet note detection. + Move parsing of unified addresses to UnifiedAddress. + Remove txid field from TxNotes + Apply suggestions from code review + Add various bits of documentation + Add Orchard components to unified address + Add Orchard components to unified full viewing keys + Add Orchard components to unified spending keys + Remove OrchardSpendingKey serialization code + Select Orchard notes in FindSpendableInputs + GenerateNewKey must be guarded by a cs_wallet lock + Filter returned Orchard notes by minimum confirmations. + Log outpoint for failed Sapling witness lookup. + Add a roundtrip test for Orchard merkle frontier serialization from the C++ side. + Add test for Orchard contribution to z_gettotalbalance + Respect minDepth argument for Orchard notes in GetFilteredNotes + Update MSRV for lints. + Update incrementalmerkletree version + Split LoadWalletTx from AddToWallet + Fix missing locks for GenerateNewUnifiedSpendingKey tests. + Record when notes are detected as being spent in the Orchard wallet. + Reset Orchard wallet state when rescanning from below NU5 activation. + Check wallet latest anchor against hashFinalOrchardRoot in ChainTip. + Remove assertions that require Orchard wallet persistence to satisfy. + Add a test for Orchard note detection. + Assert we never attempt to checkpoint the Orchard wallet at a negative block height. + Apply suggestions from code review + Add an `InPoint` type to the Orchard wallet to fix incorrect conflict data. + Apply suggestions from code review + Fix missing update to `last_checkpoint` on rewind. + Track mined-ness instead of spent-ness of notes in the Orchard wallet. + Apply suggestions from code review + Respect maxDepth for Orchard notes in GetFilteredNotes + Set number of confirmations for Orchard notes returned by FindSpendableInputs + Update walletTx with decrypted Orchard action metadata. + Persist Orchard action index/IVK mappings in CWalletTx + Restore decrypted notes to the wallet. + Update tests with rollback checks. + Apply suggestions from code review + Restore mined block heights when restoring decrypted notes. + Apply suggestions from code review + Return std::optional from CExtKey::Master + Ensure that Orchard spentness information is repopulated by LoadUnifiedCaches. + Modify `join_network` in tests to skip mempool resync. + Address suggestions from code review on #5637 + Apply suggestions from code review + Serialize the Orchard note commitment tree to the wallet. + Update orchard_wallet_add_notes_from_bundle documentation. + Derive the new mnemonic seed from the legacy HD seed, if one is available. + Fix indentation. + Apply suggestions from code review + Explicitly specify the change address in the Sapling migration. + Add TODO for Orchard z_listunspent integration. + Document that z_getnewaccount and z_getaddressforaccount replace z_getnewaddress. + Add orchard support to z_getnotescount + Document that Orchard keys are not supported in z_importkey help + Return the correct error for `z_getbalance` if a UA does not correspond to an account in the wallet.. + Update documentation of z_importviewingkey and z_exportviewingkey to address unified keys. + Add UnifiedAddress variant to ZTXOSelector + Eliminate redundancy between the wallet and the keystore. + Simplify retrieval of unified account by address. + Add OrchardWallet::GetTxActions + Apply suggestions from code review + Update z_viewtransaction documentation to correctly represent field names. + Add debug printing for receivers and recipient addresses. + Correctly report change outputs in z_viewtransaction. + Return the default unified address if we have the UFVK but no address metadata. + Fix missing AllowRevealedSenders flag in test. + Uncomment addtional tests that depend on z_viewtransaction. + Minor rename & documentation improvement. + Add RecipientType to GetPaymentAddressForRecipient result. + Make CWallet::DefaultReceiverTypes height-dependent. + Return failure rather than asserting on WriteRecipientMapping failure. + Lock cs_main for accesses to chainActive in GetPaymentAddressForRecipient. + Fix legacy address handling in CWallet::GetPaymentAddressForRecipient + Documentation fix for UnifiedAddressForReciever (+ spelling corrections.) + Restore legacy default Sapling addresses to the keystore. + Assert that pindexStart cannot be null in CWallet::ScanForWalletTransactions + Rename unifiedaddress->address in z_getaddressforaccount results + Add undocumented components to getinfo API. + Improve consistency of RPC parameter and result attribute naming. + Correctly return p2pkh/p2sh labels for z_listunifiedreceivers + Add test for rollback of an Orchard spend. + Add missing filter to ensure only fully-transparent transactions end up in mapOrphans. + Apply suggestions from code review + Improve error message for when a UA is only usable after a future NU. + Improve error logging in walletdb.cpp + Add an RPC test that attempts a double-spend. + Fix overzealous matching of Orchard FVKs to addresses. + Guard against invalid coercion of int to u32 in FindSpendableInputs + Apply suggestions from code review + Ensure that legacy imported addresses are properly restored to the wallet. + Add a test verifying the default addr is added when importing a Sapling key. + Update release notes to include all RPC changes since 4.6.0 + Note that Debian 9 has been removed from the list of supported platforms. + Add independent wallet persistence tests. + Apply suggestions from code review + Add Orchard support to z_listunspent. + Update incrementalmerkletree version to fix GC bug & use updated API. + Add account ID to z_listunspent results. + Add a test demonstrating that z_listaddresses reveals internal addrs. + Do not display internal addresses in z_listaddresses. + Adds a test demonstrating an Orchard wallet initialization bug. + Refactor ChainTip to take a struct of Merkle trees instead of a pair. + Fix a bug in initialization of the Orchard wallet after NU5 activation. + Improve error output from OrchardWallet::get_spend_info + Update test to verify rewind behavior. + Omit check of Orchard commitment root after rewind past first checkpoint. + Only check nWitnessCacheSize on rewind if we've ever witnessed a Sprout or Sapling note. + Add a test demonstrating that change may cross the pool boundary without permission. + Add logging to the miner to provide more detail on tx selection. + Check privacy strategy when setting allowed change types. + Update to orchard-0.1.0-beta.3, incrementalmerkletree 0.3.0-beta.2, secp256k1-0.21 + Make all privacy policy checks after note selection. + Add 'AllowRevealedAmounts' in tests where it is now necessary. + Return MAX_PRIORITY when transactions contain an Orchard bundle. + Use DEFAULT_FEE consistently in wallet_unified_change test + Never consider transactions that pay the default fee to be free. + Fix assertion in wallet initialization when wallet best block is ahead of the main chain. + Apply suggestions from code review + Apply suggestions from code review + Fix error in z_listaccounts help text. + Ensure pindexPrev is not null before mining against it. + Make Orchard `finalState` serialization format match Sapling. + Fix missing null initialization of `pindexLastTip` pointer in ThreadStartWalletNotifier + Fix uninitialized sleep variable. + Don't advance the wallet init timer until past reindex. + Defensively check for a null pindex in `FindFork` + Set NU5 testnet reactivation height. + Update protocol version to 170050 for v4.7.0 release. + Update the release notes to describe consensus changes since v4.6.0 + Apply suggestions from code review + Push back NU5 testnet release height to 1842420 + qa: postpone native_clang, libcxx, boost, and native_b2 upgrades before 4.7.0 release + make-release.py: Versioning changes for 4.7.0. + make-release.py: Updated manpages for 4.7.0. + +Larry Ruane (13): + add ParseArbitraryInt() for diversifier index + add -orchardwallet experimental feature flag + Add new and modify existing Orchard RPCs, non-functional + mining: submitblock: log detailed equihash solution error + allow UA as z_shieldcoinbase destination + fix minconf parsing for z_getbalanceforaccount and z_getbalanceforaddress + Update z_listreceivedbyaddress to support unified addresses (5467) + fix wallet_listreceived.py, add blockdata to taddr output + z_listreceivedbyaddress: reject UA component addr (#5537) + add functional test + document global variables + update listaddresses RPC for UAs, Orchard + Add regtest documentation to book + +Marius Kjærstad (1): + Update copyright year to 2022 + +Marshall Gaucher (1): + Update Dockerfile + +Pieter Wuille (2): + Fix csBestBlock/cvBlockChange waiting in rpc/mining + Modernize best block mutex/cv/hash variable naming + +Sean Bowe (12): + wallet: consolidate unified key/address/account map reconstruction + wallet: restore Orchard secret keys from mnemonic seed + wallet: restore orchard address to IVK mappings during wallet loading + wallet: rather than assert, error in case of inconsistency between FVK and address + wallet: add logging for failure cases in unified cache loading + AddBogusOrchardSpends + Add test that checks if a bundle containing duplicate Orchard nullifiers is rejected. + Hardcode transaction data for DuplicateOrchardNullifier test. + Revert "AddBogusOrchardSpends" + Activate NU5 at start of DuplicateOrchardNullifier test. + Rename constant in include file to avoid conflicts with btest + Fix logic for deciding whether to perform Orchard updates during rescan + +Steven Smith (9): + Lock cs_main prior to calling blockToJSON + Mark z_gettotalbalance and dumpwallet as deprecated + Add Orchard support to the z_gettreestate RPC + Update transaction size estimation to include V5 transactions + Extend uniqueness check in z_sendmany to UA receivers + Load previously persisted sent transaction recipient metadata back into the wallet. + Add Orchard & unified address support to z_viewtransaction. + Ensure z_viewtransaction returns Orchard details + Remove the fExperimentalOrchardWallet flag and related logic + +Taylor Hornby (2): + Untested, not working yet, use libtinfo from the debian packages + Only send exceptions to the log, not stderr + +sasha (21): + on Arch only, use Debian's libtinfo5_6.0 to satisfy clang + explain the 0x0f0f[..]0f0f powLimit constant for regtest + remove superfluous space at end of native_packages line + gtests ordering: change wallet filename in WriteZkeyDirectToDb + gtests ordering: ContextualCheckBlockTest's TearDown deactivates Blossom + gtests ordering: CheckBlock.VersionTooLow calls SelectParams(MAIN) + implement AtomicTimer::zeroize() that resets start_time and total_time + gtests ordering: make Metrics.GetLocalSolPS idempotent + gtests ordering: clean up wallet files before each WalletZkeysTest + make librustzcash_init_zksnark_params idempotent + move proof parameter loading out of gtest/main.cpp and into utiltest.cpp + Call LoadProofParameters() in gtests that need proofs + Add missing wallet/orchard.h to src/Makefile.am + Add missing gtest/test_transaction_builder.h to Makefile.gtest.include + Prevent a pindex == NULL case in the ScanForWalletTransactions traversal + Disallow testnet peers with a protocol version older than 170040 + Fix test_wallet_zkeys failures by increasing diversifier search offset + Fix sporadic failures in StoreAndRetrieveMnemonicSeedInEncryptedStore + Fix the exception message for SetSeedFromMnemonic failure + add walletrequirebackup=false to the zcash argument list in smoke_tests.py + fix smoke_tests.py accounting math to remove the warning before test 4r + +Jack Grigg (1): + Apply suggestions from code review + +Ying Tong Lai (31): + Move SendManyRecipient to wallet.h and introduce optional ua field. + SendTransaction: Introduce recipients argument. + Implement read and write for (txid, recipient) -> ua mapping. + z_sendmany: Only get ua if decoded is ua variant. + ShieldToAddress: Factor out static shieldToAddress() helper. + Docfixes. + CSerializeRecipientAddress: add Read method and make constructor private. + WriteRecipientMapping: Check that receiver exists in UA. + wallet_sendmany_any_taddr.py: Test sending from a change taddr. + wallet_sendmany_any_taddr.py: Test sending output from expired tx. + FindSpendableInputs: Add nDepth < 0 check. + wallet_sendmany_any_taddr.py: Expect expired tx to be ignored. + Orchard: invalidate mempool transactions that use orphaned anchors. + coins_tests.cpp: Add Orchard nullifier to TxWithNullifiers(). + coins_tests: Update tests to include Orchard case. + CWallet::GetConflictS: Handle conflicting Orchard spends. + z_getbalance: Handle Unified Address case. + Adapt RPC tests to use z_getbalance for UAs. + test_wallet: Test GetConflictedOrchardNotes. + Fix GetConflictedOrchardNotes test. + Introduce OrchardWallet::GetPotentialSpendsFromNullifier method. + Update FFI to use scoped APIs for viewing keys and addresses + Introduce CWallet::HaveOrchardSpendingKeyForAddress. + Introduce push_orchard_result in z_listreceivedbyaddress. + IsNoteSaplingChange: Inline internal recipient check. + Correctly derive UAs for unknown Orchard receivers. + Add z_listaccounts RPC. + Inline z_listaccounts check in wallet_accounts.py + Use height of latest network upgrade in -mineraddress validation. + Fix >= bound when iterating over network upgrades. + Check for overflow in IncrementAccountCounter(). + +ying tong (3): + Apply docfixes from code review + Style improvements in RPC tests. + orchard_wallet_get_potential_spends: Do not use uint256 type. + +Zancas Wilcox (4): + blake2b/s is integrated into hashlib, drop external python package dependency + update doctest in gtest suite to prefer hashlib + enforce usage of the get_tests comptool interface as ComparisonTestFramework method + All implementations of ComparisonTestFramework were overriding num_nodes + diff --git a/depend/zcash/doc/release-notes/release-notes-5.0.0-rc1.md b/depend/zcash/doc/release-notes/release-notes-5.0.0-rc1.md new file mode 100644 index 000000000..df92993b5 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-5.0.0-rc1.md @@ -0,0 +1,215 @@ +Notable changes +=============== + +Feature Deprecation and removal +------------------------------- + +`zcashd` now has a [process](https://zcash.github.io/zcash/user/deprecation.html) +for how features of the public API may be deprecated and removed. Feature +deprecation follows a series of steps whereby, over a series of releases, +features first remain enabled by default (but may be explicitly disabled), then +switch to being disabled by default, and eventually are removed entirely. + +A new string-valued option, `-allowdeprecated` has been introduced to allow a +user to explicitly manage the availability of deprecated `zcashd` features. This +flag makes it possible for users to reenable deprecated methods and features +api that are currently disabled by default, or alternately to explicitly +disable all deprecated features if they so choose. Multiple instances of this +argument may be provided. A user may disable deprecated features entirely +by providing the string `none` as the argument to this parameter. In the case +that `none` is specified, multiple invocations of `-allowdeprecated` are not +permitted. + +Deprecated +---------- + +As of this release, the following features are deprecated, but remain +available by default. These features may be disabled by setting +`-allowdeprecated=none`. After release 5.3.0, these features will be +disabled by default and the following flags to `-allowdeprecated` will +be required to permit their continued use: + + - `legacy_privacy` - the default "legacy" privacy policy for z_sendmany + is deprecated. When disabled, the default behavior of z_sendmany will + conform to the `FullPrivacy` directive (introduced in 4.7.0) in all cases + instead of just for transactions involving unified addresses. + - `getnewaddress` - controls availability of the `getnewaddress` RPC method. + - `z_getnewaddress` - controls availability of the `z_getnewaddress` RPC method. + - `addrtype` - controls availability of the deprecated `type` attribute + returned by RPC methods that return address metadata. + +As of this release, the following previously deprecated features are disabled +by default, but may be be reenabled using `-allowdeprecated=`. + + - The `zcrawreceive` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawreceive` + - The `zcrawjoinsplit` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawjoinsplit` + - The `zcrawkeygen` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawkeygen` + +Option handling +--------------- + +- The `-reindex` and `-reindex-chainstate` options now imply `-rescan` + (provided that the wallet is enabled and pruning is disabled, and unless + `-rescan=0` is specified explicitly). +- A new `-anchorconfirmations` argument has been added to allow the user + to specify the number of blocks back from the chain tip that anchors will be + selected from when spending notes. By default, anchors will now be selected + to have 3 confirmations. Values greater than 100 are not supported. +- A new `-orchardactionlimit` option has been added to allow the user to + override the default maximum of 50 Orchard actions per transaction. + Transactions that contain large numbers of Orchard actions can use + large amounts of memory for proving, so the 50-action default limit is + imposed to guard against memory exhaustion. Systems with more than 16G + of memory can safely set this parameter to allow 200 actions or more. + +RPC Interface +------------- + +- The default `minconf` value for `z_sendmany` is now 10 confirmations instead + of 1. If `minconf` and specifies a value less than that provided for + `-anchorconfirmations`, it will also override that value as it is not + possible to spend notes that are more recent than the anchor. Selecting + `minconf` values less than 3 is not recommended, as it allows the transaction + to be distinguished from transactions using the default for + `-anchorconfirmations`. + +RPC Changes +----------- + +- The deprecated `zcrawkeygen`, `zcrawreceive`, and `zcrawjoinsplit` RPC + methods are now disabled by default. Use `-allowdeprecated=` + to select individual features if you wish to continue using these APIs. + +Build system +------------ + +- `zcutil/build.sh` now automatically runs `zcutil/clean.sh` to remove + files created by previous builds. We previously recommended to do this + manually. + +Dependencies +------------ + +- The `boost` and `native_b2` dependencies have been updated to version 1.79.0 + +Tests +----- + +- The environment variable that allows users of the rpc (Python) tests to + override the default path to the `zcashd` executable has been changed + from `BITCOIND` to `ZCASHD`. + +Changelog +========= + +Alex Wied (1): + Cargo.toml: Rename hdwallet source + +Charlie O'Keefe (1): + Use bullseye apt source in Dockerfile to match debian:11 base image + +Daira Hopwood (9): + Fix to 4.7.0 release notes: testnet nodes that upgrade prior to height 1,842,420 actually still need to run with -reindex and -rescan. + zcutil/build.sh: Run zcutil/clean.sh before building. fixes #3625 + Make `-reindex` and `-reindex-chainstate` imply `-rescan` (provided that the wallet is enabled and pruning is disabled, and unless `-rescan=0` is specified explicitly). + zcutil/build-debian-package.sh: copy executable and man page for zcashd-wallet-tool. + zcashd-wallet-tool: improve the error message for an invalid logging filter directive. + Change the numbering convention for hotfixes to increment the patch number, not the hyphen number. fixes #4364 + Rename nOrchardAnchorConfirmations -> nAnchorConfirmations + Select an anchor and notes that have 10 confirmations. + Fix WalletTests.CachedWitnessesEmptyChain for new anchor selection. + +Dimitris Apostolou (1): + Fix typo + +Jack Grigg (3): + Update minimum chain work and set NU5 activation block hash for testnet + make-release.py: Versioning changes for 5.0.0-rc1. + make-release.py: Updated manpages for 5.0.0-rc1. + +Kris Nuttycombe (30): + Update boost dependencies to version 1.79.0 + Default to error logging if we can't parse the log filter. + Fix boolean initialization in Orchard transaction builder. + Use fallible version parsing for tags. + Allow deprecated wallet features to be preemptively disabled. + Remove zcrawreceive, zcrawjoinsplit, zcrawkeygen from default-allowed deprecated methods. + Add deprecation policy to the zcashd book. + Use ERROR level logging for fatal errors in main/init + Remove `-allowdeprecated=all` + Clarify documentation of the deprecation process. + Select Orchard anchors at `-orchardanchorconfirmations` depth. + Add anchor depth parameter to Get*NoteWitnesses + Disallow -anchorconfirmations values > 100 + Add -anchorconfirmations to the release notes + Fix RPC tests that depend upon -anchorconfirmations=1 + Apply suggestions from code review + Gracefully handle Get(Sprout/Sapling)NoteWitnesses failure. + Add parity-scale-codec licenses to contrib/debian/copyright + Ensure transaction integer fields are zero-initialized. + Build releases from a commit hash, rather than a named branch. + Apply suggestions from code review + Update release process documentation to clarify the use of release stabilization branches. + Fix missing handling for imported transparent multisig addresses. + Change default anchor depth from 10 confirmations to 3 + Use default anchor confirmations for minconf in z_mergetoaddress. + Add -orchardactionlimit parameter to guard against memory exhaustion. + Add -orchardactionlimit help text. + Postpone dependency updates prior to v5.0.0-rc1 + Set RELEASE_TO_DEPRECATION_WEEKS to 2 weeks to provide RC EOS halt. + Fix a typo in the release script. + +Larry Ruane (2): + Allow rpc python tests to be run standalone + ThreadStartWalletNotifier: wait until !IBD, rather than !reindex + +Marek (2): + Document the block time in the `z_gettreestate` RPC response + Specify the format and epoch + +Steven Smith (2): + Add orchard pool metrics + Require wallet recovery phrase to be backed up for z_getnewaccount and z_getaddressforaccount + +Taylor Hornby (1): + Reproduce an assertion failure in the listaddresses RPC + +dependabot[bot] (1): + Bump actions/checkout from 2 to 3 + +sasha (28): + Move LoadProofParameters to gtest/utils.cpp + add tx-orchard-duplicate-nullifiers.h to Makefile.gtest.include + Closing #1539 simplifies gtest Makefile. + remove JoinSplitTestingSetup from sighash_tests -- it doesn't need it + Make a LoadGlobalWallet and UnloadGlobalWallet for gtests + Remove proof parameter loading from btests + Separate test suite from tests, inspired by upstream's #12926 + Allow parallel btest runs using make as the parallelization tool. + btest parallelization work: tag #if'd out test suites + Port btest test_basic_joinsplit_verification to gtest suite Joinsplit + Create a new gtest group WalletRPCTests + Port btest rpc_z_shieldcoinbase_internals to gtest suite WalletRPCTests + Port btest rpc_z_mergetoaddress_internals to gtest suite WalletRPCTests + Port btest rpc_z_sendmany_taddr_to_sapling to gtest suite WalletRPCTests + Downgrade btest suite coins_test to BasicTestingSetup + Make [seed_]insecure_rand available to the gtests + Create a new gtest suite CoinsTests + Port CCoinsViewTest to gtest suite CoinsTests + Port nullifier_regression_test to gtest suite CoinsTests + Port anchor_pop_regression_test to gtest suite CoinsTests + Port anchor_regression_test to gtest suite CoinsTests + Port nullifiers_test to gtest suite CoinsTests + Port anchors_flush_test to gtest suite CoinsTests + Port anchors_test to gtest suite CoinsTests + Update copyright header + Update comments in newly-ported gtests to be more consistent with current codebase + Tidy up spacing in newly-ported gtests + Remove -developersapling since it hasn't been implemented for a long time + +teor (1): + Fix typo in getaddressbalance RPC help + diff --git a/depend/zcash/doc/release-notes/release-notes-5.0.0.md b/depend/zcash/doc/release-notes/release-notes-5.0.0.md new file mode 100644 index 000000000..50013b592 --- /dev/null +++ b/depend/zcash/doc/release-notes/release-notes-5.0.0.md @@ -0,0 +1,253 @@ +Notable changes +=============== + +The mainnet activation of the NU5 network upgrade is supported by the 5.0.0 +release, with an activation height of 1687104, which should occur on +approximately May 31, 2022. Please upgrade to this release, or any subsequent +release, in order to follow the NU5 network upgrade. + +The following ZIPs are being deployed, or have been updated, as part of this upgrade: + +* [ZIP 32 : Shielded Hierarchical Deterministic Wallets (updated)](https://zips.z.cash/zip_0032) +* [ZIP 203: Transaction Expiry (updated)](https://zips.z.cash/zip_0203) +* [ZIP 209: Prohibit Negative Shielded Chain Value Pool Balances (updated)](https://zips.z.cash/zip_0209) +* [ZIP 212: Allow Recipient to Derive Ephemeral Secret from Note Plaintext (updated)](https://zips.z.cash/zip_0212) +* [ZIP 213: Shielded Coinbase (updated)](https://zips.z.cash/zip_0213) +* [ZIP 216: Require Canonical Jubjub Point Encodings](https://zips.z.cash/zip_0216) +* [ZIP 221: FlyClient - Consensus-Layer Changes (updated)](https://zips.z.cash/zip_0221) +* [ZIP 224: Orchard Shielded Protocol](https://zips.z.cash/zip_0224) +* [ZIP 225: Version 5 Transaction Format](https://zips.z.cash/zip_0225) +* [ZIP 239: Relay of Version 5 Transactions](https://zips.z.cash/zip_0239) +* [ZIP 244: Transaction Identifier Non-Malleability](https://zips.z.cash/zip_0244) +* [ZIP 252: Deployment of the NU5 Network Upgrade](https://zips.z.cash/zip_0252) +* [ZIP 316: Unified Addresses and Unified Viewing Keys](https://zips.z.cash/zip_0316) +* [ZIP 401: Addressing Mempool Denial-of-Service (clarified)](https://zips.z.cash/zip_0401) + +Feature Deprecation and removal +------------------------------- + +`zcashd` now has a [process](https://zcash.github.io/zcash/user/deprecation.html) +for how features of the public API may be deprecated and removed. Feature +deprecation follows a series of steps whereby, over a series of releases, +features first remain enabled by default (but may be explicitly disabled), then +switch to being disabled by default, and eventually are removed entirely. + +A new string-valued option, `-allowdeprecated` has been introduced to allow a +user to explicitly manage the availability of deprecated `zcashd` features. This +flag makes it possible for users to reenable deprecated methods and features +api that are currently disabled by default, or alternately to explicitly +disable all deprecated features if they so choose. Multiple instances of this +argument may be provided. A user may disable deprecated features entirely +by providing the string `none` as the argument to this parameter. In the case +that `none` is specified, multiple invocations of `-allowdeprecated` are not +permitted. + +Deprecated +---------- + +As of this release, the following features are deprecated, but remain +available by default. These features may be disabled by setting +`-allowdeprecated=none`. After release 5.3.0, these features will be +disabled by default and the following flags to `-allowdeprecated` will +be required to permit their continued use: + + - `legacy_privacy` - the default "legacy" privacy policy for z_sendmany + is deprecated. When disabled, the default behavior of z_sendmany will + conform to the `FullPrivacy` directive (introduced in 4.7.0) in all cases + instead of just for transactions involving unified addresses. + - `getnewaddress` - controls availability of the `getnewaddress` RPC method. + - `getrawchangeaddress` - controls availability of the `getrawchangeaddress` RPC method. + - `z_getbalance` - controls availability of the `z_getbalance` RPC method. + - `z_gettotalbalance` - controls availability of the `z_gettotalbalance` RPC method. + - `z_getnewaddress` - controls availability of the `z_getnewaddress` RPC method. + - `z_listaddresses` - controls availability of the `z_listaddresses` RPC method. + - `addrtype` - controls availability of the deprecated `type` attribute + returned by RPC methods that return address metadata. + +As of this release, the following previously deprecated features are disabled +by default, but may be be reenabled using `-allowdeprecated=`. + + - The `zcrawreceive` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawreceive` + - The `zcrawjoinsplit` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawjoinsplit` + - The `zcrawkeygen` RPC method is disabled. It may be reenabled with + `allowdeprecated=zcrawkeygen` + +Option handling +--------------- + +- The `-reindex` and `-reindex-chainstate` options now imply `-rescan` + (provided that the wallet is enabled and pruning is disabled, and unless + `-rescan=0` is specified explicitly). +- A new `-anchorconfirmations` argument has been added to allow the user + to specify the number of blocks back from the chain tip that anchors will be + selected from when spending notes. By default, anchors will now be selected + to have 3 confirmations. Values greater than 100 are not supported. +- A new `-orchardactionlimit` option has been added to allow the user to + override the default maximum of 50 Orchard actions per transaction. + Transactions that contain large numbers of Orchard actions can use + large amounts of memory for proving, so the 50-action default limit is + imposed to guard against memory exhaustion. Systems with more than 16G + of memory can safely set this parameter to allow 200 actions or more. + +RPC Interface +------------- + +- The default `minconf` value for `z_sendmany` is now 10 confirmations instead + of 1. If `minconf` specifies a value less than that provided for + `-anchorconfirmations`, it will also override that value as it is not + possible to spend notes that are more recent than the anchor. Selecting + `minconf` values less than 3 is not recommended, as it allows the transaction + to be distinguished from transactions using the default for + `-anchorconfirmations`. + +RPC Changes +----------- + +- The deprecated `zcrawkeygen`, `zcrawreceive`, and `zcrawjoinsplit` RPC + methods are now disabled by default. Use `-allowdeprecated=` + to select individual features if you wish to continue using these APIs. + +Build system +------------ + +- `zcutil/build.sh` now automatically runs `zcutil/clean.sh` to remove + files created by previous builds. We previously recommended to do this + manually. + +Dependencies +------------ + +- The `boost` and `native_b2` dependencies have been updated to version 1.79.0 + +Tests +----- + +- The environment variable that allows users of the rpc (Python) tests to + override the default path to the `zcashd` executable has been changed + from `BITCOIND` to `ZCASHD`. + +Changelog +========= + +Alex Wied (1): + Cargo.toml: Rename hdwallet source + +Charlie O'Keefe (1): + Use bullseye apt source in Dockerfile to match debian:11 base image + +Daira Hopwood (9): + Fix to 4.7.0 release notes: testnet nodes that upgrade prior to height 1,842,420 actually still need to run with -reindex and -rescan. + zcutil/build.sh: Run zcutil/clean.sh before building. fixes #3625 + Make `-reindex` and `-reindex-chainstate` imply `-rescan` (provided that the wallet is enabled and pruning is disabled, and unless `-rescan=0` is specified explicitly). + zcutil/build-debian-package.sh: copy executable and man page for zcashd-wallet-tool. + zcashd-wallet-tool: improve the error message for an invalid logging filter directive. + Change the numbering convention for hotfixes to increment the patch number, not the hyphen number. fixes #4364 + Rename nOrchardAnchorConfirmations -> nAnchorConfirmations + Select an anchor and notes that have 10 confirmations. + Fix WalletTests.CachedWitnessesEmptyChain for new anchor selection. + +Dimitris Apostolou (1): + Fix typo + +Jack Grigg (5): + Update minimum chain work and set NU5 activation block hash for testnet + make-release.py: Versioning changes for 5.0.0-rc1. + make-release.py: Updated manpages for 5.0.0-rc1. + make-release.py: Updated release notes and changelog for 5.0.0-rc1. + Migrate to `zcash_primitives 0.6` et al + +Kris Nuttycombe (40): + Update boost dependencies to version 1.79.0 + Default to error logging if we can't parse the log filter. + Fix boolean initialization in Orchard transaction builder. + Use fallible version parsing for tags. + Allow deprecated wallet features to be preemptively disabled. + Remove zcrawreceive, zcrawjoinsplit, zcrawkeygen from default-allowed deprecated methods. + Add deprecation policy to the zcashd book. + Use ERROR level logging for fatal errors in main/init + Remove `-allowdeprecated=all` + Clarify documentation of the deprecation process. + Select Orchard anchors at `-orchardanchorconfirmations` depth. + Add anchor depth parameter to Get*NoteWitnesses + Disallow -anchorconfirmations values > 100 + Add -anchorconfirmations to the release notes + Fix RPC tests that depend upon -anchorconfirmations=1 + Add z_get(total)balance to deprecation flags. + Apply suggestions from code review + Gracefully handle Get(Sprout/Sapling)NoteWitnesses failure. + Add parity-scale-codec licenses to contrib/debian/copyright + Ensure transaction integer fields are zero-initialized. + Build releases from a commit hash, rather than a named branch. + Apply suggestions from code review + Update release process documentation to clarify the use of release stabilization branches. + Fix missing handling for imported transparent multisig addresses. + Change default anchor depth from 10 confirmations to 3 + Use default anchor confirmations for minconf in z_mergetoaddress. + Add -orchardactionlimit parameter to guard against memory exhaustion. + Add -orchardactionlimit help text. + Postpone dependency updates prior to v5.0.0-rc1 + Set RELEASE_TO_DEPRECATION_WEEKS to 2 weeks to provide RC EOS halt. + Fix a typo in the release script. + Fix typos in release notes & Orchard wallet internal API doc. + Add missing parenthesis to -reindex help. + Include getbalance in recommendations for z_getbalance and z_gettotalbalance replacements. + Add tests to check auth data commitments committing to Orchard actions. + Deprecate `getrawchangeaddress` and `z_listaddresses` + Update rpcwallet help to better distinguish transparent-only APIs. + Revert "Set RELEASE_TO_DEPRECATION_WEEKS to 2 weeks to provide RC EOS halt." + make-release.py: Versioning changes for 5.0.0. + make-release.py: Updated manpages for 5.0.0. + +Larry Ruane (2): + Allow rpc python tests to be run standalone + ThreadStartWalletNotifier: wait until !IBD, rather than !reindex + +Marek (2): + Document the block time in the `z_gettreestate` RPC response + Specify the format and epoch + +Steven Smith (2): + Add orchard pool metrics + Require wallet recovery phrase to be backed up for z_getnewaccount and z_getaddressforaccount + +Taylor Hornby (1): + Reproduce an assertion failure in the listaddresses RPC + +dependabot[bot] (1): + Bump actions/checkout from 2 to 3 + +sasha (28): + Move LoadProofParameters to gtest/utils.cpp + add tx-orchard-duplicate-nullifiers.h to Makefile.gtest.include + Closing #1539 simplifies gtest Makefile. + remove JoinSplitTestingSetup from sighash_tests -- it doesn't need it + Make a LoadGlobalWallet and UnloadGlobalWallet for gtests + Remove proof parameter loading from btests + Separate test suite from tests, inspired by upstream's #12926 + Allow parallel btest runs using make as the parallelization tool. + btest parallelization work: tag #if'd out test suites + Port btest test_basic_joinsplit_verification to gtest suite Joinsplit + Create a new gtest group WalletRPCTests + Port btest rpc_z_shieldcoinbase_internals to gtest suite WalletRPCTests + Port btest rpc_z_mergetoaddress_internals to gtest suite WalletRPCTests + Port btest rpc_z_sendmany_taddr_to_sapling to gtest suite WalletRPCTests + Downgrade btest suite coins_test to BasicTestingSetup + Make [seed_]insecure_rand available to the gtests + Create a new gtest suite CoinsTests + Port CCoinsViewTest to gtest suite CoinsTests + Port nullifier_regression_test to gtest suite CoinsTests + Port anchor_pop_regression_test to gtest suite CoinsTests + Port anchor_regression_test to gtest suite CoinsTests + Port nullifiers_test to gtest suite CoinsTests + Port anchors_flush_test to gtest suite CoinsTests + Port anchors_test to gtest suite CoinsTests + Update copyright header + Update comments in newly-ported gtests to be more consistent with current codebase + Tidy up spacing in newly-ported gtests + Remove -developersapling since it hasn't been implemented for a long time + +teor (1): + Fix typo in getaddressbalance RPC help + diff --git a/depend/zcash/doc/release-process.md b/depend/zcash/doc/release-process.md new file mode 100644 index 000000000..90506e8ef --- /dev/null +++ b/depend/zcash/doc/release-process.md @@ -0,0 +1,223 @@ +Release Process +==================== +Meta: There should always be a single release engineer to disambiguate responsibility. + +If this is a hotfix release, please see the [Hotfix Release +Process](https://github.com/zcash/zcash/blob/master/doc/hotfix-process.md) documentation +before proceeding. + +## Pre-release + +### Github Milestone + +Ensure all goals for the github milestone are met. If not, remove tickets +or PRs with a comment as to why it is not included. (Running out of time +is a common reason.) + +### Pre-release checklist: + +Check that dependencies are properly hosted. + +Check that there are no surprising performance regressions. + +Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc. + +Check that dependencies are up-to-date or have been postponed: + +``` +$ ./qa/zcash/updatecheck.py +``` + +If you are missing the `.updatecheck-token` file required to run this script, +please ask Taylor or another Zcash developer for a copy, or create an +unprivileged personal access token for a github account and save it to the +file in the format `username:hex-token`. + +If there are updates that have not been postponed, review their changelogs +for urgent security fixes, and if there aren't any, postpone the update by +adding a line to `qa/zcash/postponed-updates.txt`. + +### Protocol Safety Checks: + +If this release changes the behavior of the protocol or fixes a serious +bug, verify that a pre-release PR merge updated `PROTOCOL_VERSION` in +`version.h` correctly. + +If this release breaks backwards compatibility or needs to prevent +interaction with software forked projects, change the network magic +numbers. Set the four `pchMessageStart` in `CTestNetParams` in +`chainparams.cpp` to random values. + +Both of these should be done in standard PRs ahead of the release +process. If these were not anticipated correctly, this could block the +release, so if you suspect this is necessary, double check with the +whole engineering team. + +## Release dependencies + +The release script has the following dependencies: + +- `help2man` +- `debchange` (part of the devscripts Debian package) + +You can optionally install the `progressbar2` Python module with pip to have a +progress bar displayed during the build process. + +## Versioning + +Zcash version identifiers have the format `vX.Y.Z` with the following conventions: + +* Increments to the `X` component (the "major version") correspond to network + upgrades. A network upgrade occurs only when there is a change to the + consensus rules. +* Increments to the `Y` component (the "minor version") correspond to regular + Zcash releases. These occur approximately every 6 weeks and may include breaking + changes to public APIs. +* Increments to the `Z` component occur only in the case of hotfix releases. + +## Release candidate & release process + +Identify the commit from which the release stabilization branch will be made. +Release stabilization branches are used so that development can proceed +unblocked on the `master` branch during the release candidate testing and +bug-fixing process. By convention, release stabilization branches are named +`version-X.Y.0` where `X` and `Y` are the major and minor versions for the +release. + +In the commands below, and must identify `git` tags +prefixed with the character `v`, i.e. `v1.0.9` (not `1.0.9`). is a +`git` hash identifying the commit on which a release stabilization or release +branch will be based. It is recommended to use the entire hash value to +identify the commit, although a prefix of at least 10 characters is also +permitted. + +### Create the release stabilization branch + +Having identified the commit from which the release will be made, the release +manager constructs the release stabilization branch as follows: + + $ git checkout -b version-X.Y.0 + $ git push 'git@github.com:zcash/zcash' $(git rev-parse --abbrev-ref HEAD) + +### Create the release candidate branch + +Run the release script to create the first release candidate. This will create +a branch based upon the specified commit ID, then commit standard automated +changes to that branch locally: + + $ ./zcutil/make-release.py + +Examples: + + $ ./zcutil/make-release.py 600c4acee1 v1.1.0-rc1 v1.0.0 v1.0.0 280300 + $ ./zcutil/make-release.py b89b48cda1 v1.1.0 v1.1.0-rc1 v1.0.0 300600 + +### Create, Review, and Merge the release branch pull request + +Review the automated changes in git: + + $ git log version-X.Y.0..HEAD + +Push the resulting branch to github: + + $ git push 'git@github.com:$YOUR_GITHUB_NAME/zcash' $(git rev-parse --abbrev-ref HEAD) + +Then create the PR on github targeting the `version-X.Y.0` branch. Complete the +standard review process and wait for CI to complete. + +## Make a tag for the tip of the release candidate branch + +NOTE: This has changed from the previously recommended process. The tag should +be created at the tip of the automatically-generated release branch created by +the release script; this ensures that any changes made to the release +stabilization branch since the initiation of the release process are not +accidentally tagged as being part of the release as a consequence of having +been included in a merge commit. + +Check the last commit on the local and remote versions of the release branch to +make sure they are the same: + + $ git log -1 + +If you haven't previously done so, set the gpg key id you intend to use for +signing: + + git config --global user.signingkey + +Then create the git tag. The `-s` means the release tag will be signed. Enter +"Release ." and save when prompted for a commit message. **CAUTION:** +Remember the `v` at the beginning here: + + $ git tag -s vX.Y.Z-rcN + $ git push origin vX.Y.Z-rcN + +## Merge the release candidate branch to the release stabilization branch + +Once CI has completed and the release candidate branch has sufficient approving +reviews, merge the release candidate branch back to the release stabilization +branch. Testing proceeds as normal. Any changes that need to be made during the +release candidate period are made by submitting PRs targeting the release +stabilization branch. + +Subsequent release candidates, and the creation of the final release, follow +the same process as for release candidates, omitting the `-rcN` suffix for the +final release. + +## Make and deploy deterministic builds + +- Run the [Gitian deterministic build environment](https://github.com/zcash/zcash-gitian) +- Compare the uploaded [build manifests on gitian.sigs](https://github.com/zcash/gitian.sigs) +- If all is well, the DevOps engineer will build the Debian packages and update the + [apt.z.cash package repository](https://apt.z.cash). + +## Add release notes to GitHub + +- Go to the [GitHub tags page](https://github.com/zcash/zcash/tags). +- Click "Add release notes" beside the tag for this release. +- Copy the release blog post into the release description, and edit to suit + publication on GitHub. See previous release notes for examples. +- Click "Publish release" if publishing the release blog post now, or + "Save draft" to store the notes internally (and then return later to publish + once the blog post is up). + +Note that some GitHub releases are marked as "Verified", and others as +"Unverified". This is related to the GPG signature on the release tag - in +particular, GitHub needs the corresponding public key to be uploaded to a +corresponding GitHub account. If this release is marked as "Unverified", click +the marking to see what GitHub wants to be done. + +## Post Release Task List + +### Merge the release stabilization branch + +Once the final release branch has merged to the release stabilization branch, a +new PR should be opened for merging the release stabilization branch into +master. This may require fixing merge conflicts (e.g. changing the version +number in the release stabilization branch to match master, if master is +ahead). Such conflicts **MUST** be addressed with additional commits to the +release stabilization branch; specifically, the branch **MUST NOT** be rebased +on master. + +Once any conflicts have been resolved, the release stabilization branch should +be merged back to the `master` branch, and then deleted. + +### Deploy testnet + +Notify the Zcash DevOps engineer/sysadmin that the release has been tagged. They update +some variables in the company's automation code and then run an Ansible playbook, which: + +* builds Zcash based on the specified branch +* deploys it as a public service (e.g. testnet.z.cash, mainnet.z.cash) +* often the same server can be re-used, and the role idempotently handles upgrades, but if + not then they also need to update DNS records +* possible manual steps: blowing away the `testnet3` dir, deleting old parameters, + restarting DNS seeder. + +Verify that nodes can connect to the mainnet and testnet servers. + +Update the [Zcashd Full Node and CLI](https://zcash.readthedocs.io/en/latest/rtd_pages/zcashd.html) +documentation on ReadTheDocs to give the new version number. + +### Publish the release announcement (blog, github, zcash-dev, slack) + +## Celebrate diff --git a/depend/zcash/doc/security-warnings.md b/depend/zcash/doc/security-warnings.md new file mode 100644 index 000000000..53da5206e --- /dev/null +++ b/depend/zcash/doc/security-warnings.md @@ -0,0 +1,6 @@ +Security Warnings +==================== + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/security_warnings.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/security_warnings.rst \ No newline at end of file diff --git a/depend/zcash/doc/shield-coinbase.md b/depend/zcash/doc/shield-coinbase.md new file mode 100644 index 000000000..f023915b0 --- /dev/null +++ b/depend/zcash/doc/shield-coinbase.md @@ -0,0 +1,5 @@ +# Shielding Coinbase UTXOs + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/shield_coinbase.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/shield_coinbase.rst \ No newline at end of file diff --git a/depend/zcash/doc/tor.md b/depend/zcash/doc/tor.md new file mode 100644 index 000000000..970c6f12f --- /dev/null +++ b/depend/zcash/doc/tor.md @@ -0,0 +1,6 @@ +TOR SUPPORT IN ZCASH +==================== + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/tor.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/tor.rst \ No newline at end of file diff --git a/depend/zcash/doc/translation_strings_policy.md b/depend/zcash/doc/translation_strings_policy.md new file mode 100644 index 000000000..c370dba24 --- /dev/null +++ b/depend/zcash/doc/translation_strings_policy.md @@ -0,0 +1,71 @@ +*** Warning: This document has not been updated for Zcash and may be inaccurate. *** + +Translation Strings Policy +=========================== + +This document provides guidelines for internationalization of the Bitcoin Core software. + +How to translate? +------------------ + +To mark a message as translatable + +- In non-GUI source code (under `src`): use `_("...")` + +No internationalization is used for e.g. developer scripts outside `src`. + +Strings to be translated +------------------------- + +On a high level, these strings are to be translated: + +- GUI strings, anything that appears in a dialog or window + +- Command-line option documentation + +### GUI strings + +Anything that appears to the user in the GUI is to be translated. This includes labels, menu items, button texts, tooltips and window titles. +This includes messages passed to the GUI through the UI interface through `InitMessage`, `ThreadSafeMessageBox` or `ShowProgress`. + +### Command-line options + +Documentation for the command line options in the output of `--help` should be translated as well. + +Make sure that default values do not end up in the string, but use string formatting like `strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)`. Putting default values in strings has led to accidental translations in the past, and forces the string to be retranslated every time the value changes. + +Do not translate messages that are only shown to developers, such as those that only appear when `--help-debug` is used. + +General recommendations +------------------------ + +### Avoid unnecessary translation strings + +Try not to burden translators with translating messages that are e.g. slight variations of other messages. +In the GUI, avoid the use of text where an icon or symbol will do. +Make sure that placeholder texts in forms don't end up in the list of strings to be translated (use ``). + +### Make translated strings understandable + +Try to write translation strings in an understandable way, for both the user and the translator. Avoid overly technical or detailed messages + +### Do not translate internal errors + +Do not translate internal errors, or log messages, or messages that appear on the RPC interface. If an error is to be shown to the user, +use a generic message, then log the detailed message to the log. E.g. "Error: A fatal internal error occurred, see debug.log for details". +This helps troubleshooting; if the error is the same for everyone, the likelihood is increased that it can be found using a search engine. + +### Avoid fragments + +Avoid dividing up a message into fragments. Translators see every string separately, so may misunderstand the context if the messages are not self-contained. + +### Avoid HTML in translation strings + +There have been difficulties with use of HTML in translation strings; translators should not be able to accidentally affect the formatting of messages. +This may sometimes be at conflict with the recommendation in the previous section. + +### String freezes + +During a string freeze (often before a major release), no translation strings are to be added, modified or removed. + +This can be checked by executing `make translate` in the `src` directory, then verifying that `bitcoin_en.ts` remains unchanged. diff --git a/depend/zcash/doc/unit-tests.md b/depend/zcash/doc/unit-tests.md new file mode 100644 index 000000000..1864240ed --- /dev/null +++ b/depend/zcash/doc/unit-tests.md @@ -0,0 +1,6 @@ +Compiling/running automated tests +--------------------------------- + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/development_guidelines.html#testing + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/development_guidelines.rst diff --git a/depend/zcash/doc/wallet-backup.md b/depend/zcash/doc/wallet-backup.md new file mode 100644 index 000000000..e83139cae --- /dev/null +++ b/depend/zcash/doc/wallet-backup.md @@ -0,0 +1,5 @@ +# Wallet Backup Instructions + +This document has been relocated to https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_backup.html + +The source for this document is available at https://gitlab.com/zcash-docs/zcash-docs/blob/master/source/rtd_pages/wallet_backup.rst \ No newline at end of file diff --git a/depend/zcash/doc/zmq.md b/depend/zcash/doc/zmq.md new file mode 100644 index 000000000..25a649ffe --- /dev/null +++ b/depend/zcash/doc/zmq.md @@ -0,0 +1,122 @@ +# Block and Transaction Broadcasting With ZeroMQ + +[ZeroMQ](https://zeromq.org) is a lightweight wrapper around TCP +connections, inter-process communication, and shared-memory, providing +various message-oriented semantics such as publish/subscribe, +request/reply, and push/pull. + +The Zcash daemon can be configured to act as a trusted "border +router", implementing the Zcash wire 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 ZeroMQ 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 ZeroMQ subscriber port in receiving +software; it 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. + +ZeroMQ sockets are self-connecting and self-healing; that is, +connections made between two endpoints will be automatically restored +after an outage, and either end may be freely started or stopped in +any order. + +Because ZeroMQ 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 ZeroMQ feature in Zcash requires the ZeroMQ API >= 4.0.0 +[libzmq](https://github.com/zeromq/libzmq/releases), which you will +need to install if you are not using the depends system. +Typically, it is packaged by distributions as something like +*libzmq5-dev*. The C++ wrapper for ZeroMQ is *not* needed. + +In order to run the example Python client scripts in contrib/ one must +also install *python3-zmq*, though this is not necessary for daemon +operation. + +## Security WARNING + +Enabling this feature even on the loopback interface only (e.g. binding +it to localhost or 127.0.0.1) will still expose it to the wilds of the +Internet, because of an attack vector called DNS rebinding. DNS +rebinding allows an attacker located remotely on the Internet to trick +applications that you're running on the same computer as zcashd to +contact your supposedly localhost-only ZMQ port, then, depending on the +program they may be able to attempt to attack it. + +Do not enable this feature unless you are sure that you know what you +are doing, and that you have a strong reason for thinking that you are +not vulnerable to this type of attack. + +## Enabling + +By default, the ZeroMQ feature is automatically compiled in if the +necessary prerequisites are found. To disable, use --disable-zmq +during the *configure* step of building zcashd: + + $ ./configure --disable-zmq (other options) + +To actually enable operation, one must set the appropriate options on +the commandline or in the configuration file. + +## Usage + +Currently, the following notifications are supported: + + -zmqpubhashtx=address + -zmqpubhashblock=address + -zmqpubrawblock=address + -zmqpubrawtx=address + +The socket type is PUB and the address must be a valid ZeroMQ socket +address. The same address can be used in more than one notification. + +For instance: + + $ zcashd -zmqpubhashtx=tcp://127.0.0.1:28332 \ + -zmqpubrawtx=ipc:///tmp/zcashd.tx.raw + +Each PUB notification has a topic and body, where the header +corresponds to the notification type. For instance, for the +notification `-zmqpubhashtx` the topic is `hashtx` (no null +terminator) and the body is the hexadecimal transaction hash (32 +bytes). + +These options can also be provided in zcash.conf. + +ZeroMQ endpoint specifiers for TCP (and others) are documented in the +[ZeroMQ API](http://api.zeromq.org/4-0:_start). + +Client side, then, the ZeroMQ subscriber socket must have the +ZMQ_SUBSCRIBE option set to one or either of these prefixes (for +instance, just `hash`); without doing so will result in no messages +arriving. Please see `contrib/zmq/zmq_sub.py` for a working example. + +## Remarks + +From the perspective of zcashd, the ZeroMQ socket is write-only; PUB +sockets don't even have a read function. Thus, there is no state +introduced into zcashd directly. Furthermore, no information is +broadcast that wasn't already received from the public P2P network. + +No authentication or authorization is done on connecting clients; it +is assumed that the ZeroMQ port is exposed only to trusted entities, +using other means such as firewalling. + +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. + +There are several possibilities that ZMQ notification can get lost +during transmission depending on the communication type you are +using. zcashd appends an up-counting sequence number to each +notification which allows listeners to detect lost notifications. diff --git a/depend/zcash/libzcash_script.pc.in b/depend/zcash/libzcash_script.pc.in new file mode 100644 index 000000000..bd288484f --- /dev/null +++ b/depend/zcash/libzcash_script.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Zcash transparent script verification library +Description: Library for verifying scripts against the Zcash consensus protocol. +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lzcash_script +Cflags: -I${includedir} diff --git a/depend/zcash/qa/README.md b/depend/zcash/qa/README.md new file mode 100644 index 000000000..6cca07d2d --- /dev/null +++ b/depend/zcash/qa/README.md @@ -0,0 +1,87 @@ +The [pull-tester](/qa/pull-tester/) folder contains a script to call +multiple tests from the [rpc-tests](/qa/rpc-tests/) folder. + +Every pull request to the zcash repository is built and run through +the regression test suite. You can also run all or only individual +tests locally. + +Test dependencies +================= +Before running the tests, the following must be installed. + +Unix +---- +The python3-zmq library is required. On Ubuntu or Debian it can be installed via: +``` +sudo apt-get install python3-zmq +``` + +OS X +------ +``` +pip3 install pyzmq +``` + +Running tests +============= + +You can run any single test by calling + + qa/pull-tester/rpc-tests.py + +Or you can run any combination of tests by calling + + qa/pull-tester/rpc-tests.py ... + +Run the regression test suite with + + qa/pull-tester/rpc-tests.py + +Run all possible tests with + + qa/pull-tester/rpc-tests.py --extended + +By default, tests will be run in parallel. To specify how many jobs to run, +append `--jobs=n` (default n=4). + +If you want to create a basic coverage report for the RPC test suite, append `--coverage`. + +Possible options, which apply to each individual test run: + +``` + -h, --help show this help message and exit + --nocleanup Leave zcashds and test.* datadir on exit or error + --noshutdown Don't stop zcashds after the test execution + --srcdir=SRCDIR Source directory containing zcashd/zcash-cli + (default: ../../src) + --tmpdir=TMPDIR Root directory for datadirs + --tracerpc Print out all RPC calls as they are made + --coveragedir=COVERAGEDIR + Write tested RPC commands into this directory +``` + +If you set the environment variable `PYTHON_DEBUG=1` you will get some debug +output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.py wallet`). + +A 200-block -regtest blockchain and wallets for four nodes +is created the first time a regression test is run and +is stored in the cache/ directory. Each node has the miner +subsidy from 25 mature blocks (25*10=250 ZEC) in its wallet. + +After the first run, the cache/ blockchain and wallets are +copied into a temporary directory and used as the initial +test state. + +If you get into a bad state, you should be able +to recover with: + +```bash +rm -rf cache +killall zcashd +``` + +Writing tests +============= +You are encouraged to write tests for new or existing features. +Further information about the test framework and individual RPC +tests is found in [qa/rpc-tests](/qa/rpc-tests). diff --git a/depend/zcash/qa/pull-tester/rpc-tests.py b/depend/zcash/qa/pull-tester/rpc-tests.py new file mode 100755 index 000000000..0e61bee21 --- /dev/null +++ b/depend/zcash/qa/pull-tester/rpc-tests.py @@ -0,0 +1,454 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +""" +rpc-tests.py - run regression test suite + +This module calls down into individual test cases via subprocess. It will +forward all unrecognized arguments onto the individual test scripts. + +RPC tests are disabled on Windows by default. Use --force to run them anyway. + +For a description of arguments recognized by test scripts, see +`qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. + +""" + +import argparse +import configparser +import os +import time +import shutil +import sys +import subprocess +import tempfile +import re + +SERIAL_SCRIPTS = [ + # These tests involve enough shielded spends (consuming all CPU + # cores) that we can't run them in parallel. + 'mergetoaddress_sapling.py', + 'mergetoaddress_sprout.py', + 'wallet_shieldingcoinbase.py', +] + +BASE_SCRIPTS= [ + # Scripts that are run by the travis build process + # Longest test should go first, to favor running tests in parallel + # vv Tests less than 5m vv + 'wallet.py', + 'wallet_shieldcoinbase_sprout.py', + 'sprout_sapling_migration.py', + 'remove_sprout_shielding.py', + 'zcjoinsplitdoublespend.py', + # vv Tests less than 2m vv + 'zcjoinsplit.py', + 'mergetoaddress_mixednotes.py', + 'wallet_shieldcoinbase_sapling.py', + 'wallet_shieldcoinbase_ua_sapling.py', + 'wallet_shieldcoinbase_ua_nu5.py', + 'turnstile.py', + 'walletbackup.py', + 'zkey_import_export.py', + 'prioritisetransaction.py', + 'wallet_changeaddresses.py', + 'wallet_listreceived.py', + 'mempool_tx_expiry.py', + 'finalsaplingroot.py', + 'wallet_orchard.py', + 'wallet_overwintertx.py', + 'wallet_persistence.py', + 'wallet_listnotes.py', + # vv Tests less than 60s vv + 'orchard_reorg.py', + 'fundrawtransaction.py', + 'reorg_limit.py', + 'mempool_limit.py', + 'p2p-fullblocktest.py', + # vv Tests less than 30s vv + 'wallet_1941.py', + 'wallet_accounts.py', + 'wallet_addresses.py', + 'wallet_anchorfork.py', + 'wallet_changeindicator.py', + 'wallet_deprecation.py', + 'wallet_doublespend.py', + 'wallet_import_export.py', + 'wallet_isfromme.py', + 'wallet_orchard_change.py', + 'wallet_orchard_init.py', + 'wallet_orchard_persistence.py', + 'wallet_nullifiers.py', + 'wallet_sapling.py', + 'wallet_sendmany_any_taddr.py', + 'wallet_treestate.py', + 'wallet_unified_change.py', + 'listtransactions.py', + 'mempool_resurrect_test.py', + 'txn_doublespend.py', + 'txn_doublespend.py --mineblock', + 'getchaintips.py', + 'rawtransactions.py', + 'getrawtransaction_insight.py', + 'rest.py', + 'mempool_spendcoinbase.py', + 'mempool_reorg.py', + 'mempool_nu_activation.py', + 'httpbasics.py', + 'multi_rpc.py', + 'zapwallettxes.py', + 'proxy_test.py', + 'merkle_blocks.py', + 'signrawtransactions.py', + 'signrawtransaction_offline.py', + 'key_import_export.py', + 'nodehandling.py', + 'reindex.py', + 'addressindex.py', + 'spentindex.py', + 'timestampindex.py', + 'decodescript.py', + 'blockchain.py', + 'disablewallet.py', + 'keypool.py', + 'getblocktemplate.py', + 'getmininginfo.py', + 'bip65-cltv-p2p.py', + 'bipdersig-p2p.py', + 'invalidblockrequest.py', + 'invalidtxrequest.py', + 'p2p_nu_peer_management.py', + 'rewind_index.py', + 'p2p_txexpiry_dos.py', + 'p2p_txexpiringsoon.py', + 'p2p_node_bloom.py', + 'regtest_signrawtransaction.py', + 'shorter_block_times.py', + 'mining_shielded_coinbase.py', + 'coinbase_funding_streams.py', + 'framework.py', + 'sapling_rewind_check.py', + 'feature_zip221.py', + 'feature_zip239.py', + 'feature_zip244_blockcommitments.py', + 'upgrade_golden.py', + 'nuparams.py', + 'post_heartwood_rollback.py', + 'feature_logging.py', + 'feature_walletfile.py', + 'wallet_parsing_amounts.py', + 'wallet_broadcast.py', + 'wallet_z_sendmany.py', + 'wallet_zero_value.py', + 'threeofthreerestore.py', +] + +ZMQ_SCRIPTS = [ + # ZMQ test can only be run if bitcoin was built with zmq-enabled. + # call rpc_tests.py with -nozmq to explicitly exclude these tests. + "zmq_test.py"] + +EXTENDED_SCRIPTS = [ + # These tests are not run by the travis build process. + # Longest test should go first, to favor running tests in parallel + 'pruning.py', + # vv Tests less than 20m vv + 'smartfees.py', + # vv Tests less than 5m vv + # vv Tests less than 2m vv + 'getblocktemplate_longpoll.py', + # vv Tests less than 60s vv + 'rpcbind_test.py', + # vv Tests less than 30s vv + 'getblocktemplate_proposals.py', + 'forknotify.py', + 'hardforkdetection.py', + 'invalidateblock.py', + 'receivedby.py', + 'maxblocksinflight.py', +# 'forknotify.py', + 'p2p-acceptblock.py', + 'maxuploadtarget.py', + 'wallet_db_flush.py', +] + +ALL_SCRIPTS = SERIAL_SCRIPTS + BASE_SCRIPTS + ZMQ_SCRIPTS + EXTENDED_SCRIPTS + +def main(): + # Parse arguments and pass through unrecognised args + parser = argparse.ArgumentParser(add_help=False, + usage='%(prog)s [rpc-test.py options] [script options] [scripts]', + description=__doc__, + epilog=''' + Help text and arguments for individual test script:''', + formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') + parser.add_argument('--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude. Do not include the .py extension in the name.') + parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') + parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') + parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') + parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.') + parser.add_argument('--nozmq', action='store_true', help='do not run the zmq tests') + args, unknown_args = parser.parse_known_args() + + # Create a set to store arguments and create the passon string + tests = set(arg for arg in unknown_args if arg[:2] != "--") + passon_args = [arg for arg in unknown_args if arg[:2] == "--"] + + # Read config generated by configure. + config = configparser.ConfigParser() + config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) + + enable_wallet = config["components"].getboolean("ENABLE_WALLET") + enable_utils = config["components"].getboolean("ENABLE_UTILS") + enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + enable_zmq = config["components"].getboolean("ENABLE_ZMQ") and not args.nozmq + + if config["environment"]["EXEEXT"] == ".exe" and not args.force: + # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 + # https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964 + print("Tests currently disabled on Windows by default. Use --force option to enable") + sys.exit(0) + + if not (enable_wallet and enable_utils and enable_bitcoind): + print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") + print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") + sys.exit(0) + + # python3-zmq may not be installed. Handle this gracefully and with some helpful info + if enable_zmq: + try: + import zmq + zmq # Silences pyflakes + except ImportError: + print("ERROR: \"import zmq\" failed. Use -nozmq to run without the ZMQ tests." + "To run zmq tests, see dependency info in /qa/README.md.") + raise + + # Build list of tests + if tests: + # Individual tests have been specified. Run specified tests that exist + # in the ALL_SCRIPTS list. Accept the name with or without .py extension. + test_list = [t for t in ALL_SCRIPTS if + (t in tests or re.sub(".py$", "", t) in tests)] + + print("Running individually selected tests: ") + for t in test_list: + print("\t" + t) + else: + # No individual tests have been specified. Run base tests, and + # optionally ZMQ tests and extended tests. + test_list = SERIAL_SCRIPTS + BASE_SCRIPTS + if enable_zmq: + test_list += ZMQ_SCRIPTS + if args.extended: + test_list += EXTENDED_SCRIPTS + # TODO: BASE_SCRIPTS and EXTENDED_SCRIPTS are sorted by runtime + # (for parallel running efficiency). This combined list will is no + # longer sorted. + + # Remove the test cases that the user has explicitly asked to exclude. + if args.exclude: + for exclude_test in args.exclude.split(','): + if exclude_test + ".py" in test_list: + test_list.remove(exclude_test + ".py") + + if not test_list: + print("No valid test scripts specified. Check that your test is in one " + "of the test lists in rpc-tests.py, or run rpc-tests.py with no arguments to run all tests") + sys.exit(0) + + if args.help: + # Print help for rpc-tests.py, then print help of the first script and exit. + parser.print_help() + subprocess.check_call((config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) + sys.exit(0) + + run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args) + +def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=False, args=[]): + BOLD = ("","") + if os.name == 'posix': + # primitive formatting on supported + # terminal via ANSI escape sequences: + BOLD = ('\033[0m', '\033[1m') + + #Set env vars + if "ZCASHD" not in os.environ: + os.environ["ZCASHD"] = build_dir + '/src/zcashd' + exeext + + tests_dir = src_dir + '/qa/rpc-tests/' + + flags = ["--srcdir={}/src".format(build_dir)] + args + flags.append("--cachedir=%s/qa/cache" % build_dir) + + if enable_coverage: + coverage = RPCCoverage() + flags.append(coverage.flag) + print("Initializing coverage directory at %s\n" % coverage.dir) + else: + coverage = None + + if len(test_list) > 1 and jobs > 1: + # Populate cache + subprocess.check_output([tests_dir + 'create_cache.py'] + flags) + + #Run Tests + all_passed = True + time_sum = 0 + time0 = time.time() + + job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) + + max_len_name = len(max(test_list, key=len)) + results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] + for _ in range(len(test_list)): + (name, stdout, stderr, passed, duration) = job_queue.get_next() + all_passed = all_passed and passed + time_sum += duration + + print('\n' + BOLD[1] + name + BOLD[0] + ":") + print('' if passed else stdout + '\n', end='') + print('' if stderr == '' else 'stderr:\n' + stderr + '\n', end='') + print("Pass: %s%s%s, Duration: %s s\n" % (BOLD[1], passed, BOLD[0], duration)) + + results += "%s | %s | %s s\n" % (name.ljust(max_len_name), str(passed).ljust(6), duration) + + results += BOLD[1] + "\n%s | %s | %s s (accumulated)" % ("ALL".ljust(max_len_name), str(all_passed).ljust(6), time_sum) + BOLD[0] + print(results) + print("\nRuntime: %s s" % (int(time.time() - time0))) + + if coverage: + coverage.report_rpc_coverage() + + print("Cleaning up coverage data") + coverage.cleanup() + + sys.exit(not all_passed) + +class RPCTestHandler: + """ + Trigger the testscrips passed in via the list. + """ + + def __init__(self, num_tests_parallel, tests_dir, test_list=None, flags=None): + assert(num_tests_parallel >= 1) + self.num_jobs = num_tests_parallel + self.tests_dir = tests_dir + self.test_list = test_list + self.flags = flags + self.num_running = 0 + # In case there is a graveyard of zombie bitcoinds, we can apply a + # pseudorandom offset to hopefully jump over them. + # (625 is PORT_RANGE/MAX_NODES) + self.portseed_offset = int(time.time() * 1000) % 625 + self.jobs = [] + + def get_next(self): + while self.num_running < self.num_jobs and self.test_list: + # Add tests + self.num_running += 1 + t = self.test_list.pop(0) + port_seed = ["--portseed={}".format(len(self.test_list) + self.portseed_offset)] + log_stdout = tempfile.SpooledTemporaryFile(max_size=2**16) + log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) + self.jobs.append((t, + time.time(), + subprocess.Popen((self.tests_dir + t).split() + self.flags + port_seed, + universal_newlines=True, + stdout=log_stdout, + stderr=log_stderr), + log_stdout, + log_stderr)) + # Run serial scripts on their own. We always run these first, + # so we won't have added any other jobs yet. + if t in SERIAL_SCRIPTS: + break + if not self.jobs: + raise IndexError('pop from empty list') + while True: + # Return first proc that finishes + time.sleep(.5) + for j in self.jobs: + (name, time0, proc, log_out, log_err) = j + if proc.poll() is not None: + log_out.seek(0), log_err.seek(0) + [stdout, stderr] = [l.read().decode('utf-8') for l in (log_out, log_err)] + log_out.close(), log_err.close() + passed = stderr == "" and proc.returncode == 0 + self.num_running -= 1 + self.jobs.remove(j) + return name, stdout, stderr, passed, int(time.time() - time0) + print('.', end='', flush=True) + + +class RPCCoverage(object): + """ + Coverage reporting utilities for pull-tester. + + Coverage calculation works by having each test script subprocess write + coverage files into a particular directory. These files contain the RPC + commands invoked during testing, as well as a complete listing of RPC + commands per `bitcoin-cli help` (`rpc_interface.txt`). + + After all tests complete, the commands run are combined and diff'd against + the complete list to calculate uncovered RPC commands. + + See also: qa/rpc-tests/test_framework/coverage.py + + """ + def __init__(self): + self.dir = tempfile.mkdtemp(prefix="coverage") + self.flag = '--coveragedir=%s' % self.dir + + def report_rpc_coverage(self): + """ + Print out RPC commands that were unexercised by tests. + + """ + uncovered = self._get_uncovered_rpc_commands() + + if uncovered: + print("Uncovered RPC commands:") + print("".join((" - %s\n" % i) for i in sorted(uncovered))) + else: + print("All RPC commands covered.") + + def cleanup(self): + return shutil.rmtree(self.dir) + + def _get_uncovered_rpc_commands(self): + """ + Return a set of currently untested RPC commands. + + """ + # This is shared from `qa/rpc-tests/test-framework/coverage.py` + reference_filename = 'rpc_interface.txt' + coverage_file_prefix = 'coverage.' + + coverage_ref_filename = os.path.join(self.dir, reference_filename) + coverage_filenames = set() + all_cmds = set() + covered_cmds = set() + + if not os.path.isfile(coverage_ref_filename): + raise RuntimeError("No coverage reference found") + + with open(coverage_ref_filename, 'r', encoding='utf8') as f: + all_cmds.update([i.strip() for i in f.readlines()]) + + for root, dirs, files in os.walk(self.dir): + for filename in files: + if filename.startswith(coverage_file_prefix): + coverage_filenames.add(os.path.join(root, filename)) + + for filename in coverage_filenames: + with open(filename, 'r', encoding='utf8') as f: + covered_cmds.update([i.strip() for i in f.readlines()]) + + return all_cmds - covered_cmds + + +if __name__ == '__main__': + main() diff --git a/depend/zcash/qa/pull-tester/tests_config.ini.in b/depend/zcash/qa/pull-tester/tests_config.ini.in new file mode 100644 index 000000000..69a262d78 --- /dev/null +++ b/depend/zcash/qa/pull-tester/tests_config.ini.in @@ -0,0 +1,18 @@ +# Copyright (c) 2013-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# These environment variables are set by the build process and read by +# rpc-tests.py + +[environment] +SRCDIR=@abs_top_srcdir@ +BUILDDIR=@abs_top_builddir@ +EXEEXT=@EXEEXT@ + +[components] +# Which components are enabled. These are commented out by `configure` if they were disabled when running config. +@ENABLE_WALLET_TRUE@ENABLE_WALLET=true +@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true +@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true +@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true diff --git a/depend/zcash/qa/rpc-tests/.gitignore b/depend/zcash/qa/rpc-tests/.gitignore new file mode 100644 index 000000000..cb41d9442 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/.gitignore @@ -0,0 +1,2 @@ +*.pyc +cache diff --git a/depend/zcash/qa/rpc-tests/README.md b/depend/zcash/qa/rpc-tests/README.md new file mode 100644 index 000000000..315feae71 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/README.md @@ -0,0 +1,108 @@ +Regression tests +================ + +### [test_framework/test_framework.py](test_framework/test_framework.py) +Base class for RPC regression tests. + +### [test_framework/util.py](test_framework/util.py) +Generally useful functions. + +### [test_framework/mininode.py](test_framework/mininode.py) +Basic code to support p2p connectivity to a bitcoind. + +### [test_framework/comptool.py](test_framework/comptool.py) +Framework for comparison-tool style, p2p tests. + +### [test_framework/script.py](test_framework/script.py) +Utilities for manipulating transaction scripts (originally from python-bitcoinlib) + +### [test_framework/blockstore.py](test_framework/blockstore.py) +Implements disk-backed block and tx storage. + +### [test_framework/key.py](test_framework/key.py) +Wrapper around OpenSSL EC_Key (originally from python-bitcoinlib) + +### [test_framework/bignum.py](test_framework/bignum.py) +Helpers for script.py + +### [test_framework/blocktools.py](test_framework/blocktools.py) +Helper functions for creating blocks and transactions. + +P2P test design notes +--------------------- + +## Mininode + +* ```mininode.py``` contains all the definitions for objects that pass +over the network (```CBlock```, ```CTransaction```, etc, along with the network-level +wrappers for them, ```msg_block```, ```msg_tx```, etc). + +* P2P tests have two threads. One thread handles all network communication +with the bitcoind(s) being tested (using python's asyncore package); the other +implements the test logic. + +* ```NodeConn``` is the class used to connect to a bitcoind. If you implement +a callback class that derives from ```NodeConnCB``` and pass that to the +```NodeConn``` object, your code will receive the appropriate callbacks when +events of interest arrive. NOTE: be sure to call +```self.create_callback_map()``` in your derived classes' ```__init__``` +function, so that the correct mappings are set up between p2p messages and your +callback functions. + +* You can pass the same handler to multiple ```NodeConn```'s if you like, or pass +different ones to each -- whatever makes the most sense for your test. + +* Call ```NetworkThread.start()``` after all ```NodeConn``` objects are created to +start the networking thread. (Continue with the test logic in your existing +thread.) + +* RPC calls are available in p2p tests. + +* Can be used to write free-form tests, where specific p2p-protocol behavior +is tested. Examples: ```p2p-accept-block.py```, ```maxblocksinflight.py```. + +## Comptool + +* Testing framework for writing tests that compare the block/tx acceptance +behavior of a bitcoind against 1 or more other bitcoind instances, or against +known outcomes, or both. + +* Set the ```num_nodes``` variable (defined in ```ComparisonTestFramework```) to start up +1 or more nodes. If using 1 node, then ```--testbinary``` can be used as a command line +option to change the bitcoind binary used by the test. If using 2 or more nodes, +then ```--refbinary``` can be optionally used to change the bitcoind that will be used +on nodes 2 and up. + +* Implement a (generator) function called ```get_tests()``` which yields ```TestInstance```s. +Each ```TestInstance``` consists of: + - a list of ```[object, outcome, hash]``` entries + * ```object``` is a ```CBlock```, ```CTransaction```, or + ```CBlockHeader```. ```CBlock```'s and ```CTransaction```'s are tested for + acceptance. ```CBlockHeader```s can be used so that the test runner can deliver + complete headers-chains when requested from the bitcoind, to allow writing + tests where blocks can be delivered out of order but still processed by + headers-first bitcoind's. + * ```outcome``` is ```True```, ```False```, or ```None```. If ```True``` + or ```False```, the tip is compared with the expected tip -- either the + block passed in, or the hash specified as the optional 3rd entry. If + ```None``` is specified, then the test will compare all the bitcoind's + being tested to see if they all agree on what the best tip is. + * ```hash``` is the block hash of the tip to compare against. Optional to + specify; if left out then the hash of the block passed in will be used as + the expected tip. This allows for specifying an expected tip while testing + the handling of either invalid blocks or blocks delivered out of order, + which complete a longer chain. + - ```sync_every_block```: ```True/False```. If ```False```, then all blocks + are inv'ed together, and the test runner waits until the node receives the + last one, and tests only the last block for tip acceptance using the + outcome and specified tip. If ```True```, then each block is tested in + sequence and synced (this is slower when processing many blocks). + - ```sync_every_transaction```: ```True/False```. Analogous to + ```sync_every_block```, except if the outcome on the last tx is "None", + then the contents of the entire mempool are compared across all bitcoind + connections. If ```True``` or ```False```, then only the last tx's + acceptance is tested against the given outcome. + +* For examples of tests written in this framework, see + ```invalidblockrequest.py``` and ```p2p-fullblocktest.py```. + diff --git a/depend/zcash/qa/rpc-tests/addressindex.py b/depend/zcash/qa/rpc-tests/addressindex.py new file mode 100755 index 000000000..e655f9bc6 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/addressindex.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# +# Test addressindex generation and fetching for insightexplorer or lightwalletd +# +# RPCs tested here: +# +# getaddresstxids +# getaddressbalance +# getaddressdeltas +# getaddressutxos +# getaddressmempool + + +from test_framework.test_framework import BitcoinTestFramework + +from test_framework.util import ( + assert_equal, + start_nodes, + stop_nodes, + connect_nodes, + wait_bitcoinds +) + +from test_framework.script import ( + CScript, + OP_HASH160, + OP_EQUAL, + OP_DUP, + OP_DROP, +) + +from test_framework.mininode import ( + COIN, + CTransaction, + CTxIn, CTxOut, COutPoint, +) + +from binascii import hexlify, unhexlify + + +class AddressIndexTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_network(self): + # -insightexplorer causes addressindex to be enabled (fAddressIndex = true) + args_insight = ('-debug', '-txindex', '-experimentalfeatures', '-insightexplorer') + # -lightwallet also causes addressindex to be enabled + args_lightwallet = ('-debug', '-txindex', '-experimentalfeatures', '-lightwalletd') + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [args_insight] * 3 + [args_lightwallet]) + + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) # node3 is only for testing lightwalletd + + self.is_network_split = False + self.sync_all() + + def run_test(self): + + # helper functions + def getaddresstxids(node_index, addresses, start, end): + return self.nodes[node_index].getaddresstxids({ + 'addresses': addresses, + 'start': start, + 'end': end + }) + + def getaddressdeltas(node_index, addresses, start, end, chainInfo=None): + params = { + 'addresses': addresses, + 'start': start, + 'end': end, + } + if chainInfo is not None: + params.update({'chainInfo': chainInfo}) + return self.nodes[node_index].getaddressdeltas(params) + + # default received value is the balance value + def check_balance(node_index, address, expected_balance, expected_received=None): + if isinstance(address, list): + bal = self.nodes[node_index].getaddressbalance({'addresses': address}) + else: + bal = self.nodes[node_index].getaddressbalance(address) + assert_equal(bal['balance'], expected_balance) + if expected_received is None: + expected_received = expected_balance + assert_equal(bal['received'], expected_received) + + # begin test + + self.nodes[0].generate(105) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 5 * 10) + assert_equal(self.nodes[1].getblockcount(), 105) + assert_equal(self.nodes[1].getbalance(), 0) + + # only the oldest 5; subsequent are not yet mature + unspent_txids = [u['txid'] for u in self.nodes[0].listunspent()] + + # Currently our only unspents are coinbase transactions, choose any one + tx = self.nodes[0].getrawtransaction(unspent_txids[0], 1) + + # It just so happens that the first output is the mining reward, + # which has type pay-to-public-key-hash, and the second output + # is the founders' reward, which has type pay-to-script-hash. + addr_p2pkh = tx['vout'][0]['scriptPubKey']['addresses'][0] + addr_p2sh = tx['vout'][1]['scriptPubKey']['addresses'][0] + + # Check that balances from mining are correct (105 blocks mined); in + # regtest, all mining rewards from a single call to generate() are sent + # to the same pair of addresses. + check_balance(1, addr_p2pkh, 105 * 10 * COIN) + check_balance(1, addr_p2sh, 105 * 2.5 * COIN) + + # Multiple address arguments, results are the sum + check_balance(1, [addr_p2sh, addr_p2pkh], 105 * 12.5 * COIN) + + assert_equal(len(self.nodes[1].getaddresstxids(addr_p2pkh)), 105) + assert_equal(len(self.nodes[1].getaddresstxids(addr_p2sh)), 105) + # test getaddresstxids for lightwalletd + assert_equal(len(self.nodes[3].getaddresstxids(addr_p2pkh)), 105) + assert_equal(len(self.nodes[3].getaddresstxids(addr_p2sh)), 105) + + # only the oldest 5 transactions are in the unspent list, + # dup addresses are ignored + height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2pkh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + height_txids = getaddresstxids(1, [addr_p2sh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + # each txid should appear only once + height_txids = getaddresstxids(1, [addr_p2pkh, addr_p2sh], 1, 5) + assert_equal(sorted(height_txids), sorted(unspent_txids)) + + # do some transfers, make sure balances are good + txids_a1 = [] + addr1 = self.nodes[1].getnewaddress() + expected = 0 + expected_deltas = [] # for checking getaddressdeltas (below) + for i in range(5): + # first transaction happens at height 105, mined in block 106 + txid = self.nodes[0].sendtoaddress(addr1, i + 1) + txids_a1.append(txid) + self.nodes[0].generate(1) + self.sync_all() + expected += i + 1 + expected_deltas.append({ + 'height': 106 + i, + 'satoshis': (i + 1) * COIN, + 'txid': txid, + }) + check_balance(1, addr1, expected * COIN) + assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)), sorted(txids_a1)) + assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)), sorted(txids_a1)) + + # Restart all nodes to ensure indices are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + bal = self.nodes[1].getaddressbalance(addr1) + assert_equal(bal['balance'], expected * COIN) + assert_equal(bal['received'], expected * COIN) + assert_equal(sorted(self.nodes[0].getaddresstxids(addr1)), sorted(txids_a1)) + assert_equal(sorted(self.nodes[1].getaddresstxids(addr1)), sorted(txids_a1)) + + # Send 3 from addr1, but -- subtlety alert! -- addr1 at this + # time has 4 UTXOs, with values 1, 2, 3, 4. Sending value 3 requires + # using up the value 4 UTXO, because of the tx fee + # (the 3 UTXO isn't quite large enough). + # + # The txid from sending *from* addr1 is also added to the list of + # txids associated with that address (test will verify below). + + addr2 = self.nodes[2].getnewaddress() + txid = self.nodes[1].sendtoaddress(addr2, 3) + self.sync_all() + + # the one tx in the mempool refers to addresses addr1 and addr2, + # check that duplicate addresses are processed correctly + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1, addr2]}) + assert_equal(len(mempool), 3) + # test getaddressmempool for lightwalletd node + mempool = self.nodes[3].getaddressmempool({'addresses': [addr2, addr1, addr2]}) + assert_equal(len(mempool), 3) + + # addr2 (first arg) + assert_equal(mempool[0]['address'], addr2) + assert_equal(mempool[0]['satoshis'], 3 * COIN) + assert_equal(mempool[0]['txid'], txid) + + # addr1 (second arg) + assert_equal(mempool[1]['address'], addr1) + assert_equal(mempool[1]['satoshis'], (-4) * COIN) + assert_equal(mempool[1]['txid'], txid) + + # addr2 (third arg) + assert_equal(mempool[2]['address'], addr2) + assert_equal(mempool[2]['satoshis'], 3 * COIN) + assert_equal(mempool[2]['txid'], txid) + + # a single address can be specified as a string (not json object) + addr1_mempool = self.nodes[0].getaddressmempool(addr1) + assert_equal(len(addr1_mempool), 1) + # Don't check the timestamp; it's local to the node, and can mismatch + # due to propagation delay. + del addr1_mempool[0]['timestamp'] + for key in addr1_mempool[0].keys(): + assert_equal(mempool[1][key], addr1_mempool[0][key]) + + tx = self.nodes[0].getrawtransaction(txid, 1) + assert_equal(tx['vin'][0]['address'], addr1) + assert_equal(tx['vin'][0]['value'], 4) + assert_equal(tx['vin'][0]['valueSat'], 4 * COIN) + + txids_a1.append(txid) + expected_deltas.append({ + 'height': 111, + 'satoshis': (-4) * COIN, + 'txid': txid, + }) + self.sync_all() # ensure transaction is included in the next block + self.nodes[0].generate(1) + self.sync_all() + + # the send to addr2 tx is now in a mined block, no longer in the mempool + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 0) + + # Test DisconnectBlock() by invalidating the most recent mined block + tip = self.nodes[1].getchaintips()[0] + for i in range(self.num_nodes): + node = self.nodes[i] + # the value 4 UTXO is no longer in our balance + check_balance(i, addr1, (expected - 4) * COIN, expected * COIN) + check_balance(i, addr2, 3 * COIN) + + assert_equal(node.getblockcount(), 111) + node.invalidateblock(tip['hash']) + assert_equal(node.getblockcount(), 110) + + mempool = node.getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 2) + + check_balance(i, addr1, expected * COIN) + check_balance(i, addr2, 0) + + # now re-mine the addr1 to addr2 send + self.nodes[0].generate(1) + self.sync_all() + for node in self.nodes: + assert_equal(node.getblockcount(), 111) + + mempool = self.nodes[0].getaddressmempool({'addresses': [addr2, addr1]}) + assert_equal(len(mempool), 0) + + # the value 4 UTXO is no longer in our balance + check_balance(2, addr1, (expected - 4) * COIN, expected * COIN) + + # Ensure the change from that transaction appears + tx = self.nodes[0].getrawtransaction(txid, 1) + change_vout = list(filter(lambda v: v['valueZat'] != 3 * COIN, tx['vout'])) + change = change_vout[0]['scriptPubKey']['addresses'][0] + + # test getaddressbalance + for node in (2, 3): + bal = self.nodes[node].getaddressbalance(change) + assert(bal['received'] > 0) + + # the inequality is due to randomness in the tx fee + assert(bal['received'] < (4 - 3) * COIN) + assert_equal(bal['received'], bal['balance']) + assert_equal(self.nodes[2].getaddresstxids(change), [txid]) + + # Further checks that limiting by height works + + # various ranges + for i in range(5): + height_txids = getaddresstxids(1, [addr1], 106, 106 + i) + assert_equal(height_txids, txids_a1[0:i+1]) + + height_txids = getaddresstxids(1, [addr1], 1, 108) + assert_equal(height_txids, txids_a1[0:3]) + + # Further check specifying multiple addresses + txids_all = list(txids_a1) + txids_all += self.nodes[1].getaddresstxids(addr_p2pkh) + txids_all += self.nodes[1].getaddresstxids(addr_p2sh) + multitxids = self.nodes[1].getaddresstxids({ + 'addresses': [addr1, addr_p2sh, addr_p2pkh] + }) + # No dups in return list from getaddresstxids + assert_equal(len(multitxids), len(set(multitxids))) + + # set(txids_all) removes its (expected) duplicates + assert_equal(set(multitxids), set(txids_all)) + + # test getaddressdeltas + for node in (1, 3): + deltas = self.nodes[node].getaddressdeltas({'addresses': [addr1]}) + assert_equal(len(deltas), len(expected_deltas)) + for i in range(len(deltas)): + assert_equal(deltas[i]['address'], addr1) + assert_equal(deltas[i]['height'], expected_deltas[i]['height']) + assert_equal(deltas[i]['satoshis'], expected_deltas[i]['satoshis']) + assert_equal(deltas[i]['txid'], expected_deltas[i]['txid']) + + # 106-111 is the full range (also the default) + deltas_limited = getaddressdeltas(1, [addr1], 106, 111) + assert_equal(deltas_limited, deltas) + + # only the first element missing + deltas_limited = getaddressdeltas(1, [addr1], 107, 111) + assert_equal(deltas_limited, deltas[1:]) + + deltas_limited = getaddressdeltas(1, [addr1], 109, 109) + assert_equal(deltas_limited, deltas[3:4]) + + # the full range (also the default) + deltas_info = getaddressdeltas(1, [addr1], 106, 111, chainInfo=True) + assert_equal(deltas_info['deltas'], deltas) + + # check the additional items returned by chainInfo + assert_equal(deltas_info['start']['height'], 106) + block_hash = self.nodes[1].getblockhash(106) + assert_equal(deltas_info['start']['hash'], block_hash) + + assert_equal(deltas_info['end']['height'], 111) + block_hash = self.nodes[1].getblockhash(111) + assert_equal(deltas_info['end']['hash'], block_hash) + + # Test getaddressutxos by comparing results with deltas + utxos = self.nodes[3].getaddressutxos(addr1) + + # The value 4 note was spent, so won't show up in the utxo list, + # so for comparison, remove the 4 (and -4 for output) from the + # deltas list + deltas = self.nodes[1].getaddressdeltas({'addresses': [addr1]}) + deltas = list(filter(lambda d: abs(d['satoshis']) != 4 * COIN, deltas)) + assert_equal(len(utxos), len(deltas)) + for i in range(len(utxos)): + assert_equal(utxos[i]['address'], addr1) + assert_equal(utxos[i]['height'], deltas[i]['height']) + assert_equal(utxos[i]['satoshis'], deltas[i]['satoshis']) + assert_equal(utxos[i]['txid'], deltas[i]['txid']) + + # Check that outputs with the same address in the same tx return one txid + # (can't use createrawtransaction() as it combines duplicate addresses) + addr = "t2LMJ6Arw9UWBMWvfUr2QLHM4Xd9w53FftS" + addressHash = unhexlify("97643ce74b188f4fb6bbbb285e067a969041caf2") + scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL]) + # Add an unrecognized script type to vout[], a legal script that pays, + # but won't modify the addressindex (since the address can't be extracted). + # (This extra output has no effect on the rest of the test.) + scriptUnknown = CScript([OP_HASH160, OP_DUP, OP_DROP, addressHash, OP_EQUAL]) + unspent = list(filter(lambda u: u['amount'] >= 4, self.nodes[0].listunspent())) + tx = CTransaction() + tx.vin = [CTxIn(COutPoint(int(unspent[0]['txid'], 16), unspent[0]['vout']))] + tx.vout = [ + CTxOut(1 * COIN, scriptPubKey), + CTxOut(2 * COIN, scriptPubKey), + CTxOut(7 * COIN, scriptUnknown), + ] + tx = self.nodes[0].signrawtransaction(hexlify(tx.serialize()).decode('utf-8')) + txid = self.nodes[0].sendrawtransaction(tx['hex'], True) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[1].getaddresstxids(addr), [txid]) + check_balance(2, addr, 3 * COIN) + + +if __name__ == '__main__': + AddressIndexTest().main() diff --git a/depend/zcash/qa/rpc-tests/bip65-cltv-p2p.py b/depend/zcash/qa/rpc-tests/bip65-cltv-p2p.py new file mode 100755 index 000000000..2fb02ab3c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/bip65-cltv-p2p.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import hex_str_to_bytes, start_nodes +from test_framework.mininode import CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block +from test_framework.comptool import TestInstance, TestManager +from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP +from io import BytesIO + +''' +This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY). +Connect to a single node. +Mine a coinbase block, and then ... +Mine 1 version 4 block. +Check that the CLTV rules are enforced. + +TODO: factor out common code from {bipdersig-p2p,bip65-cltv-p2p}.py. +''' + +class BIP65Test(ComparisonTestFramework): + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']], + binary=[self.options.testbinary]) + self.is_network_split = False + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + test.run() + + def create_transaction(self, node, coinbase, to_address, amount): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + f = BytesIO(hex_str_to_bytes(signresult['hex'])) + tx.deserialize(f) + return tx + + def invalidate_transaction(self, tx): + ''' + Modify the signature in vin 0 of the tx to fail CLTV + + Prepends -1 CLTV DROP in the scriptSig itself. + ''' + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] + + list(CScript(tx.vin[0].scriptSig))) + + def get_tests(self): + self.coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) + height = 102 # height of the next block to build + hashTip = self.nodes[0].getbestblockhash() + hashFinalSaplingRoot = int("0x" + self.nodes[0].getblock(hashTip)['finalsaplingroot'] , 0) + self.tip = int("0x" + hashTip , 0) + self.nodeaddress = self.nodes[0].getnewaddress() + + '''Check that the rules are enforced.''' + for valid in (True, False): + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, 1.0) + if not valid: + self.invalidate_transaction(spendtx) + spendtx.rehash() + + gbt = self.nodes[0].getblocktemplate() + self.block_time = gbt["mintime"] + 1 + self.block_bits = int("0x" + gbt["bits"], 0) + + block = create_block(self.tip, create_coinbase(height), + self.block_time, self.block_bits, + hashFinalSaplingRoot) + block.nVersion = 4 + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + self.block_time += 1 + self.tip = block.sha256 + yield TestInstance([[block, valid]]) + + +if __name__ == '__main__': + BIP65Test().main() diff --git a/depend/zcash/qa/rpc-tests/bipdersig-p2p.py b/depend/zcash/qa/rpc-tests/bipdersig-p2p.py new file mode 100755 index 000000000..e61813c8c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/bipdersig-p2p.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import hex_str_to_bytes, start_nodes +from test_framework.mininode import CTransaction, NetworkThread +from test_framework.blocktools import create_coinbase, create_block +from test_framework.comptool import TestInstance, TestManager +from test_framework.script import CScript +from io import BytesIO + + +''' +This test is meant to exercise BIP66 (DER SIG). +Connect to a single node. +Mine a coinbase block, and then ... +Mine 1 version 4 block. +Check that the DERSIG rules are enforced. + +TODO: factor out common code from {bipdersig-p2p,bip65-cltv-p2p}.py. +''' +class BIP66Test(ComparisonTestFramework): + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']], + binary=[self.options.testbinary]) + self.is_network_split = False + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + test.run() + + def create_transaction(self, node, coinbase, to_address, amount): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + signresult = node.signrawtransaction(rawtx) + tx = CTransaction() + f = BytesIO(hex_str_to_bytes(signresult['hex'])) + tx.deserialize(f) + return tx + + def invalidate_transaction(self, tx): + ''' + Make the signature in vin 0 of a tx non-DER-compliant, + by adding padding after the S-value. + + A canonical signature consists of: + <30> <02> <02> + ''' + scriptSig = CScript(tx.vin[0].scriptSig) + newscript = [] + for i in scriptSig: + if (len(newscript) == 0): + newscript.append(i[0:-1] + '\0' + i[-1]) + else: + newscript.append(i) + tx.vin[0].scriptSig = CScript(newscript) + + def get_tests(self): + self.coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) + height = 102 # height of the next block to build + hashTip = self.nodes[0].getbestblockhash() + hashFinalSaplingRoot = int("0x" + self.nodes[0].getblock(hashTip)['finalsaplingroot'], 0) + self.tip = int("0x"+hashTip , 0) + self.nodeaddress = self.nodes[0].getnewaddress() + + '''Check that the rules are enforced.''' + for valid in (True, False): + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, 1.0) + if not valid: + self.invalidate_transaction(spendtx) + spendtx.rehash() + + gbt = self.nodes[0].getblocktemplate() + self.block_time = gbt["mintime"] + 1 + self.block_bits = int("0x" + gbt["bits"], 0) + + block = create_block(self.tip, create_coinbase(height), + self.block_time, self.block_bits, + hashFinalSaplingRoot) + block.nVersion = 4 + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + block.solve() + self.tip = block.sha256 + yield TestInstance([[block, valid]]) + + +if __name__ == '__main__': + BIP66Test().main() diff --git a/depend/zcash/qa/rpc-tests/blockchain.py b/depend/zcash/qa/rpc-tests/blockchain.py new file mode 100755 index 000000000..7f65063a1 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/blockchain.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test RPC calls related to blockchain state. Tests correspond to code in +# rpc/blockchain.cpp. +# + +import decimal + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + start_nodes, + connect_nodes_bi, +) + +class BlockchainTest(BitcoinTestFramework): + """ + Test blockchain-related RPC calls: + + - gettxoutsetinfo + + """ + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 2 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + connect_nodes_bi(self.nodes, 0, 1) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + res = node.gettxoutsetinfo() + + assert_equal(res['total_amount'], decimal.Decimal('2143.75000000')) # 144*12.5 + 55*6.25 + assert_equal(res['transactions'], 200) + assert_equal(res['height'], 200) + assert_equal(res['txouts'], 343) # 144*2 + 55 + assert_equal(res['bytes_serialized'], 14819), # 32*199 + 48*90 + 49*54 + 27*55 + assert_equal(len(res['bestblock']), 64) + assert_equal(len(res['hash_serialized']), 64) + + +if __name__ == '__main__': + BlockchainTest().main() diff --git a/depend/zcash/qa/rpc-tests/coinbase_funding_streams.py b/depend/zcash/qa/rpc-tests/coinbase_funding_streams.py new file mode 100755 index 000000000..0fd6e84c8 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/coinbase_funding_streams.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.mininode import ( + nuparams, + fundingstream, +) +from test_framework.util import ( + assert_equal, + bitcoind_processes, + connect_nodes, + start_node, + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, +) + +class CoinbaseFundingStreamsTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = True + + def start_node_with(self, index, extra_args=[]): + args = [ + nuparams(BLOSSOM_BRANCH_ID, 1), + nuparams(HEARTWOOD_BRANCH_ID, 2), + nuparams(CANOPY_BRANCH_ID, 5), + "-nurejectoldversions=false", + ] + return start_node(index, self.options.tmpdir, args + extra_args) + + def setup_network(self, split=False): + self.nodes = [] + self.nodes.append(self.start_node_with(0)) + self.nodes.append(self.start_node_with(1)) + connect_nodes(self.nodes[1], 0) + self.is_network_split=False + self.sync_all() + + def run_test (self): + # Generate a shielded address for node 1 for miner rewards, + miner_addr = self.nodes[1].z_getnewaddress('sapling') + + # Generate a shielded address (belonging to node 0) for funding stream + # rewards. + fs_addr = self.nodes[0].z_getnewaddress('sapling') + + # Generate past heartwood activation we won't need node 1 from this + # point onward except to check miner reward balances + self.nodes[1].generate(2) + self.sync_all() + + # Restart node 0 with funding streams. + self.nodes[0].stop() + bitcoind_processes[0].wait() + self.nodes[0] = self.start_node_with(0, [ + "-mineraddress=%s" % miner_addr, + "-minetolocalwallet=0", + fundingstream(0, 5, 9, [fs_addr, fs_addr, fs_addr]), + fundingstream(1, 5, 9, [fs_addr, fs_addr, fs_addr]), + fundingstream(2, 5, 9, [fs_addr, fs_addr, fs_addr]), + ]) + connect_nodes(self.nodes[1], 0) + self.sync_all() + + print("Generate to just prior to Canopy activation") + self.nodes[0].generate(2) + self.sync_all() + + # All miner addresses belong to node 1; check balances + walletinfo = self.nodes[1].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 10) + assert_equal(walletinfo['balance'], 0) + assert_equal(self.nodes[1].z_getbalance(miner_addr, 0), 10) + assert_equal(self.nodes[1].z_getbalance(miner_addr), 10) + + print("Activating Canopy") + self.nodes[0].generate(4) + self.sync_all() + + # check that miner payments made it to node 1's wallet + walletinfo = self.nodes[1].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 10) + assert_equal(walletinfo['balance'], 0) + assert_equal(self.nodes[1].z_getbalance(miner_addr, 0), 30) + assert_equal(self.nodes[1].z_getbalance(miner_addr), 30) + + # check that the node 0 private balance has been augmented by the + # funding stream payments + assert_equal(self.nodes[0].z_getbalance(fs_addr, 0), 5) + assert_equal(self.nodes[0].z_getbalance(fs_addr), 5) + assert_equal(self.nodes[0].z_gettotalbalance()['private'], '5.00') + assert_equal(self.nodes[0].z_gettotalbalance()['total'], '5.00') + +if __name__ == '__main__': + CoinbaseFundingStreamsTest().main() + diff --git a/depend/zcash/qa/rpc-tests/create_cache.py b/depend/zcash/qa/rpc-tests/create_cache.py new file mode 100755 index 000000000..f93aab04e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/create_cache.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Helper script to create the cache +# (see BitcoinTestFramework.setup_chain) +# + +from test_framework.test_framework import BitcoinTestFramework + +class CreateCache(BitcoinTestFramework): + + def __init__(self): + super().__init__() + + # Test network and test nodes are not required: + self.num_nodes = 0 + self.nodes = [] + + def setup_network(self): + pass + + def run_test(self): + pass + +if __name__ == '__main__': + CreateCache().main() diff --git a/depend/zcash/qa/rpc-tests/decodescript.py b/depend/zcash/qa/rpc-tests/decodescript.py new file mode 100755 index 000000000..9523c96aa --- /dev/null +++ b/depend/zcash/qa/rpc-tests/decodescript.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + start_nodes, hex_str_to_bytes, bytes_to_hex_str +from test_framework.mininode import CTransaction +from io import BytesIO + + +class DecodeScriptTest(BitcoinTestFramework): + """Tests decoding scripts via RPC command "decodescript".""" + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + self.is_network_split = False + + def decodescript_script_sig(self): + signature = '304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001' + push_signature = '48' + signature + public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2' + push_public_key = '21' + public_key + + # below are test cases for all of the standard transaction types + + # 1) P2PK scriptSig + # the scriptSig of a public key scriptPubKey simply pushes a signature onto the stack + rpc_result = self.nodes[0].decodescript(push_signature) + assert_equal(signature, rpc_result['asm']) + + # 2) P2PKH scriptSig + rpc_result = self.nodes[0].decodescript(push_signature + push_public_key) + assert_equal(signature + ' ' + public_key, rpc_result['asm']) + + # 3) multisig scriptSig + # this also tests the leading portion of a P2SH multisig scriptSig + # OP_0 + rpc_result = self.nodes[0].decodescript('00' + push_signature + push_signature) + assert_equal('0 ' + signature + ' ' + signature, rpc_result['asm']) + + # 4) P2SH scriptSig + # an empty P2SH redeemScript is valid and makes for a very simple test case. + # thus, such a spending scriptSig would just need to pass the outer redeemScript + # hash test and leave true on the top of the stack. + rpc_result = self.nodes[0].decodescript('5100') + assert_equal('1 0', rpc_result['asm']) + + # 5) null data scriptSig - no such thing because null data scripts can not be spent. + # thus, no test case for that standard transaction type is here. + + def decodescript_script_pub_key(self): + public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2' + push_public_key = '21' + public_key + public_key_hash = '11695b6cd891484c2d49ec5aa738ec2b2f897777' + push_public_key_hash = '14' + public_key_hash + + # below are test cases for all of the standard transaction types + + # 1) P2PK scriptPubKey + # OP_CHECKSIG + rpc_result = self.nodes[0].decodescript(push_public_key + 'ac') + assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm']) + + # 2) P2PKH scriptPubKey + # OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac') + assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm']) + + # 3) multisig scriptPubKey + # OP_CHECKMULTISIG + # just imagine that the pub keys used below are different. + # for our purposes here it does not matter that they are the same even though it is unrealistic. + rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_public_key + push_public_key + '53ae') + assert_equal('2 ' + public_key + ' ' + public_key + ' ' + public_key + ' 3 OP_CHECKMULTISIG', rpc_result['asm']) + + # 4) P2SH scriptPubKey + # OP_HASH160 OP_EQUAL. + # push_public_key_hash here should actually be the hash of a redeem script. + # but this works the same for purposes of this test. + rpc_result = self.nodes[0].decodescript('a9' + push_public_key_hash + '87') + assert_equal('OP_HASH160 ' + public_key_hash + ' OP_EQUAL', rpc_result['asm']) + + # 5) null data scriptPubKey + # use a signature look-alike here to make sure that we do not decode random data as a signature. + # this matters if/when signature sighash decoding comes along. + # would want to make sure that no such decoding takes place in this case. + signature_imposter = '48304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001' + # OP_RETURN + rpc_result = self.nodes[0].decodescript('6a' + signature_imposter) + assert_equal('OP_RETURN ' + signature_imposter[2:], rpc_result['asm']) + + # 6) a CLTV redeem script. redeem scripts are in-effect scriptPubKey scripts, so adding a test here. + # OP_NOP2 is also known as OP_CHECKLOCKTIMEVERIFY. + # just imagine that the pub keys used below are different. + # for our purposes here it does not matter that they are the same even though it is unrealistic. + # + # OP_IF + # OP_CHECKSIGVERIFY + # OP_ELSE + # OP_NOP2 OP_DROP + # OP_ENDIF + # OP_CHECKSIG + # + # lock until block 500,000 + rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac') + assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm']) + + def decoderawtransaction_asm_sighashtype(self): + """Tests decoding scripts via RPC command "decoderawtransaction". + + This test is in with the "decodescript" tests because they are testing the same "asm" script decodes. + """ + + # this test case uses a random plain vanilla mainnet transaction with a single P2PKH input and output + tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm']) + + # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs. + # it's from James D'Angelo's awesome introductory videos about multisig: https://www.youtube.com/watch?v=zIbUSaZBJgU and https://www.youtube.com/watch?v=OSA1pwlaypc + # verify that we have not altered scriptPubKey decoding. + tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914dc863734a218bfe83ef770ee9d41a27f824a6e5688acee2a02000000000017a9142a5edea39971049a540474c6a99edf0aa4074c588700000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('8e3730608c3b0bb5df54f09076e196bc292a8e39a78e73b44b6ba08c78f5cbb0', rpc_result['txid']) + assert_equal('0 3045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea[ALL] 3045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75[ALL] 5221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53ae', rpc_result['vin'][0]['scriptSig']['asm']) + assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) + assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) + txSave = CTransaction() + txSave.deserialize(BytesIO(hex_str_to_bytes(tx))) + + # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type + tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm']) + + # verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks + tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000' + rpc_result = self.nodes[0].decoderawtransaction(tx) + assert_equal('OP_DUP OP_HASH160 3011020701010101010101020601010101010101 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm']) + assert_equal('OP_HASH160 3011020701010101010101020601010101010101 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm']) + + # some more full transaction tests of varying specific scriptSigs. used instead of + # tests in decodescript_script_sig because the decodescript RPC is specifically + # for working on scriptPubKeys (argh!). + push_signature = bytes_to_hex_str(txSave.vin[0].scriptSig)[2:(0x48*2+4)] + signature = push_signature[2:] + der_signature = signature[:-2] + signature_sighash_decoded = der_signature + '[ALL]' + signature_2 = der_signature + '82' + push_signature_2 = '48' + signature_2 + signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]' + + # 1) P2PK scriptSig + txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) + assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # make sure that the sighash decodes come out correctly for a more complex / lesser used case. + txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) + assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # 2) multisig scriptSig + txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature + push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) + assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # 3) test a scriptSig that contains more than push operations. + # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it. + txSave.vin[0].scriptSig = hex_str_to_bytes('6a143011020701010101010101020601010101010101') + rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize())) + assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm']) + + def run_test(self): + self.decodescript_script_sig() + self.decodescript_script_pub_key() + self.decoderawtransaction_asm_sighashtype() + +if __name__ == '__main__': + DecodeScriptTest().main() diff --git a/depend/zcash/qa/rpc-tests/disablewallet.py b/depend/zcash/qa/rpc-tests/disablewallet.py new file mode 100755 index 000000000..f29820414 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/disablewallet.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Exercise API with -disablewallet. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_nodes + + +class DisableWalletTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [['-disablewallet']]) + self.is_network_split = False + self.sync_all() + + def run_test (self): + # Check regression: https://github.com/bitcoin/bitcoin/issues/6963#issuecomment-154548880 + x = self.nodes[0].validateaddress('t3b1jtLvxCstdo1pJs9Tjzc5dmWyvGQSZj8') + assert(x['isvalid'] == False) + x = self.nodes[0].validateaddress('tmGqwWtL7RsbxikDSN26gsbicxVr2xJNe86') + assert(x['isvalid'] == True) + +if __name__ == '__main__': + DisableWalletTest ().main () diff --git a/depend/zcash/qa/rpc-tests/feature_logging.py b/depend/zcash/qa/rpc-tests/feature_logging.py new file mode 100755 index 000000000..0e0977ef9 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/feature_logging.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +"""Test debug logging.""" + +import os + +from test_framework.util import start_node, stop_node, assert_start_raises_init_error + +from test_framework.test_framework import BitcoinTestFramework + +class LoggingTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + + def run_test(self): + # test default log file name + assert os.path.isfile(os.path.join(self.options.tmpdir, "node0", "regtest", "debug.log")) + + # test alternative log file name in datadir + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debuglogfile=foo.log"]) + assert os.path.isfile(os.path.join(self.options.tmpdir, "node0", "regtest", "foo.log")) + + # test alternative log file name outside datadir + tempname = os.path.join(self.options.tmpdir, "foo.log") + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debuglogfile=%s" % tempname]) + assert os.path.isfile(tempname) + + # check that invalid log (relative) will cause error + invdir = os.path.join(self.options.tmpdir, "node0", "regtest", "foo") + invalidname = os.path.join("foo", "foo.log") + stop_node(self.nodes[0], 0) + assert_start_raises_init_error(0, "-debuglogfile=%s" % (invalidname), + "Error: Could not open debug log file") + assert not os.path.isfile(os.path.join(invdir, "foo.log")) + + # check that invalid log (relative) works after path exists + os.mkdir(invdir) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debuglogfile=%s" % (invalidname)]) + assert os.path.isfile(os.path.join(invdir, "foo.log")) + + # check that invalid log (absolute) will cause error + stop_node(self.nodes[0], 0) + invdir = os.path.join(self.options.tmpdir, "foo") + invalidname = os.path.join(invdir, "foo.log") + assert_start_raises_init_error(0, "-debuglogfile=%s" % invalidname, + "Error: Could not open debug log file") + + # check that invalid log (absolute) works after path exists + os.mkdir(invdir) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-debuglogfile=%s" % invalidname]) + assert os.path.isfile(os.path.join(invdir, "foo.log")) + +if __name__ == '__main__': + LoggingTest().main() diff --git a/depend/zcash/qa/rpc-tests/feature_walletfile.py b/depend/zcash/qa/rpc-tests/feature_walletfile.py new file mode 100755 index 000000000..085624ff0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/feature_walletfile.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +"""Test wallet file location.""" + +import os + +from test_framework.util import start_node, stop_node, assert_start_raises_init_error + +from test_framework.test_framework import BitcoinTestFramework + +class WalletFileTest(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.setup_clean_chain = True + + def run_test(self): + # test default wallet location + assert os.path.isfile(os.path.join(self.options.tmpdir, "node0", "regtest", "wallet.dat")) + + # test alternative wallet file name in datadir + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-wallet=altwallet.dat"]) + assert os.path.isfile(os.path.join(self.options.tmpdir, "node0", "regtest", "altwallet.dat")) + + # test wallet file outside datadir + tempname = os.path.join(self.options.tmpdir, "outsidewallet.dat") + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-wallet=%s" % tempname]) + assert os.path.isfile(tempname) + + # test the case where absolute path does not exist + assert not os.path.isdir("/this_directory_must_not_exist") + invalidpath = os.path.join("/this_directory_must_not_exist/", "foo.dat") + stop_node(self.nodes[0], 0) + assert_start_raises_init_error(0, "-wallet=%s" % invalidpath, + "Error: Absolute path %s does not exist") + + # relative path does not exist + invalidpath = os.path.join("wallet", "foo.dat") + assert_start_raises_init_error(0, "-wallet=%s" % invalidpath, + "Error: Relative path %s does not exist") + + # create dir and retry + os.mkdir(os.path.join(self.options.tmpdir, "node0", "regtest", "wallet")) + self.nodes[0] = start_node(0, self.options.tmpdir, ["-wallet=%s" % invalidpath]) + +if __name__ == '__main__': + WalletFileTest().main() diff --git a/depend/zcash/qa/rpc-tests/feature_zip221.py b/depend/zcash/qa/rpc-tests/feature_zip221.py new file mode 100755 index 000000000..e2e6bdcc4 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/feature_zip221.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +from test_framework.flyclient import (ZcashMMRNode, append, delete, make_root_commitment) +from test_framework.mininode import (CBlockHeader) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, + bytes_to_hex_str, + hex_str_to_bytes, + nuparams, + start_nodes, +) + +from io import BytesIO + +NULL_FIELD = "00" * 32 +CHAIN_HISTORY_ROOT_VERSION = 2010200 + +# Verify block header field 'hashLightClientRoot' is set correctly for Heartwood blocks. +class Zip221Test(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ + nuparams(BLOSSOM_BRANCH_ID, 1), + nuparams(HEARTWOOD_BRANCH_ID, 10), + nuparams(CANOPY_BRANCH_ID, 32), + nuparams(NU5_BRANCH_ID, 35), + '-nurejectoldversions=false', + ]] * self.num_nodes) + + def node_for_block(self, height): + if height >= 35: + epoch = NU5_BRANCH_ID + elif height >= 32: + epoch = CANOPY_BRANCH_ID + else: + epoch = HEARTWOOD_BRANCH_ID + + block_header = CBlockHeader() + block_header.deserialize(BytesIO(hex_str_to_bytes( + self.nodes[0].getblock(str(height), 0)))) + sapling_root = hex_str_to_bytes( + self.nodes[0].getblock(str(height))["finalsaplingroot"])[::-1] + + if height >= 35: + orchard_root = hex_str_to_bytes( + self.nodes[0].getblock(str(height))["finalorchardroot"])[::-1] + v2_data = (orchard_root, 0) + else: + v2_data = None + + return ZcashMMRNode.from_block( + block_header, height, sapling_root, 0, epoch, v2_data) + + def new_tree(self, height): + newRoot = self.node_for_block(height - 1) + assert_equal( + self.nodes[0].getblock(str(height))["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(newRoot)[::-1])) + return newRoot + + def update_tree(self, root, height): + leaf = self.node_for_block(height - 1) + root = append(root, leaf) + assert_equal( + self.nodes[0].getblock(str(height))["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(root)[::-1])) + return root + + def run_test(self): + self.nodes[0].generate(10) + self.sync_all() + + # Verify all blocks up to and including Heartwood activation set + # hashChainHistoryRoot to null. + print("Verifying blocks up to and including Heartwood activation") + blockcount = self.nodes[0].getblockcount() + assert_equal(blockcount, 10) + for height in range(0, blockcount + 1): + blk = self.nodes[0].getblock(str(height)) + assert_equal(blk["chainhistoryroot"], NULL_FIELD) + + + # Create the initial history tree, containing a single node. + root = self.node_for_block(10) + + # Generate the first block that contains a non-null chain history root. + print("Verifying first non-null chain history root") + self.nodes[0].generate(1) + self.sync_all() + + # Verify that hashChainHistoryRoot is set correctly. + assert_equal( + self.nodes[0].getblock('11')["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(root)[::-1])) + + # Generate 9 more blocks on node 0, and verify their chain history roots. + print("Mining 9 blocks on node 0") + self.nodes[0].generate(9) + self.sync_all() + + print("Verifying node 0's chain history") + for height in range(12, 21): + leaf = self.node_for_block(height - 1) + root = append(root, leaf) + assert_equal( + self.nodes[0].getblock(str(height))["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(root)[::-1])) + + # The rest of the test only applies to Heartwood-aware node versions. + # Earlier versions won't serialize chain history roots in the block + # index, and splitting the network below requires restarting the nodes. + if self.nodes[0].getnetworkinfo()["version"] < CHAIN_HISTORY_ROOT_VERSION: + print("Node's block index is not Heartwood-aware, skipping reorg test") + return + + # Split the network so we can test the effect of a reorg. + print("Splitting the network") + self.split_network() + + # Generate 10 more blocks on node 0, and verify their chain history roots. + print("Mining 10 more blocks on node 0") + self.nodes[0].generate(10) + self.sync_all() + + print("Verifying node 0's chain history") + for height in range(21, 31): + leaf = self.node_for_block(height - 1) + root = append(root, leaf) + assert_equal( + self.nodes[0].getblock(str(height))["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(root)[::-1])) + + # Generate 11 blocks on node 2. + print("Mining alternate chain on node 2") + self.nodes[2].generate(11) + self.sync_all() + + # Reconnect the nodes; node 0 will re-org to node 2's chain. + print("Re-joining the network so that node 0 reorgs") + self.join_network() + + # Verify that node 0's chain history was correctly updated. + print("Deleting orphaned blocks from the expected chain history") + for _ in range(10): + root = delete(root) + + print("Verifying that node 0 is now on node 1's chain history") + for height in range(21, 32): + leaf = self.node_for_block(height - 1) + root = append(root, leaf) + assert_equal( + self.nodes[2].getblock(str(height))["chainhistoryroot"], + bytes_to_hex_str(make_root_commitment(root)[::-1])) + + # Generate 6 blocks on node 0 to activate Canopy and NU5. + print("Mining 6 blocks on node 0") + self.nodes[0].generate(6) + self.sync_all() + + # The Canopy activation block should commit to the final Heartwood tree. + root = self.update_tree(root, 32) + + # The two blocks after Canopy activation should be a new tree. + canopyRoot = self.new_tree(33) + canopyRoot = self.update_tree(canopyRoot, 34) + + # The NU5 activation block should commit to the final Heartwood tree. + canopyRoot = self.update_tree(canopyRoot, 35) + + # The two blocks after NU5 activation should be a V2 tree. + nu5Root = self.new_tree(36) + nu5Root = self.update_tree(nu5Root, 37) + + +if __name__ == '__main__': + Zip221Test().main() diff --git a/depend/zcash/qa/rpc-tests/feature_zip239.py b/depend/zcash/qa/rpc-tests/feature_zip239.py new file mode 100755 index 000000000..6824d9ff1 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/feature_zip239.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.mininode import ( + NU5_PROTO_VERSION, + CInv, + NetworkThread, + NodeConn, + mininode_lock, + msg_getdata, + msg_mempool, + msg_reject, + uint256_from_str, +) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, + assert_false, + assert_true, + fail, + hex_str_to_bytes, + nuparams, + p2p_port, + start_node, + wait_and_assert_operationid_status, +) +from tx_expiry_helper import TestNode + +import os.path +import time + +# Test ZIP 239 behaviour before and after NU5. +class Zip239Test(BitcoinTestFramework): + def setup_nodes(self): + extra_args=[ + # Enable Canopy at height 205 to allow shielding Sprout funds first. + nuparams(BLOSSOM_BRANCH_ID, 205), + nuparams(HEARTWOOD_BRANCH_ID, 205), + nuparams(CANOPY_BRANCH_ID, 205), + nuparams(NU5_BRANCH_ID, 210), + ] + + nodes = [] + nodes.append(start_node(0, self.options.tmpdir, extra_args)) + nodes.append(start_node(1, self.options.tmpdir, extra_args)) + nodes.append(start_node(2, self.options.tmpdir, extra_args)) + nodes.append(start_node(3, self.options.tmpdir, extra_args)) + return nodes + + def cinv_for(self, txid, authDigest=None): + if authDigest is not None: + return CInv(5, txid, authDigest) + else: + return CInv(1, txid) + + def verify_inv(self, testnode, txs): + # Make sure we are synced before sending the mempool message + testnode.sync_with_ping() + + # Send p2p message "mempool" to receive contents from zcashd node in "inv" message + with mininode_lock: + testnode.last_inv = None + testnode.send_message(msg_mempool()) + + # Sync up with node after p2p messages delivered + testnode.sync_with_ping(waiting_for=lambda x: x.last_inv) + + with mininode_lock: + msg = testnode.last_inv + assert_equal(len(msg.inv), len(txs)) + + expected_invs = sorted(txs, key=lambda inv: (inv.type, inv.hash, inv.hash_aux)) + actual_invs = sorted(msg.inv, key=lambda inv: (inv.type, inv.hash, inv.hash_aux)) + + for (expected, actual) in zip(expected_invs, actual_invs): + assert_equal(expected, actual) + + def send_data_message(self, testnode, txid, authDigest=None): + # Send p2p message "getdata" to verify tx gets sent in "tx" message + getdatamsg = msg_getdata() + getdatamsg.inv = [self.cinv_for(txid, authDigest)] + with mininode_lock: + testnode.last_tx = None + testnode.last_notfound = None + testnode.send_message(getdatamsg) + + def verify_last_tx(self, testnode, txid, authDigest=None): + # Sync up with node after p2p messages delivered + testnode.sync_with_ping() + + # Verify data received in "tx" message is for tx + with mininode_lock: + assert_true(testnode.last_notfound is None, "'%r' is not None" % testnode.last_notfound) + assert_false(testnode.last_tx is None, "No tx received") + incoming_tx = testnode.last_tx.tx + incoming_tx.rehash() + assert_equal(txid, incoming_tx.sha256) + + def verify_last_notfound(self, testnode, txid, authDigest=None): + # Sync up with node after p2p messages delivered + testnode.sync_with_ping() + + # Verify data received in "notfound" message is for tx + with mininode_lock: + assert_true(testnode.last_tx is None, "'%r' is not None" % testnode.last_tx) + assert_false(testnode.last_notfound is None, "notfound not received") + assert_equal(len(testnode.last_notfound.inv), 1) + assert_equal(testnode.last_notfound.inv[0], self.cinv_for(txid, authDigest)) + + def verify_invalid_cinv(self, testnode, conn, msg_type, expected_msg): + # Send p2p message "getdata" containing an invalid CInv message + getdatamsg = msg_getdata() + getdatamsg.inv = [CInv(msg_type, 1)] + with mininode_lock: + testnode.last_tx = None + testnode.last_notfound = None + testnode.send_message(getdatamsg) + + # Sync up with node after p2p messages delivered + testnode.sync_with_ping() + + # Verify that we get a reject message + expected = msg_reject() + expected.message = b"getdata" + expected.code = msg_reject.REJECT_MALFORMED + expected.reason = b"error parsing message" + assert_equal(conn.rejectMessage, expected) + + # Verify that we see the expected error in the debug log of node 0 + log_path = os.path.join(self.options.tmpdir, 'node0', 'regtest', 'debug.log') + with open(log_path, 'r', encoding='utf-8') as log_file: + log_content = log_file.read() + + if expected_msg not in log_content: + raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + log_content) + + def verify_disconnected(self, testnode, timeout=30): + sleep_time = 0.05 + while timeout > 0: + with mininode_lock: + if testnode.conn_closed: + return + time.sleep(sleep_time) + timeout -= sleep_time + fail("Should have received pong") + + def run_test(self): + # Set up test nodes. + # - test_nodes[0] will only request v4 transactions + # - test_nodes[1] will only request v5 transactions + # - test_nodes[2] will test invalid v4 request using MSG_WTXID + # - test_nodes[3] will test invalid v5 request using MSG_TX + test_nodes = [] + connections = [] + + for i in range(4): + test_nodes.append(TestNode()) + connections.append(NodeConn( + '127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i], + protocol_version=NU5_PROTO_VERSION)) + test_nodes[i].add_connection(connections[i]) + + NetworkThread().start() # Start up network handling in another thread + [x.wait_for_verack() for x in test_nodes] + + net_version = self.nodes[0].getnetworkinfo()["protocolversion"] + if net_version < NU5_PROTO_VERSION: + # Sending a getdata message containing a MSG_WTX CInv message type + # results in a reject message. + self.verify_invalid_cinv( + test_nodes[0], connections[0], 5, + "Negotiated protocol version does not support CInv message type MSG_WTX", + ) + + # Sending a getdata message containing an invalid CInv message type + # results in a reject message. + self.verify_invalid_cinv( + test_nodes[1], connections[1], 0xffff, "Unknown CInv message type") + + print("Node's block index is not NU5-aware, skipping remaining tests") + return + + # Load funds into the Sprout address + sproutzaddr = self.nodes[0].z_getnewaddress('sprout') + result = self.nodes[2].z_shieldcoinbase("*", sproutzaddr, 0) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Activate NU5. Block height after this is 210. + self.nodes[0].generate(9) + self.sync_all() + + # Add v4 transaction to the mempool. + node1_taddr = self.nodes[1].getnewaddress() + opid = self.nodes[0].z_sendmany(sproutzaddr, [{ + 'address': node1_taddr, + 'amount': 1, + }]) + v4_txid = uint256_from_str(hex_str_to_bytes( + wait_and_assert_operationid_status(self.nodes[0], opid) + )[::-1]) + + # Add v5 transaction to the mempool. + v5_txid = self.nodes[0].sendtoaddress(node1_taddr, 1, "", "", True) + v5_tx = self.nodes[0].getrawtransaction(v5_txid, 1) + assert_equal(v5_tx['version'], 5) + v5_txid = uint256_from_str(hex_str_to_bytes(v5_txid)[::-1]) + v5_auth_digest = uint256_from_str(hex_str_to_bytes(v5_tx['authdigest'])[::-1]) + + # Wait for the mempools to sync. + self.sync_all() + + # + # inv + # + + # On a mempool request, nodes should return an inv message containing: + # - the v4 tx, with type MSG_TX. + # - the v5 tx, with type MSG_WTX. + for testnode in test_nodes: + self.verify_inv(testnode, [ + self.cinv_for(v4_txid), + self.cinv_for(v5_txid, v5_auth_digest), + ]) + + # + # getdata + # + + # We can request a v4 transaction with MSG_TX. + self.send_data_message(test_nodes[0], v4_txid) + self.verify_last_tx(test_nodes[0], v4_txid) + + # We can request a v5 transaction with MSG_WTX. + self.send_data_message(test_nodes[1], v5_txid, v5_auth_digest) + self.verify_last_tx(test_nodes[1], v5_txid, v5_auth_digest) + + # Requesting with a different authDigest results in a notfound. + self.send_data_message(test_nodes[1], v5_txid, 1) + self.verify_last_notfound(test_nodes[1], v5_txid, 1) + + # Requesting a v4 transaction with MSG_WTX causes a disconnect. + self.send_data_message(test_nodes[2], v4_txid, (1 << 256) - 1) + self.verify_disconnected(test_nodes[2]) + + # Requesting a v5 transaction with MSG_TX causes a disconnect. + self.send_data_message(test_nodes[3], v5_txid) + self.verify_disconnected(test_nodes[3]) + + # Sending a getdata message containing an invalid CInv message type + # results in a reject message. + self.verify_invalid_cinv( + test_nodes[0], connections[0], 0xffff, "Unknown CInv message type") + + [c.disconnect_node() for c in connections] + +if __name__ == '__main__': + Zip239Test().main() diff --git a/depend/zcash/qa/rpc-tests/feature_zip244_blockcommitments.py b/depend/zcash/qa/rpc-tests/feature_zip244_blockcommitments.py new file mode 100755 index 000000000..a0a5bde45 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/feature_zip244_blockcommitments.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +from test_framework.blocktools import derive_block_commitments_hash +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + CANOPY_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, + bytes_to_hex_str, + hex_str_to_bytes, + nuparams, + start_nodes, +) + +TERMINATOR = b'\x00' * 32 + +# Verify block header field 'hashLightClientRoot' is set correctly for NU5 blocks. +class AuthDataRootTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ + nuparams(BLOSSOM_BRANCH_ID, 201), + nuparams(HEARTWOOD_BRANCH_ID, 201), + nuparams(CANOPY_BRANCH_ID, 201), + nuparams(NU5_BRANCH_ID, 205), + '-nurejectoldversions=false', + ]] * self.num_nodes) + + def run_test(self): + # Generate a block so we are on Canopy rules. + self.nodes[0].generate(2) + self.sync_all() + + # For blocks prior to NU5 activation, the hashBlockCommitments field of + # the block header contains the root of the ZIP 221 history tree. + for i in range(3): + block_before = self.nodes[0].getblock('%d' % (202 + i)) + assert_equal(block_before['blockcommitments'], block_before['chainhistoryroot']) + + self.nodes[0].generate(1) + self.sync_all() + + # From NU5 activation, the hashBlockCommitments field of the block + # header contains a hash of various block commitments (per ZIP 244). + for i in range(2): + block_after = self.nodes[0].getblock('%d' % (205 + i)) + block_commitments = bytes_to_hex_str(derive_block_commitments_hash( + hex_str_to_bytes(block_after['chainhistoryroot'])[::-1], + hex_str_to_bytes(block_after['authdataroot'])[::-1], + )[::-1]) + assert_equal(block_after['blockcommitments'], block_commitments) + + self.nodes[0].generate(1) + self.sync_all() + + +if __name__ == '__main__': + AuthDataRootTest().main() diff --git a/depend/zcash/qa/rpc-tests/finalsaplingroot.py b/depend/zcash/qa/rpc-tests/finalsaplingroot.py new file mode 100755 index 000000000..b028947c0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/finalsaplingroot.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + connect_nodes_bi, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +SPROUT_TREE_EMPTY_ROOT = "59d2cde5e65c1414c32ba54f0fe4bdb3d67618125286e6a191317917c812c6d7" +SAPLING_TREE_EMPTY_ROOT = "3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb" +ORCHARD_TREE_EMPTY_ROOT = "2fd8e51a03d9bbe2dd809831b1497aeb68a6e37ddf707ced4aa2d8dff13529ae" +NULL_FIELD = "0000000000000000000000000000000000000000000000000000000000000000" + +# Verify block header field 'hashFinalSaplingRoot' (returned in rpc as 'finalsaplingroot') +# is updated when Sapling transactions with outputs (commitments) are mined into a block. +class FinalSaplingRootTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = True + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ + '-txindex', # Avoid JSONRPC error: No information available about transaction + nuparams(NU5_BRANCH_ID, 210), + '-debug', + ]] * self.num_nodes) + connect_nodes_bi(self.nodes,0,1) + self.is_network_split=False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(200) + self.sync_all() + + # Verify genesis block contains null field for what is now called the final sapling root field. + blk = self.nodes[0].getblock("0") + assert_equal(blk["finalsaplingroot"], NULL_FIELD) + treestate = self.nodes[0].z_gettreestate("0") + assert_equal(treestate["height"], 0) + assert_equal(treestate["hash"], self.nodes[0].getblockhash(0)) + + assert_equal(treestate["sprout"]["commitments"]["finalRoot"], SPROUT_TREE_EMPTY_ROOT) + assert_equal(treestate["sprout"]["commitments"]["finalState"], "000000") + assert "skipHash" not in treestate["sprout"] + + assert_equal(treestate["sapling"]["commitments"]["finalRoot"], NULL_FIELD) + # There is no sapling state tree yet, and trying to find it in an earlier + # block won't succeed (we're at genesis block), so skipHash is absent. + assert "finalState" not in treestate["sapling"] + assert "skipHash" not in treestate["sapling"] + + assert_equal(treestate["orchard"]["commitments"]["finalRoot"], NULL_FIELD) + # There is no orchard state tree yet, and trying to find it in an earlier + # block won't succeed (we're at genesis block), so skipHash is absent. + assert "finalState" not in treestate["orchard"] + assert "skipHash" not in treestate["orchard"] + + # Verify all generated blocks contain the empty root of the Sapling tree. + blockcount = self.nodes[0].getblockcount() + for height in range(1, blockcount + 1): + blk = self.nodes[0].getblock(str(height)) + assert_equal(blk["finalsaplingroot"], SAPLING_TREE_EMPTY_ROOT) + + treestate = self.nodes[0].z_gettreestate(str(height)) + assert_equal(treestate["height"], height) + assert_equal(treestate["hash"], self.nodes[0].getblockhash(height)) + + assert "skipHash" not in treestate["sprout"] + assert_equal(treestate["sprout"]["commitments"]["finalRoot"], SPROUT_TREE_EMPTY_ROOT) + assert_equal(treestate["sprout"]["commitments"]["finalState"], "000000") + + + assert "skipHash" not in treestate["sapling"] + assert_equal(treestate["sapling"]["commitments"]["finalRoot"], SAPLING_TREE_EMPTY_ROOT) + assert_equal(treestate["sapling"]["commitments"]["finalState"], "000000") + + assert "skipHash" not in treestate["orchard"] + assert_equal(treestate["orchard"]["commitments"]["finalRoot"], NULL_FIELD) + + # Node 0 shields some funds + taddr0 = get_coinbase_address(self.nodes[0]) + saplingAddr0 = self.nodes[0].z_getnewaddress('sapling') + recipients = [] + recipients.append({"address": saplingAddr0, "amount": Decimal('20')}) + myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify the final Sapling root has changed + blk = self.nodes[0].getblock("201") + root = blk["finalsaplingroot"] + assert root is not SAPLING_TREE_EMPTY_ROOT + assert root is not NULL_FIELD + + # Verify there is a Sapling output description (its commitment was added to tree) + result = self.nodes[0].getrawtransaction(mytxid, 1) + assert_equal(len(result["vShieldedOutput"]), 1) + + # Since there is a now sapling shielded input in the blockchain, + # the sapling values should have changed + new_treestate = self.nodes[0].z_gettreestate(str(-1)) + assert_equal(new_treestate["sapling"]["commitments"]["finalRoot"], root) + assert_equal(new_treestate["sprout"], treestate["sprout"]) + assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"] + assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"] + assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64) + assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 70) + treestate = new_treestate + + # Mine an empty block and verify the final Sapling root does not change + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(root, self.nodes[0].getblock("202")["finalsaplingroot"]) + + # Mine a block with a transparent tx and verify the final Sapling root does not change + taddr1 = self.nodes[1].getnewaddress() + self.nodes[0].sendtoaddress(taddr1, Decimal("1.23")) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(len(self.nodes[0].getblock("203")["tx"]), 2) + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal("1.23")) + assert_equal(root, self.nodes[0].getblock("203")["finalsaplingroot"]) + + # Mine a block with a Sprout shielded tx and verify the final Sapling root does not change + zaddr1 = self.nodes[1].z_getnewaddress('sprout') + result = self.nodes[0].z_shieldcoinbase(taddr0, zaddr1, 0, 1) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(len(self.nodes[0].getblock("204")["tx"]), 2) + assert_equal(self.nodes[1].z_getbalance(zaddr1), Decimal("10")) + assert_equal(root, self.nodes[0].getblock("204")["finalsaplingroot"]) + + new_treestate = self.nodes[0].z_gettreestate(str(-1)) + assert_equal(new_treestate["sapling"]["commitments"]["finalRoot"], root) + assert_equal(new_treestate["sapling"], treestate["sapling"]) + assert new_treestate["sprout"]["commitments"]["finalRoot"] != treestate["sprout"]["commitments"]["finalRoot"] + assert new_treestate["sprout"]["commitments"]["finalState"] != treestate["sprout"]["commitments"]["finalState"] + assert_equal(len(new_treestate["sprout"]["commitments"]["finalRoot"]), 64) + assert_equal(len(new_treestate["sprout"]["commitments"]["finalState"]), 134) + treestate = new_treestate + + # Mine a block with a Sapling shielded recipient and verify the final Sapling root changes + saplingAddr1 = self.nodes[1].z_getnewaddress("sapling") + recipients = [] + recipients.append({"address": saplingAddr1, "amount": Decimal('12.34')}) + myopid = self.nodes[0].z_sendmany(saplingAddr0, recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(len(self.nodes[0].getblock("205")["tx"]), 2) + assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal("12.34")) + assert root is not self.nodes[0].getblock("205")["finalsaplingroot"] + + # Verify there is a Sapling output description (its commitment was added to tree) + result = self.nodes[0].getrawtransaction(mytxid, 1) + assert_equal(len(result["vShieldedOutput"]), 2) # there is Sapling shielded change + + new_treestate = self.nodes[0].z_gettreestate(str(-1)) + assert_equal(new_treestate["sprout"], treestate["sprout"]) + assert new_treestate["sapling"]["commitments"]["finalRoot"] != treestate["sapling"]["commitments"]["finalRoot"] + assert new_treestate["sapling"]["commitments"]["finalState"] != treestate["sapling"]["commitments"]["finalState"] + assert_equal(len(new_treestate["sapling"]["commitments"]["finalRoot"]), 64) + assert_equal(len(new_treestate["sapling"]["commitments"]["finalState"]), 136) + treestate = new_treestate + + # Mine a block with a Sapling shielded sender and transparent recipient and verify the final Sapling root doesn't change + taddr2 = self.nodes[0].getnewaddress() + recipients = [] + recipients.append({"address": taddr2, "amount": Decimal('12.34')}) + myopid = self.nodes[1].z_sendmany(saplingAddr1, recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[1], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(len(self.nodes[0].getblock("206")["tx"]), 2) + assert_equal(self.nodes[0].z_getbalance(taddr2), Decimal("12.34")) + + blk = self.nodes[0].getblock("206") + root = blk["finalsaplingroot"] + assert_equal(root, self.nodes[0].getblock("205")["finalsaplingroot"]) + + new_treestate = self.nodes[0].z_gettreestate(str(-1)) + assert_equal(new_treestate["sprout"], treestate["sprout"]) + assert_equal(new_treestate["sapling"], treestate["sapling"]) + + # Activate NU5; more testing should be added once we can mine orchard transactions. + self.sync_all() + self.nodes[0].generate(4) + self.sync_all() + new_treestate = self.nodes[0].z_gettreestate(str(-1)) + + # sprout and sapling results should not change + assert_equal(new_treestate["sprout"], treestate["sprout"]) + assert_equal(new_treestate["sapling"], treestate["sapling"]) + + assert "skipHash" not in treestate["orchard"] + assert_equal(new_treestate["orchard"]["commitments"]["finalRoot"], ORCHARD_TREE_EMPTY_ROOT) + assert_equal(new_treestate["orchard"]["commitments"]["finalState"], "000000") + pass + + +if __name__ == '__main__': + FinalSaplingRootTest().main() diff --git a/depend/zcash/qa/rpc-tests/forknotify.py b/depend/zcash/qa/rpc-tests/forknotify.py new file mode 100755 index 000000000..b97d1fb77 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/forknotify.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test -alertnotify +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_node, connect_nodes + +import os + +class ForkNotifyTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False + + alert_filename = None # Set by setup_network + + def setup_network(self): + self.nodes = [] + self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") + with open(self.alert_filename, 'w', encoding='utf8'): + pass # Just open then close to create zero-length file + self.nodes.append(start_node(0, self.options.tmpdir, + ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) + # Node1 mines block.version=211 blocks + self.nodes.append(start_node(1, self.options.tmpdir, + ["-blockversion=211"])) + connect_nodes(self.nodes[1], 0) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + # Mine 51 up-version blocks + self.nodes[1].generate(51) + self.sync_all() + # -alertnotify should trigger on the 51'st, + # but mine and sync another to give + # -alertnotify time to write + self.nodes[1].generate(1) + self.sync_all() + + with open(self.alert_filename, 'r', encoding='utf8') as f: + alert_text = f.read() + + if len(alert_text) == 0: + raise AssertionError("-alertnotify did not warn of up-version blocks") + + # Mine more up-version blocks, should not get more alerts: + self.nodes[1].generate(1) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + with open(self.alert_filename, 'r', encoding='utf8') as f: + alert_text2 = f.read() + + if alert_text != alert_text2: + raise AssertionError("-alertnotify excessive warning of up-version blocks") + +if __name__ == '__main__': + ForkNotifyTest().main() diff --git a/depend/zcash/qa/rpc-tests/framework.py b/depend/zcash/qa/rpc-tests/framework.py new file mode 100755 index 000000000..7a6765160 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/framework.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_raises, + connect_nodes, + start_node, + check_node_log, +) + +class FrameworkTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = True + + def start_node_with(self, index, extra_args=[]): + args = [] + return start_node(index, self.options.tmpdir, args + extra_args) + + def setup_network(self, split=False): + self.nodes = [] + self.nodes.append(self.start_node_with(0)) + self.nodes.append(self.start_node_with(1)) + connect_nodes(self.nodes[1], 0) + self.is_network_split=False + self.sync_all() + + def run_test (self): + + # Test the check_node_log utility function + string_to_find = "Zcash version" + check_node_log(self, 1, string_to_find) + + # Node 1 was stopped to check the logs, need to be restarted + self.nodes[1] = self.start_node_with(1, []) + connect_nodes(self.nodes[1], 0) + + assert_raises(AssertionError, check_node_log, self, 1, "Will not be found") + + # Need to start node 1 before leaving the test + self.nodes[1] = self.start_node_with(1, []) + connect_nodes(self.nodes[1], 0) + + +if __name__ == '__main__': + FrameworkTest().main() diff --git a/depend/zcash/qa/rpc-tests/fundrawtransaction.py b/depend/zcash/qa/rpc-tests/fundrawtransaction.py new file mode 100755 index 000000000..f75470306 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/fundrawtransaction.py @@ -0,0 +1,606 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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, assert_greater_than, \ + start_nodes, connect_nodes_bi, stop_nodes, \ + wait_bitcoinds + +from decimal import Decimal + +# Create one-input, one-output, no-fee transaction: +class RawTransactionsTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-experimentalfeatures', '-developerencryptwallet']] * 4) + + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + + self.is_network_split=False + self.sync_all() + + def run_test(self): + print("Mining blocks...") + + min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] + # if the fee's positive delta is higher than this value tests will fail, + # neg. delta always fail the tests. + # The size of the signature of every input may be at most 2 bytes larger + # than a minimum sized signature. + + # = 2 bytes * minRelayTxFeePerByte + feeTolerance = max(2 * min_relay_tx_fee/1000, Decimal("0.00000001")) + + self.nodes[2].generate(1) + self.sync_all() + self.nodes[0].generate(201) + self.sync_all() + + watchonly_address = self.nodes[0].getnewaddress() + watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"] + watchonly_amount = Decimal(200) + self.nodes[3].importpubkey(watchonly_pubkey, "", True) + watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount) + self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10) + + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + ############### + # simple test # + ############### + inputs = [ ] + outputs = { self.nodes[0].getnewaddress() : 1.0 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs + + ############################## + # simple test with two coins # + ############################## + inputs = [ ] + outputs = { self.nodes[0].getnewaddress() : 2.2 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs + + ############################## + # simple test with two coins # + ############################## + inputs = [ ] + outputs = { self.nodes[0].getnewaddress() : 2.6 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + assert_equal(len(dec_tx['vin']) > 0, True) + assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') + + + ################################ + # simple test with two outputs # + ################################ + inputs = [ ] + outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + for out in dec_tx['vout']: + totalOut += out['value'] + + assert_equal(len(dec_tx['vin']) > 0, True) + assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '') + + + ######################################################################### + # test a fundrawtransaction with a VIN greater than the required amount # + ######################################################################### + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 5.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] + outputs = { self.nodes[0].getnewaddress() : Decimal('1.0') } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + for out in dec_tx['vout']: + totalOut += out['value'] + + assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee + + + ##################################################################### + # test a fundrawtransaction with which will not get a change output # + ##################################################################### + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 5.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] + outputs = { self.nodes[0].getnewaddress() : Decimal('5.0') - fee - feeTolerance } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + for out in dec_tx['vout']: + totalOut += out['value'] + + assert_equal(rawtxfund['changepos'], -1) + assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee + + + ######################################################################### + # test a fundrawtransaction with a VIN smaller than the required amount # + ######################################################################### + utx = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 1.0: + utx = aUtx + break + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}] + outputs = { self.nodes[0].getnewaddress() : Decimal('1.0') } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + + # 4-byte version + 4-byte versionGroupId + 1-byte vin count + 36-byte prevout then script_len + rawtx = rawtx[:90] + "0100" + rawtx[92:] + + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex']) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + matchingOuts = 0 + for i, out in enumerate(dec_tx['vout']): + totalOut += out['value'] + if out['scriptPubKey']['addresses'][0] in outputs: + matchingOuts+=1 + else: + assert_equal(i, rawtxfund['changepos']) + + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + assert_equal("00", dec_tx['vin'][0]['scriptSig']['hex']) + + assert_equal(matchingOuts, 1) + assert_equal(len(dec_tx['vout']), 2) + + + ########################################### + # test a fundrawtransaction with two VINs # + ########################################### + utx = False + utx2 = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 1.0: + utx = aUtx + if aUtx['amount'] == 5.0: + utx2 = aUtx + + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] + outputs = { self.nodes[0].getnewaddress() : 6.0 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + matchingOuts = 0 + for out in dec_tx['vout']: + totalOut += out['value'] + if out['scriptPubKey']['addresses'][0] in outputs: + matchingOuts+=1 + + assert_equal(matchingOuts, 1) + assert_equal(len(dec_tx['vout']), 2) + + matchingIns = 0 + for vinOut in dec_tx['vin']: + for vinIn in inputs: + if vinIn['txid'] == vinOut['txid']: + matchingIns+=1 + + assert_equal(matchingIns, 2) #we now must see two vins identical to vins given as params + + ######################################################### + # test a fundrawtransaction with two VINs and two vOUTs # + ######################################################### + utx = False + utx2 = False + listunspent = self.nodes[2].listunspent() + for aUtx in listunspent: + if aUtx['amount'] == 1.0: + utx = aUtx + if aUtx['amount'] == 5.0: + utx2 = aUtx + + + assert_equal(utx!=False, True) + + inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ] + outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + assert_equal(utx['txid'], dec_tx['vin'][0]['txid']) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + fee = rawtxfund['fee'] + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + totalOut = 0 + matchingOuts = 0 + for out in dec_tx['vout']: + totalOut += out['value'] + if out['scriptPubKey']['addresses'][0] in outputs: + matchingOuts+=1 + + assert_equal(matchingOuts, 2) + assert_equal(len(dec_tx['vout']), 3) + + ############################################## + # test a fundrawtransaction with invalid vin # + ############################################## + listunspent = self.nodes[2].listunspent() + inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin! + outputs = { self.nodes[0].getnewaddress() : 1.0} + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + + errorString = "" + try: + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + except JSONRPCException as e: + errorString = e.error['message'] + + assert_equal("Insufficient" in errorString, True) + + + + ############################################################ + #compare fee of a standard pubkeyhash transaction + inputs = [] + outputs = {self.nodes[1].getnewaddress():1.1} + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[0].fundrawtransaction(rawTx) + + #create same transaction over sendtoaddress + txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1) + signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] + + #compare fee + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) + assert(feeDelta >= 0 and feeDelta <= feeTolerance) + ############################################################ + + ############################################################ + #compare fee of a standard pubkeyhash transaction with multiple outputs + inputs = [] + outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3} + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[0].fundrawtransaction(rawTx) + #create same transaction over sendtoaddress + txId = self.nodes[0].sendmany("", outputs) + signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] + + #compare fee + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) + assert(feeDelta >= 0 and feeDelta <= feeTolerance) + ############################################################ + + + ############################################################ + #compare fee of a 2of2 multisig p2sh transaction + + # create 2of2 addr + addr1 = self.nodes[1].getnewaddress() + addr2 = self.nodes[1].getnewaddress() + + addr1Obj = self.nodes[1].validateaddress(addr1) + addr2Obj = self.nodes[1].validateaddress(addr2) + + mSigObj = self.nodes[1].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + + inputs = [] + outputs = {mSigObj:1.1} + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[0].fundrawtransaction(rawTx) + + #create same transaction over sendtoaddress + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) + signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] + + #compare fee + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) + assert(feeDelta >= 0 and feeDelta <= feeTolerance) + ############################################################ + + + ############################################################ + #compare fee of a standard pubkeyhash transaction + + # create 4of5 addr + addr1 = self.nodes[1].getnewaddress() + addr2 = self.nodes[1].getnewaddress() + addr3 = self.nodes[1].getnewaddress() + addr4 = self.nodes[1].getnewaddress() + addr5 = self.nodes[1].getnewaddress() + + addr1Obj = self.nodes[1].validateaddress(addr1) + addr2Obj = self.nodes[1].validateaddress(addr2) + addr3Obj = self.nodes[1].validateaddress(addr3) + addr4Obj = self.nodes[1].validateaddress(addr4) + addr5Obj = self.nodes[1].validateaddress(addr5) + + mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']]) + + inputs = [] + outputs = {mSigObj:1.1} + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[0].fundrawtransaction(rawTx) + + #create same transaction over sendtoaddress + txId = self.nodes[0].sendtoaddress(mSigObj, 1.1) + signedFee = self.nodes[0].getrawmempool(True)[txId]['fee'] + + #compare fee + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) + assert(feeDelta >= 0 and feeDelta <= feeTolerance) + ############################################################ + + + ############################################################ + # spend a 2of2 multisig transaction over fundraw + + # create 2of2 addr + addr1 = self.nodes[2].getnewaddress() + addr2 = self.nodes[2].getnewaddress() + + addr1Obj = self.nodes[2].validateaddress(addr1) + addr2Obj = self.nodes[2].validateaddress(addr2) + + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + + + # send 1.2 BTC to msig addr + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + oldBalance = self.nodes[1].getbalance() + inputs = [] + outputs = {self.nodes[1].getnewaddress():1.1} + rawTx = self.nodes[2].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[2].fundrawtransaction(rawTx) + + signedTx = self.nodes[2].signrawtransaction(fundedTx['hex']) + txId = self.nodes[2].sendrawtransaction(signedTx['hex']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # make sure funds are received at node1 + assert_equal(oldBalance+Decimal('1.10000000'), self.nodes[1].getbalance()) + + ############################################################ + # locked wallet test + self.nodes[1].encryptwallet("test") + self.nodes.pop(1) + stop_nodes(self.nodes) + wait_bitcoinds() + + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + error = False + try: + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2) + except: + error = True + assert(error) + + oldBalance = self.nodes[0].getbalance() + + inputs = [] + outputs = {self.nodes[0].getnewaddress():1.1} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + + #now we need to unlock + self.nodes[1].walletpassphrase("test", 100) + signedTx = self.nodes[1].signrawtransaction(fundedTx['hex']) + txId = self.nodes[1].sendrawtransaction(signedTx['hex']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # make sure funds are received at node1 + assert_equal(oldBalance+Decimal('11.10000000'), self.nodes[0].getbalance()) + + + ############################################### + # multiple (~19) inputs tx test | Compare fee # + ############################################### + + #empty node1, send some small coins from node0 to node1 + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + for i in range(0,20): + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + #fund a tx with ~20 small inputs + inputs = [] + outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + + #create same transaction over sendtoaddress + txId = self.nodes[1].sendmany("", outputs) + signedFee = self.nodes[1].getrawmempool(True)[txId]['fee'] + + #compare fee + feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee) + assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs + + + ############################################# + # multiple (~19) inputs tx test | sign/send # + ############################################# + + #again, empty node1, send some small coins from node0 to node1 + self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + for i in range(0,20): + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + #fund a tx with ~20 small inputs + oldBalance = self.nodes[0].getbalance() + + inputs = [] + outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04} + rawTx = self.nodes[1].createrawtransaction(inputs, outputs) + fundedTx = self.nodes[1].fundrawtransaction(rawTx) + fundedAndSignedTx = self.nodes[1].signrawtransaction(fundedTx['hex']) + txId = self.nodes[1].sendrawtransaction(fundedAndSignedTx['hex']) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(oldBalance+Decimal('10.19000000'), self.nodes[0].getbalance()) #0.19+block reward + + ##################################################### + # test fundrawtransaction with OP_RETURN and no vin # + ##################################################### + + rawtx = "0100000000010000000000000000066a047465737400000000" + dec_tx = self.nodes[2].decoderawtransaction(rawtx) + + assert_equal(len(dec_tx['vin']), 0) + assert_equal(len(dec_tx['vout']), 1) + + rawtxfund = self.nodes[2].fundrawtransaction(rawtx) + dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex']) + + assert_greater_than(len(dec_tx['vin']), 0) # at least one vin + assert_equal(len(dec_tx['vout']), 2) # one change output added + + + ################################################## + # test a fundrawtransaction using only watchonly # + ################################################## + + inputs = [] + outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2} + rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + + result = self.nodes[3].fundrawtransaction(rawtx, True) + res_dec = self.nodes[0].decoderawtransaction(result["hex"]) + assert_equal(len(res_dec["vin"]), 1) + assert_equal(res_dec["vin"][0]["txid"], watchonly_txid) + + assert_equal("fee" in result.keys(), True) + assert_greater_than(result["changepos"], -1) + + ############################################################### + # test fundrawtransaction using the entirety of watched funds # + ############################################################### + + inputs = [] + outputs = {self.nodes[2].getnewaddress() : watchonly_amount} + rawtx = self.nodes[3].createrawtransaction(inputs, outputs) + + result = self.nodes[3].fundrawtransaction(rawtx, True) + res_dec = self.nodes[0].decoderawtransaction(result["hex"]) + assert_equal(len(res_dec["vin"]), 2) + assert(res_dec["vin"][0]["txid"] == watchonly_txid or res_dec["vin"][1]["txid"] == watchonly_txid) + + assert_greater_than(result["fee"], 0) + assert_greater_than(result["changepos"], -1) + assert_equal(result["fee"] + res_dec["vout"][result["changepos"]]["value"], watchonly_amount / 10) + + signedtx = self.nodes[3].signrawtransaction(result["hex"]) + assert(not signedtx["complete"]) + signedtx = self.nodes[0].signrawtransaction(signedtx["hex"]) + assert(signedtx["complete"]) + self.nodes[0].sendrawtransaction(signedtx["hex"]) + + +if __name__ == '__main__': + RawTransactionsTest().main() diff --git a/depend/zcash/qa/rpc-tests/getblocktemplate.py b/depend/zcash/qa/rpc-tests/getblocktemplate.py new file mode 100755 index 000000000..ac2240b67 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/getblocktemplate.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from io import BytesIO +import codecs +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + get_coinbase_address, + hex_str_to_bytes, + nuparams, + nustr, + start_nodes, + wait_and_assert_operationid_status, +) +from test_framework.mininode import ( + CTransaction, +) +from test_framework.blocktools import ( + create_block +) +from decimal import Decimal + +class GetBlockTemplateTest(BitcoinTestFramework): + ''' + Test getblocktemplate, ensure that a block created from its result + can be submitted and accepted. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self, split=False): + args = [ + nuparams(CANOPY_BRANCH_ID, 115), + nuparams(NU5_BRANCH_ID, 130), + ] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [args] * self.num_nodes) + self.is_network_split = False + self.node = self.nodes[0] + + def add_nu5_v4_tx_to_mempool(self): + node = self.node + # sprout to transparent (v4) + recipients = [{"address": self.transparent_addr, "amount": Decimal('0.1')}] + myopid = node.z_sendmany(self.sprout_addr, recipients, 1) + wait_and_assert_operationid_status(node, myopid) + + def add_nu5_v5_tx_to_mempool(self): + node = self.node + recipients = [{"address": self.unified_addr, "amount": Decimal('9.99999')}] + myopid = node.z_sendmany(get_coinbase_address(node), recipients, 1, Decimal('0.00001'), 'AllowRevealedSenders') + wait_and_assert_operationid_status(node, myopid) + + def add_transparent_tx_to_mempool(self): + node = self.node + # transparent to transparent (v5 after nu5) + outputs = {self.transparent_addr: 0.1} + node.sendmany('', outputs) + + def gbt_submitblock(self, nu5_active): + node = self.node + mempool_tx_list = node.getrawmempool() + + gbt = node.getblocktemplate() + + # make sure no transactions were left out (or added) + assert_equal(len(mempool_tx_list), len(gbt['transactions'])) + assert_equal(set(mempool_tx_list), set([tx['hash'] for tx in gbt['transactions']])) + + prevhash = int(gbt['previousblockhash'], 16) + nTime = gbt['mintime'] + nBits = int(gbt['bits'], 16) + + if nu5_active: + blockcommitmentshash = int(gbt['defaultroots']['blockcommitmentshash'], 16) + else: + blockcommitmentshash = int(gbt['defaultroots']['chainhistoryroot'], 16) + assert 'blockcommitmentshash' not in gbt['defaultroots'] + # Confirm that the legacy fields match this default value. + assert_equal(blockcommitmentshash, int(gbt['blockcommitmentshash'], 16)) + assert_equal(blockcommitmentshash, int(gbt['lightclientroothash'], 16)) + assert_equal(blockcommitmentshash, int(gbt['finalsaplingroothash'], 16)) + + f = BytesIO(hex_str_to_bytes(gbt['coinbasetxn']['data'])) + coinbase = CTransaction() + coinbase.deserialize(f) + coinbase.calc_sha256() + assert_equal(coinbase.hash, gbt['coinbasetxn']['hash']) + assert_equal(coinbase.auth_digest_hex, gbt['coinbasetxn']['authdigest']) + + block = create_block(prevhash, coinbase, nTime, nBits, blockcommitmentshash) + + # copy the non-coinbase transactions from the block template to the block + for gbt_tx in gbt['transactions']: + f = BytesIO(hex_str_to_bytes(gbt_tx['data'])) + tx = CTransaction() + tx.deserialize(f) + tx.calc_sha256() + assert_equal(tx.hash, gbt_tx['hash']) + assert_equal(tx.auth_digest_hex, node.getrawtransaction(tx.hash, 1)['authdigest']) + block.vtx.append(tx) + block.hashMerkleRoot = int(gbt['defaultroots']['merkleroot'], 16) + assert_equal(block.hashMerkleRoot, block.calc_merkle_root(), "merkleroot") + assert_equal(len(block.vtx), len(gbt['transactions']) + 1, "number of transactions") + assert_equal(block.hashPrevBlock, int(gbt['previousblockhash'], 16), "prevhash") + if nu5_active: + block.hashAuthDataRoot = int(gbt['defaultroots']['authdataroot'], 16) + assert_equal(block.hashAuthDataRoot, block.calc_auth_data_root(), "authdataroot") + else: + assert 'authdataroot' not in gbt['defaultroots'] + block.solve() + block.calc_sha256() + + submitblock_reply = node.submitblock(codecs.encode(block.serialize(), 'hex_codec')) + assert_equal(None, submitblock_reply) + assert_equal(block.hash, node.getbestblockhash()) + # Wait until the wallet has been notified of all blocks, so that it doesn't try to + # double-spend transparent coins in subsequent test phases. + self.sync_all() + + def run_test(self): + node = self.node + + # Generate Sprout funds before Canopy activates; using the Sprout address will + # force the generation of v4 transactions from NU5. + print("Generating pre-Canopy blocks to create sprout funds") + # coinbase only becomes mature after 100 blocks, so make one mature. + node.generate(105) + + self.sprout_addr = node.z_getnewaddress('sprout') + myopid = node.z_shieldcoinbase('*', self.sprout_addr)['opid'] + wait_and_assert_operationid_status(node, myopid) + + self.transparent_addr = node.getnewaddress() + account = node.z_getnewaccount()['account'] + self.unified_addr = node.z_getaddressforaccount(account)['address'] + node.generate(15) + + # at height 120, NU5 is not active + assert_equal(node.getblockchaininfo()['upgrades'][nustr(NU5_BRANCH_ID)]['status'], 'pending') + + print("Testing getblocktemplate for pre-NU5") + + # Only the coinbase; this covers the case where the Merkle root + # is equal to the coinbase txid. + print("- only coinbase") + self.gbt_submitblock(False) + + # Adding one transaction triggering a single Merkle digest. + print("- one transaction (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(False) + + # Adding two transactions to trigger hash Merkle root edge case. + print("- two transactions (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(False) + + # Activate NU5, repeat the above cases + node.generate(7) + assert_equal(node.getblockchaininfo()['upgrades'][nustr(NU5_BRANCH_ID)]['status'], 'active') + + print("Testing getblocktemplate for post-NU5") + + # Only the coinbase; this covers the case where the block authdata root + # is equal to the coinbase authdata + print("- only coinbase") + self.gbt_submitblock(True) + + # Adding one transaction triggering a single Merkle digest. + print("- one transaction (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + # Adding two transactions to trigger hash Merkle root edge case. + print("- two transactions (plus coinbase)") + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + # Adding both v4 and v5 to cover legacy auth digest (without full auth digest subtree). + print("- both v4 and v5 transactions (plus coinbase)") + self.add_nu5_v4_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + # Adding both v4 and v5 to cover legacy auth digest (with full auth digest subtree). + print("- both v4 and v5 transactions (plus coinbase)") + self.add_nu5_v4_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.add_transparent_tx_to_mempool() + self.gbt_submitblock(True) + + print("- block with 6 Orchard transactions (plus coinbase)") + for i in range(0, 6): + print(str(node.z_getbalance(self.transparent_addr))) + self.add_nu5_v5_tx_to_mempool() + self.gbt_submitblock(True) + + print("- block with 7 Orchard transactions (plus coinbase)") + for i in range(0, 7): + self.add_nu5_v5_tx_to_mempool() + self.gbt_submitblock(True) + +if __name__ == '__main__': + GetBlockTemplateTest().main() diff --git a/depend/zcash/qa/rpc-tests/getblocktemplate_longpoll.py b/depend/zcash/qa/rpc-tests/getblocktemplate_longpoll.py new file mode 100755 index 000000000..89f5394f2 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/getblocktemplate_longpoll.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import get_rpc_proxy, random_transaction + +from decimal import Decimal + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +import threading + +class LongpollThread(threading.Thread): + def __init__(self, node): + threading.Thread.__init__(self) + # query current longpollid + templat = node.getblocktemplate() + self.longpollid = templat['longpollid'] + # create a new connection to the node, we can't use the same + # connection from two threads + self.node = get_rpc_proxy(node.url, 1, timeout=600) + + def run(self): + self.node.getblocktemplate({'longpollid':self.longpollid}) + +class GetBlockTemplateLPTest(BitcoinTestFramework): + ''' + Test longpolling with getblocktemplate. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def run_test(self): + print("Warning: this test will take about 70 seconds in the best case. Be patient.") + self.nodes[0].generate(10) + templat = self.nodes[0].getblocktemplate() + longpollid = templat['longpollid'] + # longpollid should not change between successive invocations if nothing else happens + templat2 = self.nodes[0].getblocktemplate() + assert(templat2['longpollid'] == longpollid) + + # Test 1: test that the longpolling wait if we do nothing + thr = LongpollThread(self.nodes[0]) + thr.start() + # check that thread still lives + thr.join(5) # wait 5 seconds or until thread exits + assert(thr.is_alive()) + + # Test 2: test that longpoll will terminate if another node generates a block + self.nodes[1].generate(1) # generate a block on another node + # check that thread will exit now that new transaction entered mempool + thr.join(5) # wait 5 seconds or until thread exits + assert(not thr.is_alive()) + + # Test 3: test that longpoll will terminate if we generate a block ourselves + thr = LongpollThread(self.nodes[0]) + thr.start() + self.nodes[0].generate(1) # generate a block on another node + thr.join(5) # wait 5 seconds or until thread exits + assert(not thr.is_alive()) + + # Test 4: test that introducing a new transaction into the mempool will terminate the longpoll + thr = LongpollThread(self.nodes[0]) + thr.start() + # generate a random transaction and submit it + (txid, txhex, fee) = random_transaction(self.nodes, Decimal("1.1"), Decimal("0.0"), Decimal("0.001"), 20) + # after one minute, every 10 seconds the mempool is probed, so in 80 seconds it should have returned + thr.join(60 + 20) + assert(not thr.is_alive()) + +if __name__ == '__main__': + GetBlockTemplateLPTest().main() + diff --git a/depend/zcash/qa/rpc-tests/getblocktemplate_proposals.py b/depend/zcash/qa/rpc-tests/getblocktemplate_proposals.py new file mode 100755 index 000000000..262753d5e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/getblocktemplate_proposals.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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 connect_nodes_bi + +from binascii import a2b_hex, b2a_hex +from hashlib import sha256 +from struct import pack + + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +def b2x(b): + return b2a_hex(b).decode('ascii') + +# NOTE: This does not work for signed numbers (set the high bit) or zero (use b'\0') +def encodeUNum(n): + s = bytearray(b'\1') + while n > 127: + s[0] += 1 + s.append(n % 256) + n //= 256 + s.append(n) + return bytes(s) + +def varlenEncode(n): + if n < 0xfd: + return pack(' 1: + n = [] + if len(cur) & 1: + cur.append(cur[-1]) + for i in range(0, len(cur), 2): + n.append(dblsha(cur[i] + cur[i+1])) + cur = n + return cur[0] + +def template_to_bytearray(tmpl, txlist): + blkver = pack(' 0) + # The transaction count doesn't include the coinbase + assert(info['currentblocktx'] == 0) + + +if __name__ == '__main__': + GetMiningInfoTest().main() diff --git a/depend/zcash/qa/rpc-tests/getrawtransaction_insight.py b/depend/zcash/qa/rpc-tests/getrawtransaction_insight.py new file mode 100755 index 000000000..f54bf85ee --- /dev/null +++ b/depend/zcash/qa/rpc-tests/getrawtransaction_insight.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test the new fields added to the output of getrawtransaction +# RPC for the Insight Explorer by the new spentindex +# + +from test_framework.test_framework import BitcoinTestFramework + +from test_framework.util import assert_equal +from test_framework.util import start_nodes, stop_nodes, connect_nodes +from test_framework.util import wait_bitcoinds + +from test_framework.mininode import COIN + + +class GetrawtransactionTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = True + + def setup_network(self): + # -insightexplorer causes spentindex to be enabled (fSpentIndex = true) + + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + [['-debug', '-txindex', '-experimentalfeatures', '-insightexplorer']] * self.num_nodes) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + # Test getrawtransaction changes and the getspentinfo RPC + + # send coinbase to address a + a = self.nodes[1].getnewaddress() + txid_a = self.nodes[0].sendtoaddress(a, 2) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # send from a to b + # (the only utxo on node 1 is from address a) + b = self.nodes[2].getnewaddress() + txid_b = self.nodes[1].sendtoaddress(b, 1) + self.sync_all() + + # a to b transaction is not confirmed, so it has no height + tx_b = self.nodes[2].getrawtransaction(txid_b, 1) + assert('height' not in tx_b) + + self.sync_all() + tx_a = self.nodes[2].getrawtransaction(txid_a, 1) + + # txid_b is not yet confirmed, so height is invalid (-1) + vout = list(filter(lambda o: o['value'] == 2, tx_a['vout'])) + assert_equal(vout[0]['spentTxId'], txid_b) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], -1) + + # confirm txid_b (a to b transaction) + self.nodes[0].generate(1) + self.sync_all() + + # Restart all nodes to ensure index files are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Check new fields added to getrawtransaction + tx_a = self.nodes[2].getrawtransaction(txid_a, 1) + assert_equal(tx_a['vin'][0]['value'], 10) # coinbase + assert_equal(tx_a['vin'][0]['valueSat'], 10*COIN) + # we want the non-change (payment) output + vout = list(filter(lambda o: o['value'] == 2, tx_a['vout'])) + assert_equal(vout[0]['spentTxId'], txid_b) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], 107) + assert_equal(tx_a['height'], 106) + + tx_b = self.nodes[2].getrawtransaction(txid_b, 1) + assert_equal(tx_b['vin'][0]['address'], a) + assert_equal(tx_b['vin'][0]['value'], 2) + assert_equal(tx_b['vin'][0]['valueSat'], 2*COIN) + # since this transaction's outputs haven't yet been + # spent, these fields should not be present + assert('spentTxId' not in tx_b['vout'][0]) + assert('spentIndex' not in tx_b['vout'][0]) + assert('spentHeight' not in tx_b['vout'][0]) + assert_equal(tx_b['height'], 107) + +if __name__ == '__main__': + GetrawtransactionTest().main() diff --git a/depend/zcash/qa/rpc-tests/golden/blossom.tar.gz b/depend/zcash/qa/rpc-tests/golden/blossom.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..feaad9438cd12bcb7c1ab0651d6f7278b5bf89c3 GIT binary patch literal 47555 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 M0gLbI!vMe$0ra#A+yDRo literal 0 HcmV?d00001 diff --git a/depend/zcash/qa/rpc-tests/golden/heartwood.tar.gz b/depend/zcash/qa/rpc-tests/golden/heartwood.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..56173ae826b0eec15799434750009beef5c76c9b GIT binary patch literal 55861 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 P!u_IjZuk=0jm!T7=YQ^} literal 0 HcmV?d00001 diff --git a/depend/zcash/qa/rpc-tests/hardforkdetection.py b/depend/zcash/qa/rpc-tests/hardforkdetection.py new file mode 100755 index 000000000..01374573f --- /dev/null +++ b/depend/zcash/qa/rpc-tests/hardforkdetection.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +# +# Test hard fork detection +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, start_node + +import os + +class HardForkDetectionTest(BitcoinTestFramework): + + alert_filename = None # Set by setup_network + + def setup_network(self): + self.nodes = [] + self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") + with open(self.alert_filename, 'w', encoding='utf8'): + pass # Just open then close to create zero-length file + self.nodes.append(start_node(0, self.options.tmpdir, + ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) + + def assert_safemode_off(self): + self.nodes[0].getbalance() + + def assert_safemode_on(self, requiredMessage): + errorString = "" + try: + self.nodes[0].getbalance() + except JSONRPCException as e: + errorString = e.error['message'] + + assert_equal("Safe mode:" in errorString, True) + assert_equal(requiredMessage in errorString, True) + + def run_test(self): + # Generate 10 blocks + self.nodes[0].generate(100) + + # Invalidate all of them. + for block_height in range(100, 0, -1): + block_hash = self.nodes[0].getblockhash(block_height) + self.nodes[0].invalidateblock(block_hash) + + # Check that safe mode is on. + self.assert_safemode_on("We do not appear to fully agree with our peers!") + + # Check that an -alertnotify was triggered. + with open(self.alert_filename, 'r', encoding='utf8') as f: + alert_text = f.read() + + if len(alert_text) == 0: + raise AssertionError("-alertnotify did not warn of detected hard fork") + + # If our chain keeps growing, but the hard forking chain remains longer, + # safe mode should stay on. + self.nodes[0].generate(50) + self.assert_safemode_on("We do not appear to fully agree with our peers!") + + # If we're on the longer side of the hard fork, safe mode should get + # turned off. + self.nodes[0].generate(50) + self.assert_safemode_off() + + +if __name__ == '__main__': + HardForkDetectionTest().main() diff --git a/depend/zcash/qa/rpc-tests/httpbasics.py b/depend/zcash/qa/rpc-tests/httpbasics.py new file mode 100755 index 000000000..ba01583dd --- /dev/null +++ b/depend/zcash/qa/rpc-tests/httpbasics.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test rpc http basics +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, str_to_b64str + +import http.client +import urllib.parse + +class HTTPBasicsTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False + + def setup_network(self): + self.nodes = self.setup_nodes() + + def run_test(self): + + ################################################# + # lowlevel check for http persistent connection # + ################################################# + url = urllib.parse.urlparse(self.nodes[0].url) + authpair = url.username + ':' + url.password + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read() + assert_equal(b'"error":null' in out1, True) + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! + + # send 2nd request without closing connection + conn.request('POST', '/', '{"method": "getchaintips"}', headers) + out2 = conn.getresponse().read() + assert_equal(b'"error":null' in out2, True) # must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! + conn.close() + + # same should be if we add keep-alive because this should be the std. behaviour + headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection": "keep-alive"} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read() + assert_equal(b'"error":null' in out1, True) + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! + + # send 2nd request without closing connection + conn.request('POST', '/', '{"method": "getchaintips"}', headers) + out2 = conn.getresponse().read() + assert_equal(b'"error":null' in out2, True) # must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! + conn.close() + + # now do the same with "Connection: close" + headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection":"close"} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read() + assert_equal(b'"error":null' in out1, True) + assert_equal(conn.sock!=None, False) # now the connection must be closed after the response + + # node1 (2nd node) is running with disabled keep-alive option + urlNode1 = urllib.parse.urlparse(self.nodes[1].url) + authpair = urlNode1.username + ':' + urlNode1.password + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} + + conn = http.client.HTTPConnection(urlNode1.hostname, urlNode1.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read() + assert_equal(b'"error":null' in out1, True) + + # node2 (third node) is running with standard keep-alive parameters which means keep-alive is on + urlNode2 = urllib.parse.urlparse(self.nodes[2].url) + authpair = urlNode2.username + ':' + urlNode2.password + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} + + conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + out1 = conn.getresponse().read() + assert_equal(b'"error":null' in out1, True) + assert_equal(conn.sock!=None, True) # connection must be closed because bitcoind should use keep-alive by default + + # Check excessive request size + conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port) + conn.connect() + conn.request('GET', '/' + ('x'*1000), '', headers) + out1 = conn.getresponse() + assert_equal(out1.status, http.client.NOT_FOUND) + + conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port) + conn.connect() + conn.request('GET', '/' + ('x'*10000), '', headers) + out1 = conn.getresponse() + assert_equal(out1.status, http.client.BAD_REQUEST) + + +if __name__ == '__main__': + HTTPBasicsTest().main() diff --git a/depend/zcash/qa/rpc-tests/invalidateblock.py b/depend/zcash/qa/rpc-tests/invalidateblock.py new file mode 100755 index 000000000..6907dc21d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/invalidateblock.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test InvalidateBlock code +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_node, \ + connect_nodes_bi, sync_blocks + +import time + +class InvalidateTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) + + def run_test(self): + print("Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:") + print("Mine 4 blocks on Node 0") + self.nodes[0].generate(4) + assert(self.nodes[0].getblockcount() == 4) + besthash = self.nodes[0].getbestblockhash() + + print("Mine competing 6 blocks on Node 1") + self.nodes[1].generate(6) + assert(self.nodes[1].getblockcount() == 6) + + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes,0,1) + sync_blocks(self.nodes[0:2]) + assert(self.nodes[0].getblockcount() == 6) + badhash = self.nodes[1].getblockhash(2) + + print("Invalidate block 2 on node 0 and verify we reorg to node 0's original chain") + self.nodes[0].invalidateblock(badhash) + newheight = self.nodes[0].getblockcount() + newhash = self.nodes[0].getbestblockhash() + if (newheight != 4 or newhash != besthash): + raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight)) + + print("\nMake sure we won't reorg to a lower work chain:") + connect_nodes_bi(self.nodes,1,2) + print("Sync node 2 to node 1 so both have 6 blocks") + sync_blocks(self.nodes[1:3]) + assert(self.nodes[2].getblockcount() == 6) + print("Invalidate block 5 on node 1 so its tip is now at 4") + self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5)) + assert(self.nodes[1].getblockcount() == 4) + print("Invalidate block 3 on node 2, so its tip is now 2") + self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) + assert(self.nodes[2].getblockcount() == 2) + print("..and then mine a block") + self.nodes[2].generate(1) + print("Verify all nodes are at the right height") + time.sleep(5) + for i in range(3): + print(i,self.nodes[i].getblockcount()) + assert(self.nodes[2].getblockcount() == 3) + assert(self.nodes[0].getblockcount() == 4) + node1height = self.nodes[1].getblockcount() + if node1height < 4: + raise AssertionError("Node 1 reorged to a lower height: %d"%node1height) + +if __name__ == '__main__': + InvalidateTest().main() diff --git a/depend/zcash/qa/rpc-tests/invalidblockrequest.py b/depend/zcash/qa/rpc-tests/invalidblockrequest.py new file mode 100755 index 000000000..4fb916e10 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/invalidblockrequest.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.util import assert_equal +from test_framework.comptool import TestManager, TestInstance, RejectResult +from test_framework.mininode import NetworkThread +from test_framework.blocktools import create_block, create_coinbase, create_transaction + +import copy +import time + + +''' +In this test we connect to one node over p2p, and test block requests: +1) Valid blocks should be requested and become chain tip. +2) Invalid block with duplicated transaction should be re-requested. +3) Invalid block with bad coinbase value should be rejected and not +re-requested. +''' + +# Use the ComparisonTestFramework with 1 node: only use --testbinary. +class InvalidBlockRequestTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + self.tip = None + self.block_time = None + NetworkThread().start() # Start up network handling in another thread + test.run() + + def get_tests(self): + if self.tip is None: + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) + self.block_time = int(time.time())+1 + + ''' + Create a new block with an anyone-can-spend coinbase + ''' + height = 1 + block = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + block.solve() + # Save the coinbase for later + self.block1 = block + self.tip = block.sha256 + height += 1 + yield TestInstance([[block, True]]) + + ''' + Now we need that block to mature so we can spend the coinbase. + ''' + test = TestInstance(sync_every_block=False) + for i in range(100): + block = create_block(self.tip, create_coinbase(height), self.block_time) + block.solve() + self.tip = block.sha256 + self.block_time += 1 + test.blocks_and_transactions.append([block, True]) + height += 1 + yield test + + ''' + Now we use merkle-root malleability to generate an invalid block with + same blockheader. + Manufacture a block with 3 transactions (coinbase, spend of prior + coinbase, spend of that spend). Duplicate the 3rd transaction to + leave merkle root and blockheader unchanged but invalidate the block. + ''' + block2 = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + + # b'0x51' is OP_TRUE + tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 10*100000000) + tx2 = create_transaction(tx1, 0, b'\x51', 10*100000000) + + block2.vtx.extend([tx1, tx2]) + block2.hashMerkleRoot = block2.calc_merkle_root() + block2.rehash() + block2.solve() + orig_hash = block2.sha256 + block2_orig = copy.deepcopy(block2) + + # Mutate block 2 + block2.vtx.append(tx2) + assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root()) + assert_equal(orig_hash, block2.rehash()) + assert(block2_orig.vtx != block2.vtx) + + self.tip = block2.sha256 + yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]]) + height += 1 + + ''' + Make sure that a totally screwed up block is not valid. + ''' + block3 = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + block3.vtx[0].vout[0].nValue = 100*100000000 # Too high! + block3.vtx[0].sha256=None + block3.vtx[0].calc_sha256() + block3.hashMerkleRoot = block3.calc_merkle_root() + block3.rehash() + block3.solve() + + yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]]) + + +if __name__ == '__main__': + InvalidBlockRequestTest().main() diff --git a/depend/zcash/qa/rpc-tests/invalidtxrequest.py b/depend/zcash/qa/rpc-tests/invalidtxrequest.py new file mode 100755 index 000000000..8ec448f50 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/invalidtxrequest.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.comptool import TestManager, TestInstance, RejectResult +from test_framework.mininode import NetworkThread +from test_framework.blocktools import create_block, create_coinbase, create_transaction +import time + + +''' +In this test we connect to one node over p2p, and test tx requests. +''' + +# Use the ComparisonTestFramework with 1 node: only use --testbinary. +class InvalidTxRequestTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + self.tip = None + self.block_time = None + NetworkThread().start() # Start up network handling in another thread + test.run() + + def get_tests(self): + if self.tip is None: + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) + self.block_time = int(time.time())+1 + + ''' + Create a new block with an anyone-can-spend coinbase + ''' + height = 1 + block = create_block(self.tip, create_coinbase(height), self.block_time) + self.block_time += 1 + block.solve() + # Save the coinbase for later + self.block1 = block + self.tip = block.sha256 + height += 1 + yield TestInstance([[block, True]]) + + ''' + Now we need that block to mature so we can spend the coinbase. + ''' + test = TestInstance(sync_every_block=False) + for i in range(100): + block = create_block(self.tip, create_coinbase(height), self.block_time) + block.solve() + self.tip = block.sha256 + self.block_time += 1 + test.blocks_and_transactions.append([block, True]) + height += 1 + yield test + + # b'\x64' is OP_NOTIF + # Transaction will be rejected with code 16 (REJECT_INVALID) + tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 10*100000000) + yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]]) + + # TODO: test further transactions... + +if __name__ == '__main__': + InvalidTxRequestTest().main() diff --git a/depend/zcash/qa/rpc-tests/key_import_export.py b/depend/zcash/qa/rpc-tests/key_import_export.py new file mode 100755 index 000000000..186e72261 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/key_import_export.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from functools import reduce +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_greater_than, start_nodes, connect_nodes_bi + +import logging +import sys + +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout) + + +class KeyImportExportTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + def run_test(self): + [alice, bob, charlie, miner] = self.nodes + + def alice_to_bob(amount): + alice.sendtoaddress(addr, Decimal(amount)) + self.sync_all() + miner.generate(1) + self.sync_all() + + def verify_utxos(node, amounts): + utxos = node.listunspent(1, 10**9, [addr]) + utxos.sort(key=lambda x: x["confirmations"]) + utxos.reverse() + + try: + assert_equal(amounts, [utxo["amount"] for utxo in utxos]) + except AssertionError: + logging.error( + 'Expected amounts: %r; utxos: %r', + amounts, utxos) + raise + + # Seed Alice with some funds + alice.generate(10) + self.sync_all() + miner.generate(100) + self.sync_all() + + # Now get a pristine address for receiving transfers: + addr = bob.getnewaddress() + verify_utxos(bob, []) + verify_utxos(charlie, []) + + # the amounts of each txn embodied which generates a single UTXO: + amounts = list(map(Decimal, ['2.3', '3.7', '0.1', '0.5', '1.0', '0.19'])) + + # Internal test consistency assertion: + assert_greater_than( + alice.getbalance(), + reduce(Decimal.__add__, amounts)) + + logging.info("Sending pre-export txns...") + for amount in amounts[0:2]: + alice_to_bob(amount) + + logging.info("Exporting privkey from bob...") + privkey = bob.dumpprivkey(addr) + + logging.info("Sending post-export txns...") + for amount in amounts[2:4]: + alice_to_bob(amount) + + verify_utxos(bob, amounts[:4]) + verify_utxos(charlie, []) + + logging.info("Importing privkey into charlie...") + ipkaddr = charlie.importprivkey(privkey, '', True) + assert_equal(addr, ipkaddr) + + # importprivkey should have rescanned, so this should pass: + verify_utxos(charlie, amounts[:4]) + + # Verify idempotent behavior: + ipkaddr2 = charlie.importprivkey(privkey, '', True) + assert_equal(addr, ipkaddr2) + + # amounts should be unchanged + verify_utxos(charlie, amounts[:4]) + + logging.info("Sending post-import txns...") + for amount in amounts[4:]: + alice_to_bob(amount) + + verify_utxos(bob, amounts) + verify_utxos(charlie, amounts) + + +if __name__ == '__main__': + KeyImportExportTest().main() diff --git a/depend/zcash/qa/rpc-tests/keypool.py b/depend/zcash/qa/rpc-tests/keypool.py new file mode 100755 index 000000000..d567be3a5 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/keypool.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Exercise the wallet keypool, and interaction with wallet encryption/locking + +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + start_nodes, start_node, bitcoind_processes + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +class KeyPoolTest(BitcoinTestFramework): + + def run_test(self): + nodes = self.nodes + # Encrypt wallet and wait to terminate + nodes[0].encryptwallet('test') + bitcoind_processes[0].wait() + # Restart node 0 + nodes[0] = start_node(0, self.options.tmpdir) + # We can't create any external addresses, which don't use the keypool. + # We should get an error that we need to unlock the wallet. + try: + addr = nodes[0].getnewaddress() + raise AssertionError('Wallet should be locked.') + except JSONRPCException as e: + assert_equal(e.error['code'], -13) + + # put three new keys in the keypool + nodes[0].walletpassphrase('test', 12000) + nodes[0].keypoolrefill(3) + nodes[0].walletlock() + + # drain the keys + addr = set() + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + addr.add(nodes[0].getrawchangeaddress()) + # assert that four unique addresses were returned + assert(len(addr) == 4) + # the next one should fail + try: + addr = nodes[0].getrawchangeaddress() + raise AssertionError('Keypool should be exhausted after three addresses') + except JSONRPCException as e: + assert(e.error['code']==-12) + + # refill keypool with three new addresses + nodes[0].walletpassphrase('test', 12000) + nodes[0].keypoolrefill(3) + nodes[0].walletlock() + + # drain them by mining + nodes[0].generate(1) + nodes[0].generate(1) + nodes[0].generate(1) + nodes[0].generate(1) + try: + nodes[0].generate(1) + raise AssertionError('Keypool should be exhausted after three addesses') + except JSONRPCException as e: + assert_equal(e.error['code'], -12) + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-experimentalfeatures', '-developerencryptwallet']]) + +if __name__ == '__main__': + KeyPoolTest().main() diff --git a/depend/zcash/qa/rpc-tests/listtransactions.py b/depend/zcash/qa/rpc-tests/listtransactions.py new file mode 100755 index 000000000..64876d733 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/listtransactions.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Exercise the listtransactions API + +from test_framework.test_framework import BitcoinTestFramework + +from decimal import Decimal + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +class ListTransactionsTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def run_test(self): + # Simple send, 0 to 1: + txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + self.sync_all() + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, + {"category":"send","amount":Decimal("-0.1"),"amountZat":-10000000,"confirmations":0}) + check_array_result(self.nodes[1].listtransactions(), + {"txid":txid}, + {"category":"receive","amount":Decimal("0.1"),"amountZat":10000000,"confirmations":0}) + + # mine a block, confirmations should change: + self.nodes[0].generate(1) + self.sync_all() + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid}, + {"category":"send","amount":Decimal("-0.1"),"amountZat":-10000000,"confirmations":1}) + check_array_result(self.nodes[1].listtransactions(), + {"txid":txid}, + {"category":"receive","amount":Decimal("0.1"),"amountZat":10000000,"confirmations":1}) + + # send-to-self: + txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2) + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid, "category":"send"}, + {"amount":Decimal("-0.2"),"amountZat":-20000000}) + check_array_result(self.nodes[0].listtransactions(), + {"txid":txid, "category":"receive"}, + {"amount":Decimal("0.2"),"amountZat":20000000}) + + # sendmany from node1: twice to self, twice to node2: + node_0_addr_0 = self.nodes[0].getnewaddress() + node_0_addr_1 = self.nodes[0].getnewaddress() + node_1_addr_0 = self.nodes[1].getnewaddress() + node_1_addr_1 = self.nodes[1].getnewaddress() + send_to = { node_0_addr_0 : 0.11, + node_1_addr_0 : 0.22, + node_0_addr_1 : 0.33, + node_1_addr_1 : 0.44 } + txid = self.nodes[1].sendmany("", send_to) + self.sync_all() + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.11"),"amountZat":-11000000}, + {"txid":txid} ) + check_array_result(self.nodes[0].listtransactions(), + {"category":"receive","amount":Decimal("0.11"),"amountZat":11000000}, + {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.22"),"amountZat":-22000000}, + {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"receive","amount":Decimal("0.22"),"amountZat":22000000}, + {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.33"),"amountZat":-33000000}, + {"txid":txid} ) + check_array_result(self.nodes[0].listtransactions(), + {"category":"receive","amount":Decimal("0.33"),"amountZat":33000000}, + {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"send","amount":Decimal("-0.44"),"amountZat":-44000000}, + {"txid":txid} ) + check_array_result(self.nodes[1].listtransactions(), + {"category":"receive","amount":Decimal("0.44"),"amountZat":44000000}, + {"txid":txid} ) + + multisig = self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()]) + self.nodes[0].importaddress(multisig["redeemScript"], "watchonly", False, True) + txid = self.nodes[1].sendtoaddress(multisig["address"], 0.1) + self.nodes[1].generate(1) + self.sync_all() + check_array_result(self.nodes[0].listtransactions("*", 100, 0, True), + {"category":"receive","amount":Decimal("0.1"),"amountZat":10000000}, + {"txid":txid, "involvesWatchonly": True} ) + +if __name__ == '__main__': + ListTransactionsTest().main() diff --git a/depend/zcash/qa/rpc-tests/maxblocksinflight.py b/depend/zcash/qa/rpc-tests/maxblocksinflight.py new file mode 100755 index 000000000..9b4cd2048 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/maxblocksinflight.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + EarlyDisconnectError, CInv, msg_inv, mininode_lock +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ZCASHD_BINARY, start_nodes, p2p_port + +import os +import time +import random +import logging + +''' +In this test we connect to one node over p2p, send it numerous inv's, and +compare the resulting number of getdata requests to a max allowed value. We +test for exceeding 128 blocks in flight, which was the limit an 0.9 client will +reach. [0.10 clients shouldn't request more than 16 from a single peer.] +''' +MAX_REQUESTS = 128 + +class TestManager(NodeConnCB): + # set up NodeConnCB callbacks, overriding base class + def on_getdata(self, conn, message): + self.log.debug("got getdata %s" % repr(message)) + # Log the requests + for inv in message.inv: + if inv.hash not in self.blockReqCounts: + self.blockReqCounts[inv.hash] = 0 + self.blockReqCounts[inv.hash] += 1 + + def on_close(self, conn): + if not self.disconnectOkay: + raise EarlyDisconnectError(0) + + def __init__(self): + NodeConnCB.__init__(self) + self.log = logging.getLogger("BlockRelayTest") + self.create_callback_map() + + def add_new_connection(self, connection): + self.connection = connection + self.blockReqCounts = {} + self.disconnectOkay = False + + def run(self): + try: + self.connection.rpc.generate(1) # Leave IBD + + numBlocksToGenerate = [ 8, 16, 128, 1024 ] + for count in range(len(numBlocksToGenerate)): + current_invs = [] + for i in range(numBlocksToGenerate[count]): + current_invs.append(CInv(2, random.randrange(0, 1<<256))) + if len(current_invs) >= 50000: + self.connection.send_message(msg_inv(current_invs)) + current_invs = [] + if len(current_invs) > 0: + self.connection.send_message(msg_inv(current_invs)) + + # Wait and see how many blocks were requested + time.sleep(2) + + total_requests = 0 + with mininode_lock: + for key in self.blockReqCounts: + total_requests += self.blockReqCounts[key] + if self.blockReqCounts[key] > 1: + raise AssertionError("Error, test failed: block %064x requested more than once" % key) + if total_requests > MAX_REQUESTS: + raise AssertionError("Error, too many blocks (%d) requested" % total_requests) + print("Round %d: success (total requests: %d)" % (count, total_requests)) + except AssertionError as e: + print("TEST FAILED: ", e.args) + + self.disconnectOkay = True + self.connection.disconnect_node() + + +class MaxBlocksInFlightTest(BitcoinTestFramework): + def add_options(self, parser): + parser.add_option("--testbinary", dest="testbinary", + default=os.getenv("ZCASHD", ZCASHD_BINARY), + help="Binary to test max block requests behavior") + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']], + binary=[self.options.testbinary]) + + def run_test(self): + test = TestManager() + test.add_new_connection(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test)) + NetworkThread().start() # Start up network handling in another thread + test.run() + +if __name__ == '__main__': + MaxBlocksInFlightTest().main() diff --git a/depend/zcash/qa/rpc-tests/maxuploadtarget.py b/depend/zcash/qa/rpc-tests/maxuploadtarget.py new file mode 100755 index 000000000..74cce7469 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/maxuploadtarget.py @@ -0,0 +1,305 @@ +#!/usr/bin/env python3 +# +# Distributed under the MIT/X11 software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# + +from test_framework.mininode import ( \ + NodeConn, NodeConnCB, CInv, NetworkThread, \ + msg_ping, msg_pong, msg_getdata, \ + BLOSSOM_PROTO_VERSION + ) + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( \ + ZCASHD_BINARY, assert_equal, initialize_chain_clean, \ + start_node, stop_node, \ + p2p_port, \ + ) +from test_framework.comptool import wait_until +from decimal import Decimal +import os +import time + +''' +Test behavior of -maxuploadtarget. + +* Verify that getdata requests for old blocks (>1week) are dropped +if uploadtarget has been reached. +* Verify that getdata requests for recent blocks are respected even +if uploadtarget has been reached. +* Verify that the upload counters are reset after 24 hours. +''' + +# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending +# p2p messages to a node, generating the messages in the main testing logic. +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + self.block_receive_map = {} + + def add_connection(self, conn): + self.connection = conn + self.peer_disconnected = False + + def on_inv(self, conn, message): + pass + + # Track the last getdata message we receive (used in the test) + def on_getdata(self, conn, message): + self.last_getdata = message + + def on_block(self, conn, message): + message.block.calc_sha256() + try: + self.block_receive_map[message.block.sha256] += 1 + except KeyError: + self.block_receive_map[message.block.sha256] = 1 + + # Spin until verack message is received from the node. + # We use this to signal that our test can begin. This + # is called from the testing thread, so it needs to acquire + # the global lock. + def wait_for_verack(self): + def veracked(): + return self.verack_received + return wait_until(veracked, timeout=10) + + def wait_for_disconnect(self): + def disconnected(): + return self.peer_disconnected + return wait_until(disconnected, timeout=10) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_pong(self, conn, message): + self.last_pong = message + + def on_close(self, conn): + self.peer_disconnected = True + + # Sync up with the node after delivery of a block + def sync_with_ping(self, timeout=30): + def received_pong(): + return (self.last_pong.nonce == self.ping_counter) + self.connection.send_message(msg_ping(nonce=self.ping_counter)) + success = wait_until(received_pong, timeout) + self.ping_counter += 1 + return success + +class MaxUploadTest(BitcoinTestFramework): + def __init__(self): + self.utxo = [] + + # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create + # So we have big transactions and full blocks to fill up our block files + # create one script_pubkey + script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes + for _ in range(512): + script_pubkey = script_pubkey + "01" + # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change + self.txouts = "81" + for _ in range(128): + # add txout value + self.txouts = self.txouts + "0000000000000000" + # add length of script_pubkey + self.txouts = self.txouts + "fd0402" + # add script_pubkey + self.txouts = self.txouts + script_pubkey + + def add_options(self, parser): + parser.add_option("--testbinary", dest="testbinary", + default=os.getenv("ZCASHD", ZCASHD_BINARY), + help="zcashd binary to test") + + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + # Start a node with maxuploadtarget of 200 MB (/24h) + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, [ + "-debug", + '-nuparams=2bb40e60:1', # Blossom + "-maxuploadtarget=2200"])) + + def mine_full_block(self, node, address): + # Want to create a full block + # We'll generate a 66k transaction below, and 28 of them is close to the 2MB block limit + for _ in range(28): + if len(self.utxo) < 28: + self.utxo = node.listunspent() + inputs=[] + outputs = {} + t = self.utxo.pop() + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + remchange = t["amount"] - Decimal("0.001000") + outputs[address]=remchange + # Create a basic transaction that will send change back to ourself after account for a fee + # and then insert the 128 generated transaction outs in the middle. rawtx[100] is where the + # number of txouts is stored and is the only thing we overwrite from the original transaction + rawtx = node.createrawtransaction(inputs, outputs) + newtx = rawtx[0:100] + newtx = newtx + self.txouts + newtx = newtx + rawtx[102:] + # Appears to be ever so slightly faster to sign with SIGHASH_NONE + signresult = node.signrawtransaction(newtx,None,None,"NONE") + node.sendrawtransaction(signresult["hex"], True) + # Mine a full sized block which will be these transactions we just created + node.generate(1) + + def run_test(self): + # Before we connect anything, we first set the time on the node + # to be in the past, otherwise things break because the CNode + # time counters can't be reset backward after initialization + old_time = int(time.time() - 60*60*24*9) + self.nodes[0].setmocktime(old_time) + + # Generate some old blocks + self.nodes[0].generate(260) + + # test_nodes[0] will only request old blocks + # test_nodes[1] will only request new blocks + # test_nodes[2] will test resetting the counters + test_nodes = [] + connections = [] + + for i in range(3): + test_nodes.append(TestNode()) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i], protocol_version=BLOSSOM_PROTO_VERSION)) + test_nodes[i].add_connection(connections[i]) + + NetworkThread().start() # Start up network handling in another thread + [x.wait_for_verack() for x in test_nodes] + + # Test logic begins here + + # Now mine a big block + self.mine_full_block(self.nodes[0], self.nodes[0].getnewaddress()) + + # Store the hash; we'll request this later + big_old_block = self.nodes[0].getbestblockhash() + old_block_size = self.nodes[0].getblock(big_old_block, True)['size'] + big_old_block = int(big_old_block, 16) + + # Advance to two days ago + self.nodes[0].setmocktime(int(time.time()) - 2*60*60*24) + + # Generate interim blocks. Due to the "max MTP" soft-forked rule, block timestamps + # can be no more than 1.5 hours ahead of the chain tip's MTP. Thus we need to mine + # enough blocks to advance the MTP forward to the desired mocked time. + self.nodes[0].generate(1000) + + # Mine one more block, so that the prior block looks old + self.mine_full_block(self.nodes[0], self.nodes[0].getnewaddress()) + + # We'll be requesting this new block too + big_new_block = self.nodes[0].getbestblockhash() + big_new_block = int(big_new_block, 16) + + # test_nodes[0] will test what happens if we just keep requesting the + # the same big old block too many times (expect: disconnect) + + getdata_request = msg_getdata() + getdata_request.inv.append(CInv(2, big_old_block)) + + max_bytes_per_day = 2200*1024*1024 + daily_buffer = 1152 * 2000000 + max_bytes_available = max_bytes_per_day - daily_buffer + success_count = max_bytes_available / old_block_size + + # 2304GB will be reserved for relaying new blocks, so expect this to + # succeed for ~14 tries. + for i in range(int(success_count)): + test_nodes[0].send_message(getdata_request) + test_nodes[0].sync_with_ping() + assert_equal(test_nodes[0].block_receive_map[big_old_block], i+1) + + assert_equal(len(self.nodes[0].getpeerinfo()), 3) + # At most a couple more tries should succeed (depending on how long + # the test has been running so far). + for i in range(3): + test_nodes[0].send_message(getdata_request) + test_nodes[0].wait_for_disconnect() + assert_equal(len(self.nodes[0].getpeerinfo()), 2) + print("Peer 0 disconnected after downloading old block too many times") + + # Requesting the current block on test_nodes[1] should succeed indefinitely, + # even when over the max upload target. + # We'll try 200 times + getdata_request.inv = [CInv(2, big_new_block)] + for i in range(200): + test_nodes[1].send_message(getdata_request) + test_nodes[1].sync_with_ping() + assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1) + + print("Peer 1 able to repeatedly download new block") + + # But if test_nodes[1] tries for an old block, it gets disconnected too. + getdata_request.inv = [CInv(2, big_old_block)] + test_nodes[1].send_message(getdata_request) + test_nodes[1].wait_for_disconnect() + assert_equal(len(self.nodes[0].getpeerinfo()), 1) + + print("Peer 1 disconnected after trying to download old block") + + print("Advancing system time on node to clear counters...") + + # If we advance the time by 24 hours, then the counters should reset, + # and test_nodes[2] should be able to retrieve the old block. + self.nodes[0].setmocktime(int(time.time())) + test_nodes[2].sync_with_ping() + test_nodes[2].send_message(getdata_request) + test_nodes[2].sync_with_ping() + assert_equal(test_nodes[2].block_receive_map[big_old_block], 1) + + print("Peer 2 able to download old block") + + [c.disconnect_node() for c in connections] + + #stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1 + print("Restarting nodes with -whitelist=127.0.0.1") + stop_node(self.nodes[0], 0) + self.nodes[0] = start_node(0, self.options.tmpdir, [ + "-debug", + '-nuparams=2bb40e60:1', # Blossom + "-whitelist=127.0.0.1", + "-maxuploadtarget=1", + ]) + + #recreate/reconnect 3 test nodes + test_nodes = [] + connections = [] + + for i in range(3): + test_nodes.append(TestNode()) + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i], protocol_version=BLOSSOM_PROTO_VERSION)) + test_nodes[i].add_connection(connections[i]) + + NetworkThread().start() # Start up network handling in another thread + [x.wait_for_verack() for x in test_nodes] + + #retrieve 20 blocks which should be enough to break the 1MB limit + getdata_request.inv = [CInv(2, big_new_block)] + for i in range(20): + test_nodes[1].send_message(getdata_request) + test_nodes[1].sync_with_ping() + assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1) + + getdata_request.inv = [CInv(2, big_old_block)] + test_nodes[1].send_message(getdata_request) + test_nodes[1].wait_for_disconnect() + assert_equal(len(self.nodes[0].getpeerinfo()), 3) #node is still connected because of the whitelist + + print("Peer 1 still connected after trying to download old block (whitelisted)") + + [c.disconnect_node() for c in connections] + +if __name__ == '__main__': + MaxUploadTest().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_limit.py b/depend/zcash/qa/rpc-tests/mempool_limit.py new file mode 100755 index 000000000..f230d25b7 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_limit.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + get_coinbase_address, + fail, + start_nodes, + wait_and_assert_operationid_status, + DEFAULT_FEE +) + +from decimal import Decimal +from time import sleep + +# Test wallet behaviour with Sapling addresses +class MempoolLimit(BitcoinTestFramework): + def setup_nodes(self): + extra_args = [ + ["-debug=mempool", '-mempooltxcostlimit=8000'], # 2 transactions at min cost + ["-debug=mempool", '-mempooltxcostlimit=8000'], # 2 transactions at min cost + ["-debug=mempool", '-mempooltxcostlimit=8000'], # 2 transactions at min cost + # Let node 3 hold one more transaction + ["-debug=mempool", '-mempooltxcostlimit=12000'], # 3 transactions at min cost + ] + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + + def check_mempool_sizes(self, expected_size, check_node3=True): + for i in range(self.num_nodes if check_node3 else self.num_nodes - 1): + mempool = self.nodes[i].getrawmempool() + if len(mempool) != expected_size: + # print all nodes' mempools before failing + for i in range(self.num_nodes): + print("Mempool for node {}: {}".format(i, mempool)) + fail("Fail: Mempool for node {}: size={}, expected={}".format(i, len(mempool), expected_size)) + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 + + def run_test(self): + print("Mining blocks...") + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + self.nodes[3].generate(1) + self.sync_all() + self.nodes[0].generate(100) + self.sync_all() + assert_equal(Decimal("10.00"), Decimal(self.nodes[1].z_gettotalbalance()['transparent'])) + assert_equal(Decimal("10.00"), Decimal(self.nodes[2].z_gettotalbalance()['transparent'])) + assert_equal(Decimal("10.00"), Decimal(self.nodes[3].z_gettotalbalance()['transparent'])) + + zaddr1 = self.nodes[0].z_getnewaddress('sapling') + zaddr2 = self.nodes[0].z_getnewaddress('sapling') + zaddr3 = self.nodes[0].z_getnewaddress('sapling') + + print("Filling mempool...") + opid1 = self.nodes[1].z_sendmany(get_coinbase_address(self.nodes[1]), [{"address": zaddr1, "amount": Decimal('10.0') - DEFAULT_FEE}]) + wait_and_assert_operationid_status(self.nodes[1], opid1) + opid2 = self.nodes[2].z_sendmany(get_coinbase_address(self.nodes[2]), [{"address": zaddr2, "amount": Decimal('10.0') - DEFAULT_FEE}]) + wait_and_assert_operationid_status(self.nodes[2], opid2) + self.sync_all() + + self.check_mempool_sizes(2) + + print("Adding one more transaction...") + opid3 = self.nodes[3].z_sendmany(get_coinbase_address(self.nodes[3]), [{"address": zaddr3, "amount": Decimal('10.0') - DEFAULT_FEE}]) + wait_and_assert_operationid_status(self.nodes[3], opid3) + # The mempools are no longer guaranteed to be in a consistent state, so we cannot sync + sleep(5) + mempool_node3 = self.nodes[3].getrawmempool() + assert_equal(3, len(mempool_node3), "node {}".format(3)) + + print("Checking mempool size...") + # Due to the size limit, there should only be 2 transactions in the mempool + self.check_mempool_sizes(2, False) + + self.nodes[3].generate(1) + self.sync_all() + + # The mempool sizes should be reset + print("Checking mempool size reset after block mined...") + self.check_mempool_sizes(0) + zaddr4 = self.nodes[0].z_getnewaddress('sapling') + opid4 = self.nodes[0].z_sendmany(zaddr1, [{"address": zaddr4, "amount": Decimal('10.0') - 2*DEFAULT_FEE}], 1) + wait_and_assert_operationid_status(self.nodes[0], opid4) + opid5 = self.nodes[0].z_sendmany(zaddr2, [{"address": zaddr4, "amount": Decimal('10.0') - 2*DEFAULT_FEE}], 1) + wait_and_assert_operationid_status(self.nodes[0], opid5) + self.sync_all() + + self.check_mempool_sizes(2) + + # Make sure the transactions are mined without error + self.nodes[3].generate(1) + self.sync_all() + + +if __name__ == '__main__': + MempoolLimit().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_nu_activation.py b/depend/zcash/qa/rpc-tests/mempool_nu_activation.py new file mode 100755 index 000000000..14d5df2c2 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_nu_activation.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.mininode import NU5_PROTO_VERSION +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + CANOPY_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, assert_true, + nuparams, + start_node, connect_nodes, wait_and_assert_operationid_status, + get_coinbase_address +) + +from decimal import Decimal + +# Test mempool behaviour around network upgrade activation +class MempoolUpgradeActivationTest(BitcoinTestFramework): + + alert_filename = None # Set by setup_network + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = True + + def setup_network(self): + args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000", + nuparams(BLOSSOM_BRANCH_ID, 200), + nuparams(HEARTWOOD_BRANCH_ID, 210), + nuparams(CANOPY_BRANCH_ID, 220), + nuparams(NU5_BRANCH_ID, 230), + ] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes(self.nodes[1], 0) + self.is_network_split = False + self.sync_all + + def run_test(self): + self.nodes[1].generate(100) + self.sync_all() + + # Mine 97 blocks. After this, nodes[1] blocks + # 1 to 97 are spend-able. + self.nodes[0].generate(94) + self.sync_all() + + # Shield some ZEC + node1_taddr = get_coinbase_address(self.nodes[1]) + node0_zaddr = self.nodes[0].z_getnewaddress('sapling') + recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}] + myopid = self.nodes[1].z_sendmany(node1_taddr, recipients, 1, 0) + print(wait_and_assert_operationid_status(self.nodes[1], myopid)) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Mempool checks for activation of upgrade Y at height H on base X + def nu_activation_checks(): + # Start at block H - 5. After this, the mempool expects block H - 4, which is + # the last height at which we can create transactions for X blocks (due to the + # expiring-soon restrictions). + + # Mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Check node 0 shielded balance + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('10')) + + # Fill the mempool with more transactions than can fit into 4 blocks + node0_taddr = self.nodes[0].getnewaddress() + x_txids = [] + while self.nodes[1].getmempoolinfo()['bytes'] < 8 * 4000: + x_txids.append(self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001'))) + self.sync_all() + + # Spends should be in the mempool + x_mempool = set(self.nodes[0].getrawmempool()) + assert_equal(x_mempool, set(x_txids)) + assert_equal(set(self.nodes[1].getrawmempool()), set(x_txids)) + + blocks = [] + + # Mine block H - 4. After this, the mempool expects + # block H - 3, which is an X block. + self.nodes[0].generate(1) + self.sync_all() + blocks.append(self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx']) + + # mempool should not be empty. + assert_true(len(set(self.nodes[0].getrawmempool())) > 0) + assert_true(len(set(self.nodes[1].getrawmempool())) > 0) + + # Mine block H - 3. After this, the mempool expects + # block H - 2, which is an X block. + self.nodes[0].generate(1) + self.sync_all() + blocks.append(self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx']) + + # mempool should not be empty. + assert_true(len(set(self.nodes[0].getrawmempool())) > 0) + assert_true(len(set(self.nodes[1].getrawmempool())) > 0) + + # Mine block H - 2. After this, the mempool expects + # block H - 1, which is an X block. + self.nodes[0].generate(1) + self.sync_all() + blocks.append(self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx']) + + # mempool should not be empty. + assert_true(len(set(self.nodes[0].getrawmempool())) > 0) + assert_true(len(set(self.nodes[1].getrawmempool())) > 0) + + # Mine block H - 1. After this, the mempool expects + # block H, which is the first Y block. + self.nodes[0].generate(1) + self.sync_all() + blocks.append(self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx']) + + # mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + assert_equal(set(self.nodes[1].getrawmempool()), set()) + + # Blocks [H - 4..H - 1] should contain a subset of the original mempool + # (with all other transactions having been dropped) + assert(sum([len(block_txids) for block_txids in blocks]) < len(x_txids)) + for block_txids in blocks: + for txid in block_txids[1:]: # Exclude coinbase + assert(txid in x_txids) + + # Create some transparent Y transactions + y_txids = [self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001')) for i in range(10)] + self.sync_all() + + # Create a shielded Y transaction + recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}] + myopid = self.nodes[0].z_sendmany(node0_zaddr, recipients, 1,0) + shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + assert(shielded != None) + y_txids.append(shielded) + self.sync_all() + + # Spends should be in the mempool + assert_equal(set(self.nodes[0].getrawmempool()), set(y_txids)) + assert_equal(set(self.nodes[1].getrawmempool()), set(y_txids)) + + # Node 0 note should be unspendable + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('0')) + + # Invalidate block H - 1. + block_hm1 = self.nodes[0].getbestblockhash() + self.nodes[0].invalidateblock(block_hm1) + + # BUG: Ideally, the mempool should now only contain the transactions + # that were in block H - 1, the Y transactions having been dropped. + # However, because chainActive is not updated until after the transactions + # in the disconnected block have been re-added to the mempool, the height + # seen by AcceptToMemoryPool is one greater than it should be. This causes + # the block H - 1 transactions to be validated against the Y rules, + # and rejected because they (obviously) fail. + #assert_equal(set(self.nodes[0].getrawmempool()), set(block_txids[1:])) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Node 1's mempool is unaffected because it still considers block H - 1 valid. + assert_equal(set(self.nodes[1].getrawmempool()), set(y_txids)) + + # Node 0 note should be spendable again + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('10')) + + # Reconsider block H - 1. + self.nodes[0].reconsiderblock(block_hm1) + + # Mine blocks on node 1, so that the Y transactions in its mempool + # will be cleared. + self.nodes[1].generate(6) + self.sync_all() + + net_version = self.nodes[0].getnetworkinfo()["protocolversion"] + + print('Testing Sapling -> Blossom activation boundary') + # Current height = 195 + nu_activation_checks() + # Current height = 205 + + print('Testing Blossom -> Heartwood activation boundary') + nu_activation_checks() + # Current height = 215 + + print('Testing Heartwood -> Canopy activation boundary') + nu_activation_checks() + # Current height = 225 + + if net_version < NU5_PROTO_VERSION: + print("Node's block index is not NU5-aware, skipping remaining tests") + return + + print('Testing Canopy -> NU5 activation boundary') + nu_activation_checks() + # Current height = 235 + +if __name__ == '__main__': + MempoolUpgradeActivationTest().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_reorg.py b/depend/zcash/qa/rpc-tests/mempool_reorg.py new file mode 100755 index 000000000..e809195dc --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_reorg.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test re-org scenarios with a mempool that contains transactions +# that spend (directly or indirectly) coinbase transactions. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_raises, start_node, connect_nodes + + +# Create one-input, one-output, no-fee transaction: +class MempoolCoinbaseTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = False + + alert_filename = None # Set by setup_network + + def setup_network(self): + args = ["-checkmempool", "-debug=mempool"] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes(self.nodes[1], 0) + self.is_network_split = False + self.sync_all + + def create_tx(self, from_txid, to_address, amount): + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + signresult = self.nodes[0].signrawtransaction(rawtx) + assert_equal(signresult["complete"], True) + return signresult["hex"] + + def run_test(self): + # Mine three blocks. After this, nodes[0] blocks + # 101, 102, and 103 are spend-able. + new_blocks = self.nodes[1].generate(4) + self.sync_all() + + node0_address = self.nodes[0].getnewaddress() + node1_address = self.nodes[1].getnewaddress() + + # Three scenarios for re-orging coinbase spends in the memory pool: + # 1. Direct coinbase spend : spend_101 + # 2. Indirect (coinbase spend in chain, child in mempool) : spend_102 and spend_102_1 + # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1 + # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase), + # and make sure the mempool code behaves correctly. + b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] + coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] + spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 10) + spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 10) + spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 10) + + # Create a block-height-locked transaction which will be invalid after reorg + timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 10}) + # Set the time lock, ensuring we don't clobber the rest of the Sapling v4 tx format + timelock_tx = timelock_tx.replace("ffffffff", "11111111", 1) + timelock_tx = timelock_tx[:-38] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" + timelock_tx[-30:] + timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + + # Broadcast and mine spend_102 and 103: + spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) + spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) + self.nodes[0].generate(1) + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + + # Create 102_1 and 103_1: + spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 10) + spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 10) + + # Broadcast and mine 103_1: + spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) + last_block = self.nodes[0].generate(1) + timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx) + + # ... now put spend_101 and spend_102_1 in memory pools: + spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw) + spend_102_1_id = self.nodes[0].sendrawtransaction(spend_102_1_raw) + + self.sync_all() + + assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, timelock_tx_id ])) + + for node in self.nodes: + node.invalidateblock(last_block[0]) + assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, spend_103_1_id ])) + + # Use invalidateblock to re-org back and make all those coinbase spends + # immature/invalid: + for node in self.nodes: + node.invalidateblock(new_blocks[0]) + + self.sync_all() + + # mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + +if __name__ == '__main__': + MempoolCoinbaseTest().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_resurrect_test.py b/depend/zcash/qa/rpc-tests/mempool_resurrect_test.py new file mode 100755 index 000000000..45b1a6704 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_resurrect_test.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test resurrection of mined transactions when +# the blockchain is re-organized. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, start_node, DEFAULT_FEE + +from decimal import Decimal + + +# Create one-input, one-output, no-fee transaction: +class MempoolCoinbaseTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = False + + def setup_network(self): + # Just need one node for this test + args = ["-checkmempool", "-debug=mempool"] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.is_network_split = False + + def create_tx(self, from_txid, to_address, amount): + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + signresult = self.nodes[0].signrawtransaction(rawtx) + assert_equal(signresult["complete"], True) + return signresult["hex"] + + def run_test(self): + node0_address = self.nodes[0].getnewaddress() + # Spend block 1/2/3's coinbase transactions + # Mine a block. + # Create three more transactions, spending the spends + # Mine another block. + # ... make sure all the transactions are confirmed + # Invalidate both blocks + # ... make sure all the transactions are put back in the mempool + # Mine a new block + # ... make sure all the transactions are confirmed again. + + b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ] + coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] + spends1_raw = [ self.create_tx(txid, node0_address, 10) for txid in coinbase_txids ] + spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ] + + blocks = [] + blocks.extend(self.nodes[0].generate(1)) + + spends2_raw = [ self.create_tx(txid, node0_address, Decimal('10.0') - DEFAULT_FEE) for txid in spends1_id ] + 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()) + for txid in spends1_id+spends2_id: + tx = self.nodes[0].gettransaction(txid) + assert(tx["confirmations"] > 0) + + # Use invalidateblock to re-org back; all transactions should + # end up unconfirmed and back in the mempool + for node in self.nodes: + node.invalidateblock(blocks[0]) + + # mempool should be empty, all txns confirmed + assert_equal(set(self.nodes[0].getrawmempool()), set(spends1_id+spends2_id)) + for txid in spends1_id+spends2_id: + tx = self.nodes[0].gettransaction(txid) + assert(tx["confirmations"] == 0) + + # 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: + tx = self.nodes[0].gettransaction(txid) + assert(tx["confirmations"] > 0) + + +if __name__ == '__main__': + MempoolCoinbaseTest().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_spendcoinbase.py b/depend/zcash/qa/rpc-tests/mempool_spendcoinbase.py new file mode 100755 index 000000000..b692cd513 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_spendcoinbase.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test spending coinbase transactions. +# The coinbase transaction in block N can appear in block +# N+100... so is valid in the mempool when the best block +# height is N+99. +# This test makes sure coinbase spends that will be mature +# in the next block are accepted into the memory pool, +# but less mature coinbase spends are NOT. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, assert_raises, \ + start_node + + +# Create one-input, one-output, no-fee transaction: +class MempoolSpendCoinbaseTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = False + + def setup_network(self): + # Just need one node for this test + args = ["-checkmempool", "-debug=mempool"] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.is_network_split = False + + def create_tx(self, from_txid, to_address, amount): + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + signresult = self.nodes[0].signrawtransaction(rawtx) + assert_equal(signresult["complete"], True) + return signresult["hex"] + + def run_test(self): + chain_height = self.nodes[0].getblockcount() + assert_equal(chain_height, 200) + node0_address = self.nodes[0].getnewaddress() + + # Coinbase at height chain_height-100+1 ok in mempool, should + # get mined. Coinbase at height chain_height-100+2 is + # is too immature to spend. + b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ] + coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] + spends_raw = [ self.create_tx(txid, node0_address, 10) for txid in coinbase_txids ] + + spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) + + # coinbase at height 102 should be too immature to spend + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1]) + + # mempool should have just spend_101: + mempoolinfo = self.nodes[0].getmempoolinfo() + assert_equal(mempoolinfo['size'], 1) + assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) + + # the size of the memory pool should be greater than 1x ~100 bytes + assert_greater_than(mempoolinfo['bytes'], 100) + # the actual memory usage should be strictly greater than the size + # of the memory pool + assert_greater_than(mempoolinfo['usage'], mempoolinfo['bytes']) + + # mine a block, spend_101 should get confirmed + self.nodes[0].generate(1) + mempoolinfo = self.nodes[0].getmempoolinfo() + assert_equal(mempoolinfo['size'], 0) + assert_equal(mempoolinfo['bytes'], 0) + assert_equal(mempoolinfo['usage'], 0) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # ... and now height 102 can be spent: + spend_102_id = self.nodes[0].sendrawtransaction(spends_raw[1]) + mempoolinfo = self.nodes[0].getmempoolinfo() + assert_equal(mempoolinfo['size'], 1) + assert_equal(self.nodes[0].getrawmempool(), [ spend_102_id ]) + assert_greater_than(mempoolinfo['bytes'], 100) + assert_greater_than(mempoolinfo['usage'], mempoolinfo['bytes']) + +if __name__ == '__main__': + MempoolSpendCoinbaseTest().main() diff --git a/depend/zcash/qa/rpc-tests/mempool_tx_expiry.py b/depend/zcash/qa/rpc-tests/mempool_tx_expiry.py new file mode 100755 index 000000000..4e4aec95d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mempool_tx_expiry.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test proper expiry for transactions >= version 4 +# + +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + connect_nodes_bi, sync_blocks, start_nodes, \ + wait_and_assert_operationid_status, DEFAULT_FEE + +from decimal import Decimal + +TX_EXPIRING_SOON_THRESHOLD = 3 +TX_EXPIRY_DELTA = 10 + +class MempoolTxExpiryTest(BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, + [[ + "-txexpirydelta=%d" % TX_EXPIRY_DELTA, + "-debug=mempool" + ]] * self.num_nodes) + + # Test before, at, and after expiry block + # chain is at block height 199 when run_test executes + def run_test(self): + alice = self.nodes[0].getnewaddress() + z_alice = self.nodes[0].z_getnewaddress('sapling') + bob = self.nodes[2].getnewaddress() + z_bob = self.nodes[2].z_getnewaddress('sapling') + + print("Splitting network...") + self.split_network() + + # Test dependent txs + firstTx = self.nodes[0].sendtoaddress(alice, 0.1) + firstTxInfo = self.nodes[0].getrawtransaction(firstTx, 1) + assert_equal(firstTxInfo["version"], 4) + assert_equal(firstTxInfo["overwintered"], True) + assert("expiryheight" in firstTxInfo) + print("First tx expiry height:", firstTxInfo['expiryheight']) + # Mine first transaction + self.nodes[0].generate(1) + for outpoint in firstTxInfo['vout']: + if outpoint['value'] == Decimal('0.10000000'): + vout = outpoint + break + inputs = [{'txid': firstTx, 'vout': vout['n'], 'scriptPubKey': vout['scriptPubKey']['hex']}] + outputs = {alice: 0.1} + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + rawTxSigned = self.nodes[0].signrawtransaction(rawTx) + assert(rawTxSigned['complete']) + secondTx = self.nodes[0].sendrawtransaction(rawTxSigned['hex']) + secondTxInfo = self.nodes[0].getrawtransaction(secondTx, 1) + print("Second tx expiry height:", secondTxInfo['expiryheight']) + # Mine second, dependent transaction + self.nodes[0].generate(1) + print("Mine %d competing blocks on Node 2..." % (2 + TX_EXPIRY_DELTA)) + blocks = self.nodes[2].generate(2 + TX_EXPIRY_DELTA) + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes,0,2) + self.is_network_split = False + print("Syncing blocks") + sync_blocks(self.nodes) + print("Ensure that both txs are dropped from mempool of node 0") + print("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + assert_equal(set(self.nodes[2].getrawmempool()), set()) + + ## Shield one of Alice's coinbase funds to her zaddr + res = self.nodes[0].z_shieldcoinbase("*", z_alice, DEFAULT_FEE, 1) + wait_and_assert_operationid_status(self.nodes[0], res['opid']) + self.nodes[0].generate(1) + self.sync_all() + + # Get balance on node 0 + bal = self.nodes[0].z_gettotalbalance() + print("Balance before zsend, after shielding 10: ", bal) + assert_equal(Decimal(bal["private"]), Decimal('10.0') - DEFAULT_FEE) + + print("Splitting network...") + self.split_network() + + # Create transactions + blockheight = self.nodes[0].getblockchaininfo()['blocks'] + zsendamount = Decimal('1.0') - DEFAULT_FEE + recipients = [] + recipients.append({"address": z_bob, "amount": zsendamount}) + myopid = self.nodes[0].z_sendmany(z_alice, recipients, 1) + persist_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + persist_transparent = self.nodes[0].sendtoaddress(bob, 0.01) + # Verify transparent transaction is version 4 intended for Sapling branch + rawtx = self.nodes[0].getrawtransaction(persist_transparent, 1) + assert_equal(rawtx["version"], 4) + assert_equal(rawtx["overwintered"], True) + assert_equal(rawtx["expiryheight"], blockheight + 1 + TX_EXPIRY_DELTA) + print("Blockheight at persist_transparent & persist_shielded creation:", self.nodes[0].getblockchaininfo()['blocks']) + print("Expiryheight of persist_transparent:", rawtx['expiryheight']) + # Verify shielded transaction is version 4 intended for Sapling branch + rawtx = self.nodes[0].getrawtransaction(persist_shielded, 1) + print("Expiryheight of persist_shielded", rawtx['expiryheight']) + assert_equal(rawtx["version"], 4) + assert_equal(rawtx["overwintered"], True) + assert_equal(rawtx["expiryheight"], blockheight + 1 + TX_EXPIRY_DELTA) + + print("\nBlockheight advances to less than expiry block height. After reorg, txs should persist in mempool") + assert(persist_transparent in self.nodes[0].getrawmempool()) + assert(persist_shielded in self.nodes[0].getrawmempool()) + assert_equal(set(self.nodes[2].getrawmempool()), set()) + print("mempool node 0:", self.nodes[0].getrawmempool()) + print("mempool node 2:", self.nodes[2].getrawmempool()) + bal = self.nodes[0].z_gettotalbalance() + print("Printing balance before persist_shielded & persist_transparent are initially mined from mempool", bal) + # Txs are mined on node 0; will later be rolled back + self.nodes[0].generate(1) + print("Node 0 generated 1 block") + print("Node 0 height:", self.nodes[0].getblockchaininfo()['blocks']) + print("Node 2 height:", self.nodes[2].getblockchaininfo()['blocks']) + bal = self.nodes[0].z_gettotalbalance() + print("Printing balance after persist_shielded & persist_transparent are mined:", bal) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + print("Mine 2 competing blocks on Node 2...") + blocks = self.nodes[2].generate(2) + for block in blocks: + blk = self.nodes[2].getblock(block) + print("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])) + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes,0,2) + self.is_network_split = False + + print("Syncing blocks") + sync_blocks(self.nodes) + + print("Ensure that txs are back in mempool of node 0") + print("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']) + print("mempool node 0: ", self.nodes[0].getrawmempool()) + print("mempool node 2: ", self.nodes[2].getrawmempool()) + assert(persist_transparent in self.nodes[0].getrawmempool()) + assert(persist_shielded in self.nodes[0].getrawmempool()) + bal = self.nodes[0].z_gettotalbalance() + # Mine txs to get them out of the way of mempool sync in split_network() + print("Generating another block on node 0 to clear txs from mempool") + self.nodes[0].generate(1) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + sync_blocks(self.nodes) + + print("Splitting network...") + self.split_network() + + print("\nBlockheight advances to equal expiry block height. After reorg, txs should persist in mempool") + myopid = self.nodes[0].z_sendmany(z_alice, recipients, 1) + persist_shielded_2 = wait_and_assert_operationid_status(self.nodes[0], myopid) + persist_transparent_2 = self.nodes[0].sendtoaddress(bob, 0.01) + rawtx_trans = self.nodes[0].getrawtransaction(persist_transparent_2, 1) + rawtx_shield = self.nodes[0].getrawtransaction(persist_shielded_2, 1) + print("Blockheight node 0 at persist_transparent_2 creation:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2 at persist_transparent_2 creation:", self.nodes[2].getblockchaininfo()['blocks']) + print("Expiryheight of persist_transparent_2:", rawtx_trans['expiryheight']) + print("Expiryheight of persist_shielded_2:", rawtx_shield['expiryheight']) + blocks = self.nodes[2].generate(4) + for block in blocks: + blk = self.nodes[2].getblock(block) + print("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])) + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + print("Ensure that persist_transparent_2 & persist_shielded_2 are in mempool at expiry block height") + print("Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks']) + print("mempool node 0: ", self.nodes[0].getrawmempool()) + print("mempool node 2: ", self.nodes[2].getrawmempool()) + assert(persist_transparent_2 in self.nodes[0].getrawmempool()) + assert(persist_shielded_2 in self.nodes[0].getrawmempool()) + # Mine persist txs to get them out of the way of mempool sync in split_network() + self.nodes[0].generate(1) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + sync_blocks(self.nodes) + print("Balance after persist_shielded_2 is mined to remove from mempool: ", self.nodes[0].z_gettotalbalance()) + + print("Splitting network...") + self.split_network() + + print("\nBlockheight advances to greater than expiry block height. After reorg, txs should expire from mempool") + print("Balance before expire_shielded is sent: ", self.nodes[0].z_gettotalbalance()) + myopid = self.nodes[0].z_sendmany(z_alice, recipients, 1) + expire_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + expire_transparent = self.nodes[0].sendtoaddress(bob, 0.01) + print("Blockheight node 0 at expire_transparent creation:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2 at expire_shielded creation:", self.nodes[2].getblockchaininfo()['blocks']) + print("Expiryheight of expire_transparent:", self.nodes[0].getrawtransaction(expire_transparent, 1)['expiryheight']) + print("Expiryheight of expire_shielded:", self.nodes[0].getrawtransaction(expire_shielded, 1)['expiryheight']) + assert(expire_transparent in self.nodes[0].getrawmempool()) + assert(expire_shielded in self.nodes[0].getrawmempool()) + blocks = self.nodes[2].generate(1 + TX_EXPIRY_DELTA + 1) + for block in blocks: + blk = self.nodes[2].getblock(block) + print("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])) + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + print("Ensure that expire_transparent & expire_shielded are not in mempool after expiry block height") + print("mempool node 0: ", self.nodes[0].getrawmempool()) + print("mempool node 2: ", self.nodes[2].getrawmempool()) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + print("Ensure balance of node 0 is correct") + bal = self.nodes[0].z_gettotalbalance() + print("Balance after expire_shielded has expired: ", bal) + assert_equal(Decimal(bal["private"]), Decimal('8.0') - DEFAULT_FEE) + + print("Splitting network...") + self.split_network() + + print("\nBlockheight advances to just before expiring soon threshold. Txs should be rejected from entering mempool.") + print("Balance before expire_shielded is sent: ", self.nodes[0].z_gettotalbalance()) + myopid = self.nodes[0].z_sendmany(z_alice, recipients, 1) + expire_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + expire_transparent = self.nodes[0].sendtoaddress(bob, 0.01) + print("Blockheight node 0 at expire_transparent creation:", self.nodes[0].getblockchaininfo()['blocks']) + print("Blockheight node 2 at expire_shielded creation:", self.nodes[2].getblockchaininfo()['blocks']) + print("Expiryheight of expire_transparent:", self.nodes[0].getrawtransaction(expire_transparent, 1)['expiryheight']) + print("Expiryheight of expire_shielded:", self.nodes[0].getrawtransaction(expire_shielded, 1)['expiryheight']) + assert(expire_transparent in self.nodes[0].getrawmempool()) + assert(expire_shielded in self.nodes[0].getrawmempool()) + blocks = self.nodes[2].generate(1 + TX_EXPIRY_DELTA - TX_EXPIRING_SOON_THRESHOLD - 1) + for block in blocks: + blk = self.nodes[2].getblock(block) + print("Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"])) + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + print("Ensure that expire_transparent & expire_shielded are in node 0 mempool but not node 2 mempool") + print("mempool node 0: ", self.nodes[0].getrawmempool()) + print("mempool node 2: ", self.nodes[2].getrawmempool()) + assert(expire_transparent in self.nodes[0].getrawmempool()) + assert(expire_shielded in self.nodes[0].getrawmempool()) + assert(expire_transparent not in self.nodes[2].getrawmempool()) + assert(expire_shielded not in self.nodes[2].getrawmempool()) + + # Now try to add the transactions to Node 2 mempool. + # Node 2 mempool will accept a transaction since block height has not reached the expiring soon threshold. + rawtx = self.nodes[0].getrawtransaction(expire_transparent) + self.nodes[2].sendrawtransaction(rawtx) + + # Generate a block and enter the expiring soon threshold. + self.nodes[2].generate(1) + # Node 2 mempool will reject a transaction which is expiring soon. + try: + rawtx = self.nodes[0].getrawtransaction(expire_shielded) + self.nodes[2].sendrawtransaction(rawtx) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("tx-expiring-soon" in errorString) + +if __name__ == '__main__': + MempoolTxExpiryTest().main() diff --git a/depend/zcash/qa/rpc-tests/mergetoaddress_helper.py b/depend/zcash/qa/rpc-tests/mergetoaddress_helper.py new file mode 100755 index 000000000..50f28c8fd --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mergetoaddress_helper.py @@ -0,0 +1,365 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Common code for testing z_mergetoaddress before and after sapling activation +# + +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, connect_nodes_bi, fail, \ + initialize_chain_clean, start_node, sync_blocks, sync_mempools, \ + wait_and_assert_operationid_status, DEFAULT_FEE + +from decimal import Decimal + + +def assert_mergetoaddress_exception(expected_error_msg, merge_to_address_lambda): + try: + merge_to_address_lambda() + except JSONRPCException as e: + assert_equal(expected_error_msg, e.error['message']) + except Exception as e: + fail("Expected JSONRPCException. Found %s" % repr(e)) + else: + fail("Expected exception: %s" % expected_error_msg) + + +class MergeToAddressHelper: + + def __init__(self, addr_type, any_zaddr, utxos_to_generate, utxos_in_tx1, utxos_in_tx2): + self.addr_type = addr_type + self.any_zaddr = [any_zaddr] + self.any_zaddr_or_utxo = [any_zaddr, "ANY_TADDR"] + # utxos_to_generate, utxos_in_tx1, utxos_in_tx2 have to do with testing transaction size limits + self.utxos_to_generate = utxos_to_generate + self.utxos_in_tx1 = utxos_in_tx1 + self.utxos_in_tx2 = utxos_in_tx2 + + def setup_chain(self, test): + print("Initializing test directory "+test.options.tmpdir) + initialize_chain_clean(test.options.tmpdir, 4) + + def setup_network(self, test, additional_args=[]): + args = ['-debug=zrpcunsafe'] + args += additional_args + test.nodes = [] + test.nodes.append(start_node(0, test.options.tmpdir, args)) + test.nodes.append(start_node(1, test.options.tmpdir, args)) + args2 = ['-debug=zrpcunsafe'] + args2 += additional_args + test.nodes.append(start_node(2, test.options.tmpdir, args2)) + connect_nodes_bi(test.nodes, 0, 1) + connect_nodes_bi(test.nodes, 1, 2) + connect_nodes_bi(test.nodes, 0, 2) + test.is_network_split = False + test.sync_all() + + def run_test(self, test): + print("Mining blocks...") + + test.nodes[0].generate(1) + do_not_shield_taddr = test.nodes[0].getnewaddress() + + test.nodes[0].generate(4) + test.sync_all() + walletinfo = test.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 50) + assert_equal(walletinfo['balance'], 0) + test.sync_all() + test.nodes[2].generate(1) + test.nodes[2].getnewaddress() + test.nodes[2].generate(1) + test.nodes[2].getnewaddress() + test.nodes[2].generate(1) + test.sync_all() + test.nodes[1].generate(101) + test.sync_all() + assert_equal(test.nodes[0].getbalance(), 50) + assert_equal(test.nodes[1].getbalance(), 10) + assert_equal(test.nodes[2].getbalance(), 30) + + # Shield the coinbase + myzaddr = test.nodes[0].z_getnewaddress(self.addr_type) + result = test.nodes[0].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + # Prepare some UTXOs and notes for merging + mytaddr = test.nodes[0].getnewaddress() + mytaddr2 = test.nodes[0].getnewaddress() + mytaddr3 = test.nodes[0].getnewaddress() + result = test.nodes[0].z_sendmany(myzaddr, [ + {'address': do_not_shield_taddr, 'amount': 10}, + {'address': mytaddr, 'amount': 10}, + {'address': mytaddr2, 'amount': 10}, + {'address': mytaddr3, 'amount': 10}, + ], 1, 0) + wait_and_assert_operationid_status(test.nodes[0], result) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + # Merging will fail because from arguments need to be in an array + assert_mergetoaddress_exception( + "JSON value is not an array as expected", + lambda: test.nodes[0].z_mergetoaddress("notanarray", myzaddr)) + + # Merging will fail when trying to spend from watch-only address + test.nodes[2].importaddress(mytaddr) + assert_mergetoaddress_exception( + "Could not find any funds to merge.", + lambda: test.nodes[2].z_mergetoaddress([mytaddr], myzaddr)) + + # Merging will fail because fee is negative + assert_mergetoaddress_exception( + "Amount out of range", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, -1)) + + # Merging will fail because fee is larger than MAX_MONEY + assert_mergetoaddress_exception( + "Amount out of range", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, Decimal('21000000.00000001'))) + + # Merging will fail because fee is larger than sum of UTXOs + assert_mergetoaddress_exception( + "Insufficient funds, have 50.00, which is less than miners fee 999.00", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, 999)) + + # Merging will fail because transparent limit parameter must be at least 0 + assert_mergetoaddress_exception( + "Limit on maximum number of UTXOs cannot be negative", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, Decimal('0.001'), -1)) + + # Merging will fail because transparent limit parameter is absurdly large + assert_mergetoaddress_exception( + "JSON integer out of range", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, Decimal('0.001'), 99999999999999)) + + # Merging will fail because shielded limit parameter must be at least 0 + assert_mergetoaddress_exception( + "Limit on maximum number of notes cannot be negative", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, Decimal('0.001'), 50, -1)) + + # Merging will fail because shielded limit parameter is absurdly large + assert_mergetoaddress_exception( + "JSON integer out of range", + lambda: test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, Decimal('0.001'), 50, 99999999999999)) + + # Merging will fail for this specific case where it would spend a fee and do nothing + assert_mergetoaddress_exception( + "Destination address is also the only source address, and all its funds are already merged.", + lambda: test.nodes[0].z_mergetoaddress([mytaddr], mytaddr)) + + # Merging will fail if we try to specify from Sprout AND Sapling + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: test.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], mytaddr)) + + # Merge UTXOs from node 0 of value 30, default fee + result = test.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone + assert_equal(test.nodes[0].getbalance(), 10) + assert_equal(test.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + assert_equal(test.nodes[0].z_getbalance(myzaddr), Decimal('40.0') - DEFAULT_FEE) + assert_equal(test.nodes[1].getbalance(), 40) + assert_equal(test.nodes[2].getbalance(), 30) + + # Shield all notes to another z-addr + myzaddr2 = test.nodes[0].z_getnewaddress(self.addr_type) + result = test.nodes[0].z_mergetoaddress(self.any_zaddr, myzaddr2, 0) + assert_equal(result["mergingUTXOs"], Decimal('0')) + assert_equal(result["remainingUTXOs"], Decimal('0')) + assert_equal(result["mergingNotes"], Decimal('2')) + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + blockhash = test.nodes[1].generate(1) + test.sync_all() + + assert_equal(len(test.nodes[0].getblock(blockhash[0])['tx']), 2) + assert_equal(test.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(test.nodes[0].z_getbalance(myzaddr2), Decimal('40.0') - DEFAULT_FEE) + + # Shield coinbase UTXOs from any node 2 taddr, and set fee to 0 + result = test.nodes[2].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(test.nodes[2], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + assert_equal(test.nodes[0].getbalance(), 10) + assert_equal(test.nodes[0].z_getbalance(myzaddr), Decimal('30')) + assert_equal(test.nodes[0].z_getbalance(myzaddr2), Decimal('40.0') - DEFAULT_FEE) + assert_equal(test.nodes[1].getbalance(), 60) + assert_equal(test.nodes[2].getbalance(), 0) + + # Merge all notes from node 0 into a node 0 taddr, and set fee to 0 + result = test.nodes[0].z_mergetoaddress(self.any_zaddr, mytaddr, 0) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + assert_equal(test.nodes[0].getbalance(), Decimal('80.0') - DEFAULT_FEE) + assert_equal(test.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + assert_equal(test.nodes[0].z_getbalance(mytaddr), Decimal('70.0') - DEFAULT_FEE) + assert_equal(test.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(test.nodes[0].z_getbalance(myzaddr2), 0) + assert_equal(test.nodes[1].getbalance(), 70) + assert_equal(test.nodes[2].getbalance(), 0) + + # Merge all node 0 UTXOs together into a node 1 taddr, and set fee to 0 + test.nodes[1].getnewaddress() # Ensure we have an empty address + n1taddr = test.nodes[1].getnewaddress() + result = test.nodes[0].z_mergetoaddress(["ANY_TADDR"], n1taddr, 0) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + assert_equal(test.nodes[0].getbalance(), 0) + assert_equal(test.nodes[0].z_getbalance(do_not_shield_taddr), 0) + assert_equal(test.nodes[0].z_getbalance(mytaddr), 0) + assert_equal(test.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(test.nodes[1].getbalance(), Decimal('160.0') - DEFAULT_FEE) + assert_equal(test.nodes[1].z_getbalance(n1taddr), Decimal('80.0') - DEFAULT_FEE) + assert_equal(test.nodes[2].getbalance(), 0) + + # Generate self.utxos_to_generate regular UTXOs on node 0, and 20 regular UTXOs on node 2 + mytaddr = test.nodes[0].getnewaddress() + n2taddr = test.nodes[2].getnewaddress() + test.nodes[1].generate(1000) + test.sync_all() + for i in range(self.utxos_to_generate): + test.nodes[1].sendtoaddress(mytaddr, 1) + for i in range(20): + test.nodes[1].sendtoaddress(n2taddr, 1) + test.nodes[1].generate(1) + test.sync_all() + + # Merging the UTXOs will conditionally occur over two transactions, since max tx size is 100,000 bytes before Sapling and 2,000,000 after. + # We don't verify mergingTransparentValue as UTXOs are not selected in any specific order, so value can change on each test run. + # We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of UTXOs. + result = test.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 99999) + assert_equal(result["mergingUTXOs"], self.utxos_in_tx1) + assert_equal(result["remainingUTXOs"], self.utxos_in_tx2) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["mergingShieldedValue"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + assert_equal(result["remainingShieldedValue"], Decimal('0')) + remainingTransparentValue = result["remainingTransparentValue"] + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + + # For sapling we do not check that this occurs over two transactions because of the time that it would take + if self.utxos_in_tx2 > 0: + # Verify that UTXOs are locked (not available for selection) by queuing up another merging operation + result = test.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 0) + assert_equal(result["mergingUTXOs"], self.utxos_in_tx2) + assert_equal(result["mergingTransparentValue"], Decimal(remainingTransparentValue)) + assert_equal(result["remainingUTXOs"], Decimal('0')) + assert_equal(result["remainingTransparentValue"], Decimal('0')) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["mergingShieldedValue"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + assert_equal(result["remainingShieldedValue"], Decimal('0')) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + + # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected. + # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated + # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced. + sync_blocks(test.nodes[:2]) + sync_mempools(test.nodes[:2]) + # Generate enough blocks to ensure all transactions are mined + while test.nodes[1].getmempoolinfo()['size'] > 0: + test.nodes[1].generate(1) + test.sync_all() + + # Verify maximum number of UTXOs which node 2 can shield is not limited + # when the limit parameter is set to 0. + expected_to_merge = 20 + expected_remaining = 0 + + result = test.nodes[2].z_mergetoaddress([n2taddr], myzaddr, DEFAULT_FEE, 0) + assert_equal(result["mergingUTXOs"], expected_to_merge) + assert_equal(result["remainingUTXOs"], expected_remaining) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(test.nodes[2], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + # Verify maximum number of UTXOs which node 0 can shield is set by default limit parameter of 50 + mytaddr = test.nodes[0].getnewaddress() + for i in range(100): + test.nodes[1].sendtoaddress(mytaddr, 1) + test.nodes[1].generate(1) + test.sync_all() + result = test.nodes[0].z_mergetoaddress([mytaddr], myzaddr, DEFAULT_FEE) + assert_equal(result["mergingUTXOs"], Decimal('50')) + assert_equal(result["remainingUTXOs"], Decimal('50')) + assert_equal(result["mergingNotes"], Decimal('0')) + # Remaining notes are only counted if we are trying to merge any notes + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + + # Verify maximum number of UTXOs which node 0 can shield can be set by the limit parameter + result = test.nodes[0].z_mergetoaddress([mytaddr], myzaddr, DEFAULT_FEE, 33) + assert_equal(result["mergingUTXOs"], Decimal('33')) + assert_equal(result["remainingUTXOs"], Decimal('17')) + assert_equal(result["mergingNotes"], Decimal('0')) + # Remaining notes are only counted if we are trying to merge any notes + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit + sync_blocks(test.nodes[:2]) + sync_mempools(test.nodes[:2]) + test.nodes[1].generate(1) + test.sync_all() + + # Verify maximum number of notes which node 0 can shield can be set by the limit parameter + # Also check that we can set off a second merge before the first one is complete + + # myzaddr will have 5 notes if testing before to Sapling activation and 4 otherwise + num_notes = len(test.nodes[0].z_listunspent(0)) + result1 = test.nodes[0].z_mergetoaddress([myzaddr], myzaddr, DEFAULT_FEE, 50, 2) + result2 = test.nodes[0].z_mergetoaddress([myzaddr], myzaddr, DEFAULT_FEE, 50, 2) + + # First merge should select from all notes + assert_equal(result1["mergingUTXOs"], Decimal('0')) + # Remaining UTXOs are only counted if we are trying to merge any UTXOs + assert_equal(result1["remainingUTXOs"], Decimal('0')) + assert_equal(result1["mergingNotes"], Decimal('2')) + assert_equal(result1["remainingNotes"], num_notes - 2) + + # Second merge should ignore locked notes + assert_equal(result2["mergingUTXOs"], Decimal('0')) + assert_equal(result2["remainingUTXOs"], Decimal('0')) + assert_equal(result2["mergingNotes"], Decimal('2')) + assert_equal(result2["remainingNotes"], num_notes - 4) + wait_and_assert_operationid_status(test.nodes[0], result1['opid']) + wait_and_assert_operationid_status(test.nodes[0], result2['opid']) + + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() + + # Shield both UTXOs and notes to a z-addr + result = test.nodes[0].z_mergetoaddress(self.any_zaddr_or_utxo, myzaddr, 0, 10, 2) + assert_equal(result["mergingUTXOs"], Decimal('10')) + assert_equal(result["remainingUTXOs"], Decimal('7')) + assert_equal(result["mergingNotes"], Decimal('2')) + assert_equal(result["remainingNotes"], num_notes - 4) + wait_and_assert_operationid_status(test.nodes[0], result['opid']) + test.sync_all() + test.nodes[1].generate(1) + test.sync_all() diff --git a/depend/zcash/qa/rpc-tests/mergetoaddress_mixednotes.py b/depend/zcash/qa/rpc-tests/mergetoaddress_mixednotes.py new file mode 100755 index 000000000..59e01e5dd --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mergetoaddress_mixednotes.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, get_coinbase_address, \ + initialize_chain_clean, start_nodes, wait_and_assert_operationid_status +from mergetoaddress_helper import assert_mergetoaddress_exception + + +class MergeToAddressMixedNotes(BitcoinTestFramework): + def setup_nodes(self): + self.num_nodes = 4 + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[['-anchorconfirmations=1']] * self.num_nodes) + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def run_test(self): + print("Mining blocks...") + self.nodes[0].generate(102) + self.sync_all() + + # Send some ZEC to Sprout/Sapling addresses + coinbase_addr = get_coinbase_address(self.nodes[0]) + sproutAddr = self.nodes[0].z_getnewaddress('sprout') + saplingAddr = self.nodes[0].z_getnewaddress('sapling') + t_addr = self.nodes[1].getnewaddress() + + result = self.nodes[0].z_shieldcoinbase(coinbase_addr, sproutAddr, 0, 1) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('10')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0')) + # Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sprout Notes + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr)) + opid = self.nodes[0].z_sendmany(coinbase_addr, [{"address": saplingAddr, "amount": Decimal('10')}], 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('0')) + + # Merge Sprout -> taddr + result = self.nodes[0].z_mergetoaddress(["ANY_SPROUT"], t_addr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('10')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('10')) + + # Make sure we cannot use "ANY_SPROUT" and "ANY_SAPLING" even if we only have Sapling Notes + assert_mergetoaddress_exception( + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress", + lambda: self.nodes[0].z_mergetoaddress(["ANY_SPROUT", "ANY_SAPLING"], t_addr)) + # Merge Sapling -> taddr + result = self.nodes[0].z_mergetoaddress(["ANY_SAPLING"], t_addr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].z_getbalance(sproutAddr), Decimal('0')) + assert_equal(self.nodes[0].z_getbalance(saplingAddr), Decimal('0')) + assert_equal(Decimal(self.nodes[1].z_gettotalbalance()["transparent"]), Decimal('20')) + + +if __name__ == '__main__': + MergeToAddressMixedNotes().main() diff --git a/depend/zcash/qa/rpc-tests/mergetoaddress_sapling.py b/depend/zcash/qa/rpc-tests/mergetoaddress_sapling.py new file mode 100755 index 000000000..80c6d9a17 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mergetoaddress_sapling.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from mergetoaddress_helper import MergeToAddressHelper + + +class MergeToAddressSapling (BitcoinTestFramework): + # 13505 would be the maximum number of utxos based on the transaction size limits for Sapling + # but testing this causes the test to take an indeterminately long time to run. + helper = MergeToAddressHelper('sapling', 'ANY_SAPLING', 800, 800, 0) + + def setup_chain(self): + self.helper.setup_chain(self) + + def setup_network(self, split=False): + self.helper.setup_network(self, ['-anchorconfirmations=1']) + + def run_test(self): + self.helper.run_test(self) + + +if __name__ == '__main__': + MergeToAddressSapling().main() diff --git a/depend/zcash/qa/rpc-tests/mergetoaddress_sprout.py b/depend/zcash/qa/rpc-tests/mergetoaddress_sprout.py new file mode 100755 index 000000000..5ca4b0e5f --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mergetoaddress_sprout.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from mergetoaddress_helper import MergeToAddressHelper + + +class MergeToAddressSprout (BitcoinTestFramework): + # 13505 would be the maximum number of utxos based on the transaction size limits for Sapling + # but testing this causes the test to take an indeterminately long time to run. + helper = MergeToAddressHelper('sprout', 'ANY_SPROUT', 800, 800, 0) + + def setup_chain(self): + self.helper.setup_chain(self) + + def setup_network(self, split=False): + self.helper.setup_network(self, ['-anchorconfirmations=1']) + + def run_test(self): + self.helper.run_test(self) + + +if __name__ == '__main__': + MergeToAddressSprout().main() diff --git a/depend/zcash/qa/rpc-tests/merkle_blocks.py b/depend/zcash/qa/rpc-tests/merkle_blocks.py new file mode 100755 index 000000000..2945861b3 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/merkle_blocks.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test merkleblock fetch/validation +# + +import string +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_raises, \ + start_node, connect_nodes + + +class MerkleBlockTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 + + def setup_network(self): + self.nodes = [] + # Nodes 0/1 are "wallet" nodes + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) + # Nodes 2/3 are used for testing + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) + self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-txindex"])) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[0], 3) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + print("Mining blocks...") + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + assert_equal(self.nodes[1].getbalance(), 0) + assert_equal(self.nodes[2].getbalance(), 0) + + node0utxos = self.nodes[0].listunspent(1) + tx1 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 10}) + txid1 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx1)["hex"]) + tx2 = self.nodes[0].createrawtransaction([node0utxos.pop()], {self.nodes[1].getnewaddress(): 10}) + txid2 = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransaction(tx2)["hex"]) + assert_raises(JSONRPCException, self.nodes[0].gettxoutproof, [txid1]) + + self.nodes[0].generate(1) + blockhash = self.nodes[0].getblockhash(chain_height + 1) + self.sync_all() + + txlist = [] + blocktxn = self.nodes[0].getblock(blockhash, True)["tx"] + txlist.append(blocktxn[1]) + txlist.append(blocktxn[2]) + + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1])), [txid1]) + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist) + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2], blockhash)), txlist) + + txin_spent = self.nodes[1].listunspent(1).pop() + tx3 = self.nodes[1].createrawtransaction([txin_spent], {self.nodes[0].getnewaddress(): 10}) + self.nodes[0].sendrawtransaction(self.nodes[1].signrawtransaction(tx3)["hex"]) + self.nodes[0].generate(1) + self.sync_all() + + txid_spent = txin_spent["txid"] + txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2 + + # We can't find the block from a fully-spent tx + assert_raises(JSONRPCException, self.nodes[2].gettxoutproof, [txid_spent]) + # ...but we can if we specify the block + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent]) + # ...or if the first tx is not fully-spent + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent]) + try: + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid1, txid2])), txlist) + except JSONRPCException: + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid2, txid1])), txlist) + # ...or if we have a -txindex + assert_equal(self.nodes[2].verifytxoutproof(self.nodes[3].gettxoutproof([txid_spent])), [txid_spent]) + + # Quick test of getblock using blockhash and different levels of verbosity + result = self.nodes[0].getblock(blockhash, 2) + coinbase_txid = result["tx"][0]["txid"] + result = self.nodes[0].getblock(blockhash, 1) + assert_equal(coinbase_txid, result["tx"][0]) # verbosity 1 only lists txids + result = self.nodes[0].getblock(blockhash, 0) + assert(c in string.hexdigits for c in result) # verbosity 0 returns raw hex + + # Test getblock heights including negatives relative to the head + assert_equal(self.nodes[0].getblock("0")["height"], 0) + assert_raises(JSONRPCException, self.nodes[0].getblock, ["108"]) + assert_equal(self.nodes[0].getblock("107")["height"], 107) + assert_equal(self.nodes[0].getblock("-1")["height"], 107) + assert_equal(self.nodes[0].getblock("-2")["height"], 106) + assert_equal(self.nodes[0].getblock("-20")["height"], 88) + assert_equal(self.nodes[0].getblock("-107")["height"], 1) + assert_equal(self.nodes[0].getblock("-108")["height"], 0) + assert_raises(JSONRPCException, self.nodes[0].getblock, ["-109"]) + assert_raises(JSONRPCException, self.nodes[0].getblock, ["-0"]) + + # Test getblockhash negative heights + assert_equal(self.nodes[0].getblockhash(-1), self.nodes[0].getblockhash(107)) + assert_equal(self.nodes[0].getblockhash(-2), self.nodes[0].getblockhash(106)) + +if __name__ == '__main__': + MerkleBlockTest().main() diff --git a/depend/zcash/qa/rpc-tests/mining_shielded_coinbase.py b/depend/zcash/qa/rpc-tests/mining_shielded_coinbase.py new file mode 100755 index 000000000..3dee057e3 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/mining_shielded_coinbase.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.mininode import COIN, nuparams +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, + assert_raises, + bitcoind_processes, + connect_nodes, + start_node, + wait_and_assert_operationid_status, + check_node_log, +) + +class ShieldCoinbaseTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def start_node_with(self, index, extra_args=[]): + args = [ + nuparams(BLOSSOM_BRANCH_ID, 1), + nuparams(HEARTWOOD_BRANCH_ID, 10), + nuparams(CANOPY_BRANCH_ID, 20), + nuparams(NU5_BRANCH_ID, 20), + "-nurejectoldversions=false", + ] + return start_node(index, self.options.tmpdir, args + extra_args) + + def setup_network(self, split=False): + self.nodes = [] + self.nodes.append(self.start_node_with(0)) + self.nodes.append(self.start_node_with(1)) + connect_nodes(self.nodes[1], 0) + self.is_network_split=False + self.sync_all() + + def run_test (self): + # Generate a Sapling address for node 1 + node1_zaddr = self.nodes[1].z_getnewaddress('sapling') + + self.nodes[1].stop() + bitcoind_processes[1].wait() + self.nodes[1] = self.start_node_with(1, [ + "-mineraddress=%s" % node1_zaddr, + ]) + connect_nodes(self.nodes[1], 0) + + # Node 0 can mine blocks, because it is targeting a transparent address + print("Mining block with node 0") + self.nodes[0].generate(1) + self.sync_all() + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 5) + assert_equal(walletinfo['balance'], 0) + + # Node 1 cannot mine blocks, because it is targeting a Sapling address + # but Heartwood is not yet active + print("Attempting to mine block with node 1") + assert_raises(JSONRPCException, self.nodes[1].generate, 1) + assert_equal(self.nodes[1].z_getbalance(node1_zaddr, 0), 0) + assert_equal(self.nodes[1].z_getbalance(node1_zaddr), 0) + + # Stop node 1 and check logs to verify the block was rejected correctly + string_to_find = "CheckTransaction(): coinbase has output descriptions" + check_node_log(self, 1, string_to_find) + + # Restart node 1 + self.nodes[1] = self.start_node_with(1, ["-mineraddress=%s" % node1_zaddr]) + connect_nodes(self.nodes[1], 0) + + # Activate Heartwood + print("Activating Heartwood") + self.nodes[0].generate(8) + self.sync_all() + + # Node 1 can now mine blocks! + print("Mining block with node 1") + self.nodes[1].generate(1) + self.sync_all() + + # Transparent coinbase outputs are subject to coinbase maturity + assert_equal(self.nodes[0].getbalance(), Decimal('0')) + assert_equal(self.nodes[0].z_gettotalbalance()['transparent'], '0.00') + assert_equal(self.nodes[0].z_gettotalbalance()['private'], '0.00') + assert_equal(self.nodes[0].z_gettotalbalance()['total'], '0.00') + + # Shielded coinbase outputs are not subject to coinbase maturity + assert_equal(self.nodes[1].z_getbalance(node1_zaddr, 0), 5) + assert_equal(self.nodes[1].z_getbalance(node1_zaddr), 5) + assert_equal(self.nodes[1].z_gettotalbalance()['private'], '5.00') + assert_equal(self.nodes[1].z_gettotalbalance()['total'], '5.00') + + # Send from Sapling coinbase to Sapling address and transparent address + # (to check that a non-empty vout is allowed when spending shielded + # coinbase) + print("Sending Sapling coinbase to Sapling address") + node0_zaddr = self.nodes[0].z_getnewaddress('sapling') + node0_taddr = self.nodes[0].getnewaddress() + recipients = [] + recipients.append({"address": node0_zaddr, "amount": Decimal('2')}) + recipients.append({"address": node0_taddr, "amount": Decimal('2')}) + myopid = self.nodes[1].z_sendmany(node1_zaddr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], myopid) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), 2) + assert_equal(self.nodes[0].z_getbalance(node0_taddr), 2) + assert_equal(self.nodes[1].z_getbalance(node1_zaddr), 1) + + # Generate a Unified Address for node 1 + self.nodes[1].z_getnewaccount() + node1_addr0 = self.nodes[1].z_getaddressforaccount(0) + assert_equal(node1_addr0['account'], 0) + assert_equal(set(node1_addr0['receiver_types']), set(['p2pkh', 'sapling', 'orchard'])) + node1_ua = node1_addr0['address'] + + # Set node 1's miner address to the UA + self.nodes[1].stop() + bitcoind_processes[1].wait() + self.nodes[1] = self.start_node_with(1, [ + "-mineraddress=%s" % node1_ua, + ]) + connect_nodes(self.nodes[1], 0) + + # The UA starts with zero balance. + assert_equal(self.nodes[1].z_getbalanceforaccount(0)['pools'], {}) + + # Node 1 can mine blocks because the miner selects the Sapling receiver + # of its UA. + print("Mining block with node 1") + self.nodes[1].generate(1) + self.sync_all() + + # The UA balance should show that Sapling funds were received. + assert_equal(self.nodes[1].z_getbalanceforaccount(0)['pools'], { + 'sapling': {'valueZat': 5 * COIN }, + }) + + # Activate NU5 + print("Activating NU5") + self.nodes[0].generate(7) + self.sync_all() + + # Now any block mined by node 1 should use the Orchard receiver of its UA. + print("Mining block with node 1") + self.nodes[1].generate(1) + self.sync_all() + assert_equal(self.nodes[1].z_getbalanceforaccount(0)['pools'], { + 'sapling': {'valueZat': 5 * COIN }, + # 6.25 ZEC because the FR always ends when Canopy activates, and + # regtest has no defined funding streams. + 'orchard': {'valueZat': 6.25 * COIN }, + }) + +if __name__ == '__main__': + ShieldCoinbaseTest().main() diff --git a/depend/zcash/qa/rpc-tests/multi_rpc.py b/depend/zcash/qa/rpc-tests/multi_rpc.py new file mode 100755 index 000000000..7263c0b2b --- /dev/null +++ b/depend/zcash/qa/rpc-tests/multi_rpc.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test multiple rpc user config option rpcauth +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import str_to_b64str, assert_equal + +import os +import http.client +import urllib.parse + +class HTTPBasicsTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = False + self.num_nodes = 1 + + def setup_chain(self): + super().setup_chain() + #Append rpcauth to zcash.conf before initialization + rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" + rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" + with open(os.path.join(self.options.tmpdir+"/node0", "zcash.conf"), 'a', encoding='utf8') as f: + f.write(rpcauth+"\n") + f.write(rpcauth2+"\n") + + def setup_network(self): + self.nodes = self.setup_nodes() + + def run_test(self): + + ################################################## + # Check correctness of the rpcauth config option # + ################################################## + url = urllib.parse.urlparse(self.nodes[0].url) + + #Old authpair + authpair = url.username + ':' + url.password + + #New authpair generated via share/rpcuser tool + #rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" + password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM=" + + #Second authpair with different username + #rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" + password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI=" + authpairnew = "rt:"+password + + headers = {"Authorization": "Basic " + str_to_b64str(authpair)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Use new authpair to confirm both work + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Wrong login name with rt's password + authpairnew = "rtwrong:"+password + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + #Wrong password for rt + authpairnew = "rt:"+password+"wrong" + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + #Correct for rt2 + authpairnew = "rt2:"+password2 + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, False) + conn.close() + + #Wrong password for rt2 + authpairnew = "rt2:"+password2+"wrong" + headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)} + + conn = http.client.HTTPConnection(url.hostname, url.port) + conn.connect() + conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) + resp = conn.getresponse() + assert_equal(resp.status==401, True) + conn.close() + + +if __name__ == '__main__': + HTTPBasicsTest ().main () diff --git a/depend/zcash/qa/rpc-tests/nodehandling.py b/depend/zcash/qa/rpc-tests/nodehandling.py new file mode 100755 index 000000000..59cdbd60c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/nodehandling.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test node handling +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes_bi, p2p_port, \ + start_node, stop_node + +import time +import urllib.parse + +class NodeHandlingTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def run_test(self): + ########################### + # setban/listbanned tests # + ########################### + assert_equal(len(self.nodes[2].getpeerinfo()), 4) #we should have 4 nodes at this point + self.nodes[2].setban("127.0.0.1", "add") + time.sleep(3) #wait till the nodes are disconnected + assert_equal(len(self.nodes[2].getpeerinfo()), 0) #all nodes must be disconnected at this point + assert_equal(len(self.nodes[2].listbanned()), 1) + self.nodes[2].clearbanned() + assert_equal(len(self.nodes[2].listbanned()), 0) + self.nodes[2].setban("127.0.0.0/24", "add") + assert_equal(len(self.nodes[2].listbanned()), 1) + try: + self.nodes[2].setban("127.0.0.1", "add") #throws exception because 127.0.0.1 is within range 127.0.0.0/24 + except: + pass + assert_equal(len(self.nodes[2].listbanned()), 1) #still only one banned ip because 127.0.0.1 is within the range of 127.0.0.0/24 + try: + self.nodes[2].setban("127.0.0.1", "remove") + except: + pass + assert_equal(len(self.nodes[2].listbanned()), 1) + self.nodes[2].setban("127.0.0.0/24", "remove") + assert_equal(len(self.nodes[2].listbanned()), 0) + self.nodes[2].clearbanned() + assert_equal(len(self.nodes[2].listbanned()), 0) + + ##test persisted banlist + self.nodes[2].setban("127.0.0.0/32", "add") + self.nodes[2].setban("127.0.0.0/24", "add") + self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds + self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds + listBeforeShutdown = self.nodes[2].listbanned(); + assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here + time.sleep(2) #make 100% sure we expired 192.168.0.1 node time + + #stop node + stop_node(self.nodes[2], 2) + + self.nodes[2] = start_node(2, self.options.tmpdir) + listAfterShutdown = self.nodes[2].listbanned(); + assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) + assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) + assert_equal("/19" in listAfterShutdown[2]['address'], True) + + ########################### + # RPC disconnectnode test # + ########################### + url = urllib.parse.urlparse(self.nodes[1].url) + self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1))) + time.sleep(2) #disconnecting a node needs a little bit of time + for node in self.nodes[0].getpeerinfo(): + assert(node['addr'] != url.hostname+":"+str(p2p_port(1))) + + connect_nodes_bi(self.nodes,0,1) #reconnect the node + found = False + for node in self.nodes[0].getpeerinfo(): + if node['addr'] == url.hostname+":"+str(p2p_port(1)): + found = True + assert(found) + +if __name__ == '__main__': + NodeHandlingTest ().main () diff --git a/depend/zcash/qa/rpc-tests/nuparams.py b/depend/zcash/qa/rpc-tests/nuparams.py new file mode 100755 index 000000000..b90fee231 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/nuparams.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + start_nodes, + nuparams, + nustr, + OVERWINTER_BRANCH_ID, + SAPLING_BRANCH_ID, + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, +) + + +class NuparamsTest(BitcoinTestFramework): + ''' + Test that unspecified network upgrades are activated automatically; + this is really more of a test of the test framework. + ''' + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self, split=False): + args = [[ + nuparams(HEARTWOOD_BRANCH_ID, 3), + nuparams(NU5_BRANCH_ID, 5), + ] * self.num_nodes] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, args) + self.is_network_split = False + self.sync_all() + + def run_test(self): + node = self.nodes[0] + # No blocks have been created, only the genesis block exists (height 0) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 0) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'pending') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'pending') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + + # start_node() hardcodes Sapling and Overwinter to activate a height 1 + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 1) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 2) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'pending') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'pending') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(2) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 4) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'pending') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'pending') + + node.generate(1) + bci = node.getblockchaininfo() + assert_equal(bci['blocks'], 5) + upgrades = bci['upgrades'] + + overwinter = upgrades[nustr(OVERWINTER_BRANCH_ID)] + assert_equal(overwinter['name'], 'Overwinter') + assert_equal(overwinter['activationheight'], 1) + assert_equal(overwinter['status'], 'active') + + sapling = upgrades[nustr(SAPLING_BRANCH_ID)] + assert_equal(sapling['name'], 'Sapling') + assert_equal(sapling['activationheight'], 1) + assert_equal(sapling['status'], 'active') + + blossom = upgrades[nustr(BLOSSOM_BRANCH_ID)] + assert_equal(blossom['name'], 'Blossom') + assert_equal(blossom['activationheight'], 3) + assert_equal(blossom['status'], 'active') + + heartwood = upgrades[nustr(HEARTWOOD_BRANCH_ID)] + assert_equal(heartwood['name'], 'Heartwood') + assert_equal(heartwood['activationheight'], 3) + assert_equal(heartwood['status'], 'active') + + canopy = upgrades[nustr(CANOPY_BRANCH_ID)] + assert_equal(canopy['name'], 'Canopy') + assert_equal(canopy['activationheight'], 5) + assert_equal(canopy['status'], 'active') + + nu5 = upgrades[nustr(NU5_BRANCH_ID)] + assert_equal(nu5['name'], 'NU5') + assert_equal(nu5['activationheight'], 5) + assert_equal(nu5['status'], 'active') + + +if __name__ == '__main__': + NuparamsTest().main() diff --git a/depend/zcash/qa/rpc-tests/orchard_reorg.py b/depend/zcash/qa/rpc-tests/orchard_reorg.py new file mode 100755 index 000000000..57f48ea14 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/orchard_reorg.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test the effect of reorgs on the Orchard commitment tree. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +from finalsaplingroot import ORCHARD_TREE_EMPTY_ROOT + +from decimal import Decimal + +class OrchardReorgTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ + nuparams(BLOSSOM_BRANCH_ID, 1), + nuparams(HEARTWOOD_BRANCH_ID, 5), + nuparams(CANOPY_BRANCH_ID, 5), + nuparams(NU5_BRANCH_ID, 10), + '-nurejectoldversions=false', + ]] * self.num_nodes) + + def run_test(self): + # Activate NU5 so we can test Orchard. + self.nodes[0].generate(10) + self.sync_all() + + # Generate a UA with only an Orchard receiver. + account = self.nodes[0].z_getnewaccount()['account'] + addr = self.nodes[0].z_getaddressforaccount(account, ['orchard']) + assert_equal(addr['account'], account) + assert_equal(set(addr['receiver_types']), set(['orchard'])) + ua = addr['address'] + + # Before mining any Orchard notes, finalorchardroot should be the empty Orchard root. + assert_equal( + ORCHARD_TREE_EMPTY_ROOT, + self.nodes[0].getblock(self.nodes[0].getbestblockhash())['finalorchardroot'], + ) + + # finalorchardroot should not change if we mine additional blocks without Orchard notes. + self.nodes[0].generate(100) + self.sync_all() + assert_equal( + ORCHARD_TREE_EMPTY_ROOT, + self.nodes[0].getblock(self.nodes[0].getbestblockhash())['finalorchardroot'], + ) + + # Create an Orchard note. + recipients = [{'address': ua, 'amount': Decimal('12.5')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], opid) + + # After mining a block, finalorchardroot should have changed. + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + orchardroot_oneleaf = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['finalorchardroot'] + print("Root of Orchard commitment tree with one leaf:", orchardroot_oneleaf) + assert(orchardroot_oneleaf != ORCHARD_TREE_EMPTY_ROOT) + + # finalorchardroot should not change if we mine additional blocks without Orchard notes. + self.nodes[0].generate(4) + self.sync_all() + assert_equal( + orchardroot_oneleaf, + self.nodes[0].getblock(self.nodes[0].getbestblockhash())['finalorchardroot'], + ) + + # Split the network so we can test the effect of a reorg. + print("Splitting the network") + self.split_network() + + # Create another Orchard note on node 0. + recipients = [{'address': ua, 'amount': Decimal('12.5')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], opid) + + # Mine two blocks on node 0. + print("Mining 2 blocks on node 0") + self.nodes[0].generate(2) + self.sync_all() + orchardroot_twoleaf = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['finalorchardroot'] + print("Root of Orchard commitment tree with two leaves:", orchardroot_twoleaf) + assert(orchardroot_twoleaf != ORCHARD_TREE_EMPTY_ROOT) + assert(orchardroot_twoleaf != orchardroot_oneleaf) + + # Generate 10 blocks on node 2. + print("Mining alternate chain on node 2") + self.nodes[2].generate(10) + self.sync_all() + assert_equal( + orchardroot_oneleaf, + self.nodes[2].getblock(self.nodes[2].getbestblockhash())['finalorchardroot'], + ) + + # Reconnect the nodes; node 0 will re-org to node 2's chain. + print("Re-joining the network so that node 0 reorgs") + self.join_network() + + # Verify that node 0's latest Orchard root matches what we expect. + orchardroot_postreorg = self.nodes[0].getblock(self.nodes[2].getbestblockhash())['finalorchardroot'] + print("Root of Orchard commitment tree after reorg:", orchardroot_postreorg) + assert_equal(orchardroot_postreorg, orchardroot_oneleaf) + + +if __name__ == '__main__': + OrchardReorgTest().main() diff --git a/depend/zcash/qa/rpc-tests/p2p-acceptblock.py b/depend/zcash/qa/rpc-tests/p2p-acceptblock.py new file mode 100755 index 000000000..83ef7ba97 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p-acceptblock.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.mininode import CBlockHeader, CInv, NodeConn, NodeConnCB, \ + NetworkThread, msg_block, msg_headers, msg_inv, msg_ping, msg_pong, \ + mininode_lock +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + start_node, p2p_port, ZCASHD_BINARY +from test_framework.blocktools import create_block, create_coinbase + +import os +import time + +''' +AcceptBlockTest -- test processing of unrequested blocks. + +Since behavior differs when receiving unrequested blocks from whitelisted peers +versus non-whitelisted peers, this tests the behavior of both (effectively two +separate tests running in parallel). + +Setup: two nodes, node0 and node1, not connected to each other. Node0 does not +whitelist localhost, but node1 does. They will each be on their own chain for +this test. + +We have one NodeConn connection to each, test_node and white_node respectively. + +The test: +1. Generate one block on each node, to leave IBD. + +2. Mine a new block on each tip, and deliver to each node from node's peer. + The tip should advance. + +3. Mine a block that forks the previous block, and deliver to each node from + corresponding peer. + Node0 should not process this block (just accept the header), because it is + unrequested and doesn't have more work than the tip. + Node1 should process because this is coming from a whitelisted peer. + +4. Send another block that builds on the forking block. + Node0 should process this block but be stuck on the shorter chain, because + it's missing an intermediate block. + Node1 should reorg to this longer chain. + +4b.Send 288 more blocks on the longer chain. + Node0 should process all but the last block (too far ahead in height). + Send all headers to Node1, and then send the last block in that chain. + Node1 should accept the block because it's coming from a whitelisted peer. + +5. Send a duplicate of the block in #3 to Node0. + Node0 should not process the block because it is unrequested, and stay on + the shorter chain. + +6. Send Node0 an inv for the height 3 block produced in #4 above. + Node0 should figure out that Node0 has the missing height 2 block and send a + getdata. + +7. Send Node0 the missing block again. + Node0 should process and the tip should advance. +''' + +# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending +# p2p messages to a node, generating the messages in the main testing logic. +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + self.connection = None + self.ping_counter = 1 + self.last_pong = msg_pong() + + def add_connection(self, conn): + self.connection = conn + + # Track the last getdata message we receive (used in the test) + def on_getdata(self, conn, message): + self.last_getdata = message + + # Spin until verack message is received from the node. + # We use this to signal that our test can begin. This + # is called from the testing thread, so it needs to acquire + # the global lock. + def wait_for_verack(self): + while True: + with mininode_lock: + if self.verack_received: + return + time.sleep(0.05) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_pong(self, conn, message): + self.last_pong = message + + # Sync up with the node after delivery of a block + def sync_with_ping(self, timeout=30): + self.connection.send_message(msg_ping(nonce=self.ping_counter)) + received_pong = False + sleep_time = 0.05 + while not received_pong and timeout > 0: + time.sleep(sleep_time) + timeout -= sleep_time + with mininode_lock: + if self.last_pong.nonce == self.ping_counter: + received_pong = True + self.ping_counter += 1 + return received_pong + + +class AcceptBlockTest(BitcoinTestFramework): + def add_options(self, parser): + parser.add_option("--testbinary", dest="testbinary", + default=os.getenv("ZCASHD", ZCASHD_BINARY), + help="zcashd binary to test") + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 2 + + def setup_network(self): + # Node0 will be used to test behavior of processing unrequested blocks + # from peers which are not whitelisted, while Node1 will be used for + # the whitelisted case. + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"], + binary=self.options.testbinary)) + self.nodes.append(start_node(1, self.options.tmpdir, + ["-debug", "-whitelist=127.0.0.1"], + binary=self.options.testbinary)) + + def run_test(self): + # Setup the p2p connections and start up the network thread. + test_node = TestNode() # connects to node0 (not whitelisted) + white_node = TestNode() # connects to node1 (whitelisted) + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], white_node)) + test_node.add_connection(connections[0]) + white_node.add_connection(connections[1]) + + NetworkThread().start() # Start up network handling in another thread + + # Test logic begins here + test_node.wait_for_verack() + white_node.wait_for_verack() + + # 1. Have both nodes mine a block (leave IBD) + [ n.generate(1) for n in self.nodes ] + tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ] + + # 2. Send one block that builds on each tip. + # This should be accepted. + blocks_h2 = [] # the height 2 blocks on each node's chain + block_time = int(time.time()) + 1 + for i in range(2): + blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) + blocks_h2[i].solve() + block_time += 1 + test_node.send_message(msg_block(blocks_h2[0])) + white_node.send_message(msg_block(blocks_h2[1])) + + [ x.sync_with_ping() for x in [test_node, white_node] ] + assert_equal(self.nodes[0].getblockcount(), 2) + assert_equal(self.nodes[1].getblockcount(), 2) + print("First height 2 block accepted by both nodes") + + # 3. Send another block that builds on the original tip. + blocks_h2f = [] # Blocks at height 2 that fork off the main chain + for i in range(2): + blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1)) + blocks_h2f[i].solve() + test_node.send_message(msg_block(blocks_h2f[0])) + white_node.send_message(msg_block(blocks_h2f[1])) + + [ x.sync_with_ping() for x in [test_node, white_node] ] + for x in self.nodes[0].getchaintips(): + if x['hash'] == blocks_h2f[0].hash: + assert_equal(x['status'], "headers-only") + + for x in self.nodes[1].getchaintips(): + if x['hash'] == blocks_h2f[1].hash: + assert_equal(x['status'], "valid-headers") + + print("Second height 2 block accepted only from whitelisted peer") + + # 4. Now send another block that builds on the forking chain. + blocks_h3 = [] + for i in range(2): + blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1)) + blocks_h3[i].solve() + test_node.send_message(msg_block(blocks_h3[0])) + white_node.send_message(msg_block(blocks_h3[1])) + + [ x.sync_with_ping() for x in [test_node, white_node] ] + # Since the earlier block was not processed by node0, the new block + # can't be fully validated. + for x in self.nodes[0].getchaintips(): + if x['hash'] == blocks_h3[0].hash: + assert_equal(x['status'], "headers-only") + + # But this block should be accepted by node0 since it has more work. + try: + self.nodes[0].getblock(blocks_h3[0].hash) + print("Unrequested more-work block accepted from non-whitelisted peer") + except: + raise AssertionError("Unrequested more work block was not processed") + + # Node1 should have accepted and reorged. + assert_equal(self.nodes[1].getblockcount(), 3) + print("Successfully reorged to length 3 chain from whitelisted peer") + + # 4b. Now mine 288 more blocks and deliver; all should be processed but + # the last (height-too-high) on node0. Node1 should process the tip if + # we give it the headers chain leading to the tip. + tips = blocks_h3 + headers_message = msg_headers() + all_blocks = [] # node0's blocks + for j in range(2): + for i in range(288): + next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1) + next_block.solve() + if j==0: + test_node.send_message(msg_block(next_block)) + all_blocks.append(next_block) + else: + headers_message.headers.append(CBlockHeader(next_block)) + tips[j] = next_block + + time.sleep(2) + for x in all_blocks: + try: + self.nodes[0].getblock(x.hash) + if x == all_blocks[287]: + raise AssertionError("Unrequested block too far-ahead should have been ignored") + except: + if x == all_blocks[287]: + print("Unrequested block too far-ahead not processed") + else: + raise AssertionError("Unrequested block with more work should have been accepted") + + headers_message.headers.pop() # Ensure the last block is unrequested + white_node.send_message(headers_message) # Send headers leading to tip + white_node.send_message(msg_block(tips[1])) # Now deliver the tip + try: + white_node.sync_with_ping() + self.nodes[1].getblock(tips[1].hash) + print("Unrequested block far ahead of tip accepted from whitelisted peer") + except: + raise AssertionError("Unrequested block from whitelisted peer not accepted") + + # 5. Test handling of unrequested block on the node that didn't process + # Should still not be processed (even though it has a child that has more + # work). + test_node.send_message(msg_block(blocks_h2f[0])) + + # Here, if the sleep is too short, the test could falsely succeed (if the + # node hasn't processed the block by the time the sleep returns, and then + # the node processes it and incorrectly advances the tip). + # But this would be caught later on, when we verify that an inv triggers + # a getdata request for this block. + test_node.sync_with_ping() + assert_equal(self.nodes[0].getblockcount(), 2) + print("Unrequested block that would complete more-work chain was ignored") + + # 6. Try to get node to request the missing block. + # Poke the node with an inv for block at height 3 and see if that + # triggers a getdata on block 2 (it should if block 2 is missing). + with mininode_lock: + # Clear state so we can check the getdata request + test_node.last_getdata = None + test_node.send_message(msg_inv([CInv(2, blocks_h3[0].sha256)])) + + test_node.sync_with_ping() + with mininode_lock: + getdata = test_node.last_getdata + + # Check that the getdata includes the right block + assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256) + print("Inv at tip triggered getdata for unprocessed block") + + # 7. Send the missing block for the third time (now it is requested) + test_node.send_message(msg_block(blocks_h2f[0])) + + test_node.sync_with_ping() + assert_equal(self.nodes[0].getblockcount(), 290) + print("Successfully reorged to longer chain from non-whitelisted peer") + + [ c.disconnect_node() for c in connections ] + +if __name__ == '__main__': + AcceptBlockTest().main() diff --git a/depend/zcash/qa/rpc-tests/p2p-fullblocktest.py b/depend/zcash/qa/rpc-tests/p2p-fullblocktest.py new file mode 100755 index 000000000..17cc3572c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p-fullblocktest.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import ComparisonTestFramework +from test_framework.blocktools import (create_block, create_coinbase) +from test_framework.comptool import TestManager, TestInstance +from test_framework.key import CECKey +from test_framework.mininode import ( + CBlockHeader, + COutPoint, + CTransaction, + CTxIn, + CTxOut, + NetworkThread, +) +from test_framework.script import CScript, SignatureHash, SIGHASH_ALL, OP_CHECKSIG, OP_TRUE +from test_framework.util import SAPLING_BRANCH_ID +import random +import time + +class PreviousSpendableOutput(object): + def __init__(self, tx = CTransaction(), n = -1): + self.tx = tx + self.n = n # the output we're spending + +''' +This reimplements tests from the bitcoinj/FullBlockTestGenerator used +by the pull-tester. + +We use the testing framework in which we expect a particular answer from +each test. +''' + +class FullBlockTest(ComparisonTestFramework): + + ''' Can either run this test as 1 node with expected answers, or two and compare them. + Change the "outcome" variable from each TestInstance object to only do the comparison. ''' + def __init__(self): + super().__init__() + self.block_heights = {} + self.coinbase_key = CECKey() + self.coinbase_key.set_secretbytes(b"horsebattery") + self.coinbase_pubkey = self.coinbase_key.get_pubkey() + self.block_time = int(time.time())+1 + self.tip = None + self.blocks = {} + + def run_test(self): + test = TestManager(self, self.options.tmpdir) + test.add_all_connections(self.nodes) + NetworkThread().start() # Start up network handling in another thread + test.run() + + def add_transactions_to_block(self, block, tx_list): + [ tx.rehash() for tx in tx_list ] + block.vtx.extend(tx_list) + block.hashMerkleRoot = block.calc_merkle_root() + block.rehash() + return block + + # Create a block on top of self.tip, and advance self.tip to point to the new block + # if spend is specified, then 1 satoshi will be spent from that to an anyone-can-spend output, + # and rest will go to fees. + def next_block(self, number, spend=None, additional_coinbase_value=0, script=None): + if self.tip == None: + base_block_hash = self.genesis_hash + else: + base_block_hash = self.tip.sha256 + # First create the coinbase + height = self.block_heights[base_block_hash] + 1 + coinbase = create_coinbase(height, self.coinbase_pubkey) + coinbase.vout[0].nValue += additional_coinbase_value + if (spend != None): + coinbase.vout[0].nValue += spend.tx.vout[spend.n].nValue - 1 # all but one satoshi to fees + coinbase.rehash() + block = create_block(base_block_hash, coinbase, self.block_time) + if (spend != None): + tx = CTransaction() + tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), b"", 0xffffffff)) # no signature yet + # This copies the java comparison tool testing behavior: the first + # txout has a garbage scriptPubKey, "to make sure we're not + # pre-verifying too much" (?) + tx.vout.append(CTxOut(0, CScript([random.randint(0,255), height & 255]))) + if script == None: + tx.vout.append(CTxOut(1, CScript([OP_TRUE]))) + else: + tx.vout.append(CTxOut(1, script)) + # Now sign it if necessary + scriptSig = b"" + scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey) + if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend + scriptSig = CScript([OP_TRUE]) + else: + # We have to actually sign it + (sighash, err) = SignatureHash( + spend.tx.vout[spend.n].scriptPubKey, + tx, + 0, + SIGHASH_ALL, + spend.tx.vout[spend.n].nValue, + SAPLING_BRANCH_ID, + ) + scriptSig = CScript([self.coinbase_key.sign(sighash) + bytes(bytearray([SIGHASH_ALL]))]) + tx.vin[0].scriptSig = scriptSig + # Now add the transaction to the block + block = self.add_transactions_to_block(block, [tx]) + block.solve() + self.tip = block + self.block_heights[block.sha256] = height + self.block_time += 1 + assert number not in self.blocks + self.blocks[number] = block + return block + + def get_tests(self): + self.genesis_hash = int(self.nodes[0].getbestblockhash(), 16) + self.block_heights[self.genesis_hash] = 0 + spendable_outputs = [] + + # save the current tip so it can be spent by a later block + def save_spendable_output(): + spendable_outputs.append(self.tip) + + # get an output that we previous marked as spendable + def get_spendable_output(): + return PreviousSpendableOutput(spendable_outputs.pop(0).vtx[0], 0) + + # returns a test case that asserts that the current tip was accepted + def accepted(): + return TestInstance([[self.tip, True]]) + + # returns a test case that asserts that the current tip was rejected + def rejected(): + return TestInstance([[self.tip, False]]) + + # move the tip back to a previous block + def tip(number): + self.tip = self.blocks[number] + + # creates a new block and advances the tip to that block + block = self.next_block + + + # Create a new block + block(0) + save_spendable_output() + yield accepted() + + + # Now we need that block to mature so we can spend the coinbase. + test = TestInstance(sync_every_block=False) + for i in range(100): + block(1000 + i) + test.blocks_and_transactions.append([self.tip, True]) + save_spendable_output() + yield test + + + # Start by building a couple of blocks on top (which output is spent is in parentheses): + # genesis -> b1 (0) -> b2 (1) + out0 = get_spendable_output() + block(1, spend=out0) + save_spendable_output() + yield accepted() + + out1 = get_spendable_output() + block(2, spend=out1) + # Inv again, then deliver twice (shouldn't break anything). + yield accepted() + + + # so fork like this: + # + # genesis -> b1 (0) -> b2 (1) + # \-> b3 (1) + # + # Nothing should happen at this point. We saw b2 first so it takes priority. + tip(1) + block(3, spend=out1) + # Deliver twice (should still not break anything) + yield rejected() + + + # Now we add another block to make the alternative chain longer. + # + # genesis -> b1 (0) -> b2 (1) + # \-> b3 (1) -> b4 (2) + out2 = get_spendable_output() + block(4, spend=out2) + yield accepted() + + + # ... and back to the first chain. + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b3 (1) -> b4 (2) + tip(2) + block(5, spend=out2) + save_spendable_output() + yield rejected() + + out3 = get_spendable_output() + block(6, spend=out3) + yield accepted() + + + # Try to create a fork that double-spends + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b7 (2) -> b8 (4) + # \-> b3 (1) -> b4 (2) + tip(5) + block(7, spend=out2) + yield rejected() + + out4 = get_spendable_output() + block(8, spend=out4) + yield rejected() + + + # Try to create a block that has too much fee + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b9 (4) + # \-> b3 (1) -> b4 (2) + tip(6) + block(9, spend=out4, additional_coinbase_value=1) + yield rejected() + + + # Create a fork that ends in a block with too much fee (the one that causes the reorg) + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b10 (3) -> b11 (4) + # \-> b3 (1) -> b4 (2) + tip(5) + block(10, spend=out3) + yield rejected() + + block(11, spend=out4, additional_coinbase_value=1) + yield rejected() + + + # Try again, but with a valid fork first + # genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3) + # \-> b12 (3) -> b13 (4) -> b14 (5) + # (b12 added last) + # \-> b3 (1) -> b4 (2) + tip(5) + b12 = block(12, spend=out3) + save_spendable_output() + #yield TestInstance([[b12, False]]) + b13 = block(13, spend=out4) + # Deliver the block header for b12, and the block b13. + # b13 should be accepted but the tip won't advance until b12 is delivered. + yield TestInstance([[CBlockHeader(b12), None], [b13, False]]) + + save_spendable_output() + out5 = get_spendable_output() + # b14 is invalid, but the node won't know that until it tries to connect + # Tip still can't advance because b12 is missing + block(14, spend=out5, additional_coinbase_value=1) + yield rejected() + + yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13. + + + # Test that a block with a lot of checksigs is okay + lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50 - 1)) + tip(13) + block(15, spend=out5, script=lots_of_checksigs) + yield accepted() + + + # Test that a block with too many checksigs is rejected + out6 = get_spendable_output() + too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50)) + block(16, spend=out6, script=too_many_checksigs) + yield rejected() + + + +if __name__ == '__main__': + FullBlockTest().main() diff --git a/depend/zcash/qa/rpc-tests/p2p_node_bloom.py b/depend/zcash/qa/rpc-tests/p2p_node_bloom.py new file mode 100755 index 000000000..505cf98a3 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p_node_bloom.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + msg_filteradd, msg_filterclear, mininode_lock, 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 + + +class TestNode(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + self.connection = None + + def add_connection(self, conn): + self.connection = conn + + # Spin until verack message is received from the node. + # We use this to signal that our test can begin. This + # is called from the testing thread, so it needs to acquire + # the global lock. + def wait_for_verack(self): + while True: + with mininode_lock: + if self.verack_received: + return + time.sleep(0.05) + + # Wrapper for the NodeConn's send_message function + def send_message(self, message): + self.connection.send_message(message) + + def on_close(self, conn): + pass + + def on_reject(self, conn, message): + conn.rejectMessage = message + + +class NodeBloomTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = start_nodes(2, self.options.tmpdir, + extra_args=[['-nopeerbloomfilters', '-enforcenodebloom'], []]) + + def run_test(self): + nobf_node = TestNode() + bf_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], nobf_node)) + connections.append(NodeConn('127.0.0.1', p2p_port(1), self.nodes[1], bf_node)) + nobf_node.add_connection(connections[0]) + bf_node.add_connection(connections[1]) + + # Start up network handling in another thread + NetworkThread().start() + + nobf_node.wait_for_verack() + bf_node.wait_for_verack() + + # Verify mininodes are connected to zcashd nodes + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + + # Mininodes send filterclear message to zcashd node. + nobf_node.send_message(msg_filterclear()) + bf_node.send_message(msg_filterclear()) + + time.sleep(3) + + # Verify mininodes are still connected to zcashd nodes + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + + # Mininodes send filteradd message to zcashd node. + nobf_node.send_message(msg_filteradd()) + bf_node.send_message(msg_filteradd()) + + time.sleep(3) + + # Verify NoBF mininode has been dropped, and BF mininode is still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SAPLING_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + + [ c.disconnect_node() for c in connections ] + +if __name__ == '__main__': + NodeBloomTest().main() diff --git a/depend/zcash/qa/rpc-tests/p2p_nu_peer_management.py b/depend/zcash/qa/rpc-tests/p2p_nu_peer_management.py new file mode 100755 index 000000000..d06a815bb --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p_nu_peer_management.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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 range(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/depend/zcash/qa/rpc-tests/p2p_txexpiringsoon.py b/depend/zcash/qa/rpc-tests/p2p_txexpiringsoon.py new file mode 100755 index 000000000..4cc4a38c7 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p_txexpiringsoon.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.authproxy import JSONRPCException +from test_framework.mininode import NodeConn, NetworkThread, CInv, \ + msg_mempool, msg_getdata, msg_tx, mininode_lock, SAPLING_PROTO_VERSION +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes_bi, fail, \ + p2p_port, start_nodes, sync_blocks, sync_mempools +from tx_expiry_helper import TestNode, create_transaction + + +class TxExpiringSoonTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = True + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + connect_nodes_bi(self.nodes, 0, 1) + # We don't connect node 2 + + def send_transaction(self, testnode, block, address, expiry_height): + tx = create_transaction(self.nodes[0], + block, + address, + 10.0, + expiry_height) + testnode.send_message(msg_tx(tx)) + + # Sync up with node after p2p messages delivered + testnode.sync_with_ping() + + # Sync nodes 0 and 1 + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + + return tx + + def verify_inv(self, testnode, tx): + # Make sure we are synced before sending the mempool message + testnode.sync_with_ping() + + # Send p2p message "mempool" to receive contents from zcashd node in "inv" message + with mininode_lock: + testnode.last_inv = None + testnode.send_message(msg_mempool()) + + # Sync up with node after p2p messages delivered + testnode.sync_with_ping(waiting_for=lambda x: x.last_inv) + + with mininode_lock: + msg = testnode.last_inv + assert_equal(len(msg.inv), 1) + assert_equal(tx.sha256, msg.inv[0].hash) + + def send_data_message(self, testnode, tx): + # Send p2p message "getdata" to verify tx gets sent in "tx" message + getdatamsg = msg_getdata() + getdatamsg.inv = [CInv(1, tx.sha256)] + with mininode_lock: + testnode.last_notfound = None + testnode.last_tx = None + testnode.send_message(getdatamsg) + + def verify_last_tx(self, testnode, tx): + # Sync up with node after p2p messages delivered + testnode.sync_with_ping() + + # Verify data received in "tx" message is for tx + with mininode_lock: + incoming_tx = testnode.last_tx.tx + incoming_tx.rehash() + assert_equal(tx.sha256, incoming_tx.sha256) + + def run_test(self): + testnode0 = TestNode() + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + testnode0, "regtest", SAPLING_PROTO_VERSION)) + testnode0.add_connection(connections[0]) + + # Start up network handling in another thread + NetworkThread().start() + testnode0.wait_for_verack() + + # Verify mininodes are connected to zcashd nodes + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + assert_equal(0, peerinfo[0]["banscore"]) + + # Mine some blocks so we can spend + coinbase_blocks = self.nodes[0].generate(200) + node_address = self.nodes[0].getnewaddress() + + # Sync nodes 0 and 1 + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + + # Verify block count + assert_equal(self.nodes[0].getblockcount(), 200) + assert_equal(self.nodes[1].getblockcount(), 200) + assert_equal(self.nodes[2].getblockcount(), 0) + + # Mininodes send expiring soon transaction in "tx" message to zcashd node + self.send_transaction(testnode0, coinbase_blocks[0], node_address, 203) + + # Assert that the tx is not in the mempool (expiring soon) + assert_equal([], self.nodes[0].getrawmempool()) + assert_equal([], self.nodes[1].getrawmempool()) + assert_equal([], self.nodes[2].getrawmempool()) + + # Mininodes send transaction in "tx" message to zcashd node + tx2 = self.send_transaction(testnode0, coinbase_blocks[1], node_address, 204) + + # tx2 is not expiring soon + assert_equal([tx2.hash], self.nodes[0].getrawmempool()) + assert_equal([tx2.hash], self.nodes[1].getrawmempool()) + # node 2 is isolated + assert_equal([], self.nodes[2].getrawmempool()) + + # Verify txid for tx2 + self.verify_inv(testnode0, tx2) + self.send_data_message(testnode0, tx2) + self.verify_last_tx(testnode0, tx2) + + # Sync and mine an empty block with node 2, leaving tx in the mempool of node0 and node1 + for blkhash in coinbase_blocks: + blk = self.nodes[0].getblock(blkhash, 0) + self.nodes[2].submitblock(blk) + self.nodes[2].generate(1) + + # Verify block count + assert_equal(self.nodes[0].getblockcount(), 200) + assert_equal(self.nodes[1].getblockcount(), 200) + assert_equal(self.nodes[2].getblockcount(), 201) + + # Reconnect node 2 to the network + connect_nodes_bi(self.nodes, 0, 2) + + # Set up test node for node 2 + testnode2 = TestNode() + connections.append(NodeConn('127.0.0.1', p2p_port(2), self.nodes[2], + testnode2, "regtest", SAPLING_PROTO_VERSION)) + testnode2.add_connection(connections[-1]) + + # Verify block count + sync_blocks(self.nodes[:3]) + assert_equal(self.nodes[0].getblockcount(), 201) + assert_equal(self.nodes[1].getblockcount(), 201) + assert_equal(self.nodes[2].getblockcount(), 201) + + # Verify contents of mempool + assert_equal([tx2.hash], self.nodes[0].getrawmempool()) + assert_equal([tx2.hash], self.nodes[1].getrawmempool()) + assert_equal([], self.nodes[2].getrawmempool()) + + # Confirm tx2 cannot be submitted to a mempool because it is expiring soon. + try: + rawtx2 = tx2.serialize().hex() + self.nodes[2].sendrawtransaction(rawtx2) + fail("Sending transaction should have failed") + except JSONRPCException as e: + assert_equal( + "tx-expiring-soon: expiryheight is 204 but should be at least 205 to avoid transaction expiring soon", + e.error['message'] + ) + + self.send_data_message(testnode0, tx2) + + # Sync up with node after p2p messages delivered + testnode0.sync_with_ping() + + # Verify node 0 does not reply to "getdata" by sending "tx" message, as tx2 is expiring soon + with mininode_lock: + assert_equal(testnode0.last_tx, None) + + # Verify mininode received a "notfound" message containing the txid of tx2 + with mininode_lock: + msg = testnode0.last_notfound + assert_equal(len(msg.inv), 1) + assert_equal(tx2.sha256, msg.inv[0].hash) + + # Create a transaction to verify that processing of "getdata" messages is functioning + tx3 = self.send_transaction(testnode0, coinbase_blocks[2], node_address, 999) + + self.send_data_message(testnode0, tx3) + self.verify_last_tx(testnode0, tx3) + # Verify txid for tx3 is returned in "inv", but tx2 which is expiring soon is not returned + self.verify_inv(testnode0, tx3) + self.verify_inv(testnode2, tx3) + + # Verify contents of mempool + assert_equal({tx2.hash, tx3.hash}, set(self.nodes[0].getrawmempool())) + assert_equal({tx2.hash, tx3.hash}, set(self.nodes[1].getrawmempool())) + assert_equal({tx3.hash}, set(self.nodes[2].getrawmempool())) + + # Verify banscore for nodes are still zero + assert_equal(0, sum(peer["banscore"] for peer in self.nodes[0].getpeerinfo())) + assert_equal(0, sum(peer["banscore"] for peer in self.nodes[2].getpeerinfo())) + + [c.disconnect_node() for c in connections] + + +if __name__ == '__main__': + TxExpiringSoonTest().main() diff --git a/depend/zcash/qa/rpc-tests/p2p_txexpiry_dos.py b/depend/zcash/qa/rpc-tests/p2p_txexpiry_dos.py new file mode 100755 index 000000000..e1b7e9e1e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/p2p_txexpiry_dos.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.mininode import NodeConn, NetworkThread, \ + msg_tx, SAPLING_PROTO_VERSION +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_nodes, p2p_port, assert_equal +from tx_expiry_helper import TestNode, create_transaction + +import time + + +class TxExpiryDoSTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def setup_network(self): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + + def run_test(self): + test_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test_node, "regtest", SAPLING_PROTO_VERSION)) + test_node.add_connection(connections[0]) + + # Start up network handling in another thread + NetworkThread().start() + + test_node.wait_for_verack() + + # Verify mininodes are connected to zcashd nodes + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + assert_equal(0, peerinfo[0]["banscore"]) + + coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) + node_address = self.nodes[0].getnewaddress() + + # Mininodes send transaction to zcashd node. + spendtx = create_transaction(self.nodes[0], + coinbase_blocks[0], + node_address, + 1.0, + 101) + test_node.send_message(msg_tx(spendtx)) + + time.sleep(3) + + # Verify test mininode has not been dropped + # and still has a banscore of 0. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + assert_equal(0, peerinfo[0]["banscore"]) + + # Mine a block and resend the transaction + self.nodes[0].generate(1) + test_node.send_message(msg_tx(spendtx)) + + time.sleep(3) + + # Verify test mininode has not been dropped + # but has a banscore of 10. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SAPLING_PROTO_VERSION)) + assert_equal(10, peerinfo[0]["banscore"]) + + [c.disconnect_node() for c in connections] + + +if __name__ == '__main__': + TxExpiryDoSTest().main() diff --git a/depend/zcash/qa/rpc-tests/post_heartwood_rollback.py b/depend/zcash/qa/rpc-tests/post_heartwood_rollback.py new file mode 100755 index 000000000..4f11545ea --- /dev/null +++ b/depend/zcash/qa/rpc-tests/post_heartwood_rollback.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +''' +Test rollbacks on post-Heartwood chains. +''' + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + bitcoind_processes, + connect_nodes_bi, + nuparams, + start_node, + start_nodes, + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, +) + +import logging +import time + +HAS_CANOPY = [nuparams(BLOSSOM_BRANCH_ID, 205), nuparams(HEARTWOOD_BRANCH_ID, 210), nuparams(CANOPY_BRANCH_ID, 220), '-nurejectoldversions=false'] +NO_CANOPY = [nuparams(BLOSSOM_BRANCH_ID, 205), nuparams(HEARTWOOD_BRANCH_ID, 210), '-nurejectoldversions=false'] + +class PostHeartwoodRollbackTest (BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[ + HAS_CANOPY, + HAS_CANOPY, + NO_CANOPY, + NO_CANOPY + ]) + + def run_test (self): + + # Generate shared state beyond Heartwood activation + print("Generating shared state beyond Heartwood activation") + logging.info("Generating initial blocks.") + self.nodes[0].generate(15) + self.sync_all() + + # Split network at block 215 (after Heartwood, before Canopy) + print("Splitting network at block 215 (after Heartwood, before Canopy)") + self.split_network() + + # Activate Canopy on node 0 + print("Activating Canopy on node 0") + self.nodes[0].generate(5) + self.sync_all() + + # Mine past Canopy activation height on node 2 + print("Mining past Canopy activation height on node 2 ") + self.nodes[2].generate(20) + self.sync_all() + + # print("nodes[0].getblockcount()", self.nodes[0].getblockcount()) + # print("nodes[2].getblockcount()", self.nodes[2].getblockcount()) + + # for i in range (0,3,2): + # blockcount = self.nodes[i].getblockcount() + # for j in range (201,blockcount + 1): + # print("\n before shutdown node: ", i, "block: ", j, "\n") + # print(self.nodes[i].getblock(str(j))) + + # Upgrade node 2 and 3 to Canopy + print("Upgrading nodes 2 and 3 to Canopy") + self.nodes[2].stop() + bitcoind_processes[2].wait() + self.nodes[2] = start_node(2, self.options.tmpdir, extra_args=HAS_CANOPY) + + self.nodes[3].stop() + bitcoind_processes[3].wait() + self.nodes[3] = start_node(3, self.options.tmpdir, extra_args=HAS_CANOPY) + + # for i in range (0,3,2): + # blockcount = self.nodes[i].getblockcount() + # for j in range (201,blockcount + 1): + # print("\n after shutdown node: ", i, "block: ", j, "\n") + # print(self.nodes[i].getblock(str(j))) + + # Join network + print("Joining network") + # (if we used self.sync_all() here and there was a bug, the test would hang) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,1,3) + connect_nodes_bi(self.nodes,2,3) + + time.sleep(5) + + # for i in range (0,3,2): + # blockcount = self.nodes[i].getblockcount() + # for j in range (201,blockcount + 1): + # print("\n after sync node: ", i, "block: ", j, "\n") + # print(self.nodes[i].getblock(str(j))) + + node0_blockcount = self.nodes[0].getblockcount() + node2_blockcount = self.nodes[2].getblockcount() + + assert_equal(node0_blockcount, node2_blockcount, "node 0 blockcount: " + str(node0_blockcount) + "node 2 blockcount: " + str(node2_blockcount)) + + node0_bestblockhash = self.nodes[0].getbestblockhash() + node2_bestblockhash = self.nodes[2].getbestblockhash() + + assert_equal(node0_bestblockhash, node2_bestblockhash, "node 0 bestblockhash: " + str(node0_bestblockhash) + "node 2 bestblockhash: " + str(node2_blockcount)) + +if __name__ == '__main__': + PostHeartwoodRollbackTest().main() diff --git a/depend/zcash/qa/rpc-tests/prioritisetransaction.py b/depend/zcash/qa/rpc-tests/prioritisetransaction.py new file mode 100755 index 000000000..a4d215702 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/prioritisetransaction.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes, + initialize_chain_clean, + start_node, + sync_blocks, + sync_mempools, +) +from test_framework.mininode import COIN + +import time + + +class PrioritiseTransactionTest (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): + self.nodes = [] + # Start nodes with tiny block size of 11kb + self.nodes.append(start_node(0, self.options.tmpdir, ["-blockprioritysize=7000", "-blockmaxsize=11000", "-maxorphantx=1000", "-relaypriority=true", "-printpriority=1"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-blockprioritysize=7000", "-blockmaxsize=11000", "-maxorphantx=1000", "-relaypriority=true", "-printpriority=1"])) + connect_nodes(self.nodes[1], 0) + self.is_network_split=False + self.sync_all() + + def run_test (self): + # tx priority is calculated: priority = sum(input_value_in_base_units * input_age)/size_in_bytes + + print("Mining 11kb blocks...") + self.nodes[0].generate(501) + + base_fee = self.nodes[0].getnetworkinfo()['relayfee'] + + # 11 kb blocks will only hold about 50 txs, so this will fill mempool with older txs + taddr = self.nodes[1].getnewaddress() + for _ in range(900): + self.nodes[0].sendtoaddress(taddr, 0.1) + self.nodes[0].generate(1) + sync_blocks(self.nodes) + # With a rate of either 7tx/s or 14tx/s per peer (depending on whether + # the connection is inbound or outbound), syncing this many transactions + # could take up to 128s. So use a higher timeout on the mempool sync. + sync_mempools(self.nodes, timeout=200) + + # Create tx of lower value to be prioritized on node 0 + # Older transactions get mined first, so this lower value, newer tx is unlikely to be mined without prioritisation + priority_tx_0 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + + # Check that priority_tx_0 is not in block_template() prior to prioritisation + block_template = self.nodes[0].getblocktemplate() + in_block_template = False + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + assert_equal(in_block_template, False) + + priority_success = self.nodes[0].prioritisetransaction(priority_tx_0, 1000, int(3 * base_fee * COIN)) + assert(priority_success) + + # Check that prioritized transaction is not in getblocktemplate() + # (not updated because no new txns) + in_block_template = False + block_template = self.nodes[0].getblocktemplate() + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + assert_equal(in_block_template, False) + + # Sending a new transaction will make getblocktemplate refresh within 10s + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + + # Check that prioritized transaction is not in getblocktemplate() + # (too soon) + in_block_template = False + block_template = self.nodes[0].getblocktemplate() + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + assert_equal(in_block_template, False) + + # Check that prioritized transaction is in getblocktemplate() + # getblocktemplate() will refresh after 1 min, or after 10 sec if new transaction is added to mempool + # Mempool is probed every 10 seconds. We'll give getblocktemplate() a maximum of 30 seconds to refresh + block_template = self.nodes[0].getblocktemplate() + start = time.time(); + in_block_template = False + while in_block_template == False: + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + if time.time() - start > 30: + raise AssertionError("Test timed out because prioritised transaction was not returned by getblocktemplate within 30 seconds.") + time.sleep(1) + block_template = self.nodes[0].getblocktemplate() + + assert(in_block_template) + + # Node 1 doesn't get the next block, so this *shouldn't* be mined despite being prioritized on node 1 + priority_tx_1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.1) + self.nodes[1].prioritisetransaction(priority_tx_1, 1000, int(3 * base_fee * COIN)) + + # Mine block on node 0 + blk_hash = self.nodes[0].generate(1) + block = self.nodes[0].getblock(blk_hash[0]) + self.sync_all() + + # Check that priority_tx_0 was mined + mempool = self.nodes[0].getrawmempool() + assert_equal(priority_tx_0 in block['tx'], True) + assert_equal(priority_tx_0 in mempool, False) + + # Check that priority_tx_1 was not mined + assert_equal(priority_tx_1 in mempool, True) + assert_equal(priority_tx_1 in block['tx'], False) + + # Mine a block on node 1 and sync + blk_hash_1 = self.nodes[1].generate(1) + block_1 = self.nodes[1].getblock(blk_hash_1[0]) + self.sync_all() + + # Check to see if priority_tx_1 is now mined + mempool_1 = self.nodes[1].getrawmempool() + assert_equal(priority_tx_1 in mempool_1, False) + assert_equal(priority_tx_1 in block_1['tx'], True) + +if __name__ == '__main__': + PrioritiseTransactionTest().main() diff --git a/depend/zcash/qa/rpc-tests/proxy_test.py b/depend/zcash/qa/rpc-tests/proxy_test.py new file mode 100755 index 000000000..d26f90f7c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/proxy_test.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import socket +import os + +from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, start_nodes +from test_framework.netutil import test_ipv6_local +''' +Test plan: +- Start bitcoind's with different proxy configurations +- Use addnode to initiate connections +- Verify that proxies are connected to, and the right connection command is given +- Proxy configurations to test on bitcoind side: + - `-proxy` (proxy everything) + - `-onion` (proxy just onions) + - `-proxyrandomize` Circuit randomization +- Proxy configurations to test on proxy side, + - support no authentication (other proxy) + - support no authentication + user/pass authentication (Tor) + - proxy on IPv6 + +- Create various proxies (as threads) +- Create bitcoinds that connect to them +- Manipulate the bitcoinds using addnode (onetry) an observe effects + +addnode connect to IPv4 +addnode connect to IPv6 +addnode connect to onion +addnode connect to generic DNS name +''' + +class ProxyTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + self.have_ipv6 = test_ipv6_local() + # Create two proxies on different ports + # ... one unauthenticated + self.conf1 = Socks5Configuration() + self.conf1.addr = ('127.0.0.1', 13000 + (os.getpid() % 1000)) + self.conf1.unauth = True + self.conf1.auth = False + # ... one supporting authenticated and unauthenticated (Tor) + self.conf2 = Socks5Configuration() + self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000)) + self.conf2.unauth = True + self.conf2.auth = True + if self.have_ipv6: + # ... one on IPv6 with similar configuration + self.conf3 = Socks5Configuration() + self.conf3.af = socket.AF_INET6 + self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000)) + self.conf3.unauth = True + self.conf3.auth = True + else: + print("Warning: testing without local IPv6 support") + + self.serv1 = Socks5Server(self.conf1) + self.serv1.start() + self.serv2 = Socks5Server(self.conf2) + self.serv2.start() + if self.have_ipv6: + self.serv3 = Socks5Server(self.conf3) + self.serv3.start() + + def setup_nodes(self): + # Note: proxies are not used to connect to local nodes + # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost + args = [ + ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'], + ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'], + ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'], + [] + ] + if self.have_ipv6: + args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion'] + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=args) + + def node_test(self, node, proxies, auth, test_onion=True): + rv = [] + # Test: outgoing IPv4 connection through node + node.addnode("15.61.23.23:1234", "onetry") + cmd = proxies[0].queue.get() + assert(isinstance(cmd, Socks5Command)) + # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 + assert_equal(cmd.atyp, AddressType.DOMAINNAME) + assert_equal(cmd.addr, b"15.61.23.23") + assert_equal(cmd.port, 1234) + if not auth: + assert_equal(cmd.username, None) + assert_equal(cmd.password, None) + rv.append(cmd) + + if self.have_ipv6: + # Test: outgoing IPv6 connection through node + node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry") + cmd = proxies[1].queue.get() + assert(isinstance(cmd, Socks5Command)) + # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 + assert_equal(cmd.atyp, AddressType.DOMAINNAME) + assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534") + assert_equal(cmd.port, 5443) + if not auth: + assert_equal(cmd.username, None) + assert_equal(cmd.password, None) + rv.append(cmd) + + if test_onion: + # Test: outgoing onion connection through node + node.addnode("bitcoinostk4e4re.onion:8333", "onetry") + cmd = proxies[2].queue.get() + assert(isinstance(cmd, Socks5Command)) + assert_equal(cmd.atyp, AddressType.DOMAINNAME) + assert_equal(cmd.addr, b"bitcoinostk4e4re.onion") + assert_equal(cmd.port, 8333) + if not auth: + assert_equal(cmd.username, None) + assert_equal(cmd.password, None) + rv.append(cmd) + + # Test: outgoing DNS name connection through node + node.addnode("node.noumenon:8333", "onetry") + cmd = proxies[3].queue.get() + assert(isinstance(cmd, Socks5Command)) + assert_equal(cmd.atyp, AddressType.DOMAINNAME) + assert_equal(cmd.addr, b"node.noumenon") + assert_equal(cmd.port, 8333) + if not auth: + assert_equal(cmd.username, None) + assert_equal(cmd.password, None) + rv.append(cmd) + + return rv + + def run_test(self): + # basic -proxy + self.node_test(self.nodes[0], [self.serv1, self.serv1, self.serv1, self.serv1], False) + + # -proxy plus -onion + self.node_test(self.nodes[1], [self.serv1, self.serv1, self.serv2, self.serv1], False) + + # -proxy plus -onion, -proxyrandomize + rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True) + # Check that credentials as used for -proxyrandomize connections are unique + credentials = set((x.username,x.password) for x in rv) + assert_equal(len(credentials), len(rv)) + + if self.have_ipv6: + # proxy on IPv6 localhost + self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False) + + def networks_dict(d): + r = {} + for x in d['networks']: + r[x['name']] = x + return r + + # test RPC getnetworkinfo + n0 = networks_dict(self.nodes[0].getnetworkinfo()) + for net in ['ipv4','ipv6','onion']: + assert_equal(n0[net]['proxy'], '%s:%i' % (self.conf1.addr)) + assert_equal(n0[net]['proxy_randomize_credentials'], True) + assert_equal(n0['onion']['reachable'], True) + + n1 = networks_dict(self.nodes[1].getnetworkinfo()) + for net in ['ipv4','ipv6']: + assert_equal(n1[net]['proxy'], '%s:%i' % (self.conf1.addr)) + assert_equal(n1[net]['proxy_randomize_credentials'], False) + assert_equal(n1['onion']['proxy'], '%s:%i' % (self.conf2.addr)) + assert_equal(n1['onion']['proxy_randomize_credentials'], False) + assert_equal(n1['onion']['reachable'], True) + + n2 = networks_dict(self.nodes[2].getnetworkinfo()) + for net in ['ipv4','ipv6','onion']: + assert_equal(n2[net]['proxy'], '%s:%i' % (self.conf2.addr)) + assert_equal(n2[net]['proxy_randomize_credentials'], True) + assert_equal(n2['onion']['reachable'], True) + + if self.have_ipv6: + n3 = networks_dict(self.nodes[3].getnetworkinfo()) + for net in ['ipv4','ipv6']: + assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr)) + assert_equal(n3[net]['proxy_randomize_credentials'], False) + assert_equal(n3['onion']['reachable'], False) + +if __name__ == '__main__': + ProxyTest().main() + diff --git a/depend/zcash/qa/rpc-tests/pruning.py b/depend/zcash/qa/rpc-tests/pruning.py new file mode 100755 index 000000000..95a18ca92 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/pruning.py @@ -0,0 +1,363 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test pruning code +# ******** +# WARNING: +# This test uses 4GB of disk space. +# This test takes 30 mins or more (up to 2 hours) +# ******** + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import start_node, \ + connect_nodes, stop_node, sync_blocks + +import os.path +import time + +def calc_usage(blockdir): + return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.) + +class PruneTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + + self.utxo = [] + self.address = ["",""] + + # Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create + # So we have big transactions and full blocks to fill up our block files + + # create one script_pubkey + script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes + for i in range (512): + script_pubkey = script_pubkey + "01" + # concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change + self.txouts = "81" + for k in range(128): + # add txout value + self.txouts = self.txouts + "0000000000000000" + # add length of script_pubkey + self.txouts = self.txouts + "fd0402" + # add script_pubkey + self.txouts = self.txouts + script_pubkey + + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + + # Create nodes 0 and 1 to mine + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)) + + # Create node 2 to test pruning + self.nodes.append(start_node(2, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-prune=550"], timewait=900)) + self.prunedir = self.options.tmpdir+"/node2/regtest/blocks/" + + self.address[0] = self.nodes[0].getnewaddress() + self.address[1] = self.nodes[1].getnewaddress() + + # Determine default relay fee + self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"] + + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[1], 2) + connect_nodes(self.nodes[2], 0) + sync_blocks(self.nodes[0:3]) + + def create_big_chain(self): + # Start by creating some coinbases we can spend later + self.nodes[1].generate(200) + sync_blocks(self.nodes[0:2]) + self.nodes[0].generate(150) + # Then mine enough full blocks to create more than 550MiB of data + for i in range(645): + self.mine_full_block(self.nodes[0], self.address[0]) + + sync_blocks(self.nodes[0:3]) + + def test_height_min(self): + if not os.path.isfile(self.prunedir+"blk00000.dat"): + raise AssertionError("blk00000.dat is missing, pruning too early") + print("Success") + print("Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir)) + print("Mining 25 more blocks should cause the first block file to be pruned") + # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this + for i in range(25): + self.mine_full_block(self.nodes[0],self.address[0]) + + waitstart = time.time() + while os.path.isfile(self.prunedir+"blk00000.dat"): + time.sleep(0.1) + if time.time() - waitstart > 10: + raise AssertionError("blk00000.dat not pruned when it should be") + + print("Success") + usage = calc_usage(self.prunedir) + print("Usage should be below target:", usage) + if (usage > 550): + raise AssertionError("Pruning target not being met") + + def create_chain_with_staleblocks(self): + # Create stale blocks in manageable sized chunks + print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds") + + for j in range(12): + # Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain + # Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects + # Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine + stop_node(self.nodes[0],0) + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900) + # Mine 24 blocks in node 1 + self.utxo = self.nodes[1].listunspent() + for i in range(24): + if j == 0: + self.mine_full_block(self.nodes[1],self.address[1]) + else: + self.nodes[1].generate(1) #tx's already in mempool from previous disconnects + + # Reorg back with 25 block chain from node 0 + self.utxo = self.nodes[0].listunspent() + for i in range(25): + self.mine_full_block(self.nodes[0],self.address[0]) + + # Create connections in the order so both nodes can see the reorg at the same time + connect_nodes(self.nodes[1], 0) + connect_nodes(self.nodes[2], 0) + sync_blocks(self.nodes[0:3]) + + print("Usage can be over target because of high stale rate:", calc_usage(self.prunedir)) + + def reorg_test(self): + # Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip + # This will cause Node 2 to do a reorg requiring 288 blocks of undo data to the reorg_test chain + # Reboot node 1 to clear its mempool (hopefully make the invalidate faster) + # Lower the block max size so we don't keep mining all our big mempool transactions (from disconnected blocks) + stop_node(self.nodes[1],1) + self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) + + height = self.nodes[1].getblockcount() + print("Current block height:", height) + + invalidheight = height-287 + badhash = self.nodes[1].getblockhash(invalidheight) + print("Invalidating block at height:",invalidheight,badhash) + self.nodes[1].invalidateblock(badhash) + + # We've now switched to our previously mined-24 block fork on node 1, but that's not what we want + # So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago) + mainchainhash = self.nodes[0].getblockhash(invalidheight - 1) + curhash = self.nodes[1].getblockhash(invalidheight - 1) + while curhash != mainchainhash: + self.nodes[1].invalidateblock(curhash) + curhash = self.nodes[1].getblockhash(invalidheight - 1) + + assert(self.nodes[1].getblockcount() == invalidheight - 1) + print("New best height", self.nodes[1].getblockcount()) + + # Reboot node1 to clear those giant tx's from mempool + stop_node(self.nodes[1],1) + self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900) + + print("Generating new longer chain of 300 more blocks") + self.nodes[1].generate(300) + + print("Reconnect nodes") + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[2], 1) + sync_blocks(self.nodes[0:3]) + + print("Verify height on node 2:",self.nodes[2].getblockcount()) + print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) + + print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)") + self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects + sync_blocks(self.nodes[0:3]) + + usage = calc_usage(self.prunedir) + print("Usage should be below target:", usage) + if (usage > 550): + raise AssertionError("Pruning target not being met") + + return invalidheight,badhash + + def reorg_back(self): + # Verify that a block on the old main chain fork has been pruned away + try: + self.nodes[2].getblock(self.forkhash) + raise AssertionError("Old block wasn't pruned so can't test redownload") + except JSONRPCException: + print("Will need to redownload block",self.forkheight) + + # Verify that we have enough history to reorg back to the fork point + # Although this is more than 288 blocks, because this chain was written more recently + # and only its other 299 small and 220 large block are in the block files after it, + # its expected to still be retained + self.nodes[2].getblock(self.nodes[2].getblockhash(self.forkheight)) + + first_reorg_height = self.nodes[2].getblockcount() + curchainhash = self.nodes[2].getblockhash(self.mainchainheight) + self.nodes[2].invalidateblock(curchainhash) + goalbestheight = self.mainchainheight + goalbesthash = self.mainchainhash2 + + # As of 0.10 the current block download logic is not able to reorg to the original chain created in + # create_chain_with_stale_blocks because it doesn't know of any peer that's on that chain from which to + # redownload its missing blocks. + # Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain + # because it has all the block data. + # However it must mine enough blocks to have a more work chain than the reorg_test chain in order + # to trigger node 2's block download logic. + # At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg + if self.nodes[2].getblockcount() < self.mainchainheight: + blocks_to_mine = first_reorg_height + 1 - self.mainchainheight + print("Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine) + self.nodes[0].invalidateblock(curchainhash) + assert(self.nodes[0].getblockcount() == self.mainchainheight) + assert(self.nodes[0].getbestblockhash() == self.mainchainhash2) + goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1] + goalbestheight = first_reorg_height + 1 + + print("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload") + waitstart = time.time() + while self.nodes[2].getblockcount() < goalbestheight: + time.sleep(0.1) + if time.time() - waitstart > 900: + raise AssertionError("Node 2 didn't reorg to proper height") + assert(self.nodes[2].getbestblockhash() == goalbesthash) + # Verify we can now have the data for a block previously pruned + assert(self.nodes[2].getblock(self.forkhash)["height"] == self.forkheight) + + def mine_full_block(self, node, address): + # Want to create a full block + # We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit + for j in range(14): + if len(self.utxo) < 14: + self.utxo = node.listunspent() + inputs=[] + outputs = {} + t = self.utxo.pop() + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]}) + remchange = t["amount"] - 100*self.relayfee # Fee must be above min relay rate for 66kb tx + outputs[address]=remchange + # Create a basic transaction that will send change back to ourself after account for a fee + # And then insert the 128 generated transaction outs in the middle rawtx[92] is where the # + # of txouts is stored and is the only thing we overwrite from the original transaction + rawtx = node.createrawtransaction(inputs, outputs) + newtx = rawtx[0:92] + newtx = newtx + self.txouts + newtx = newtx + rawtx[94:] + # Appears to be ever so slightly faster to sign with SIGHASH_NONE + signresult = node.signrawtransaction(newtx,None,None,"NONE") + node.sendrawtransaction(signresult["hex"], True) + # Mine a full sized block which will be these transactions we just created + node.generate(1) + + + def run_test(self): + print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)") + print("Mining a big blockchain of 995 blocks") + self.create_big_chain() + # Chain diagram key: + # * blocks on main chain + # +,&,$,@ blocks on other forks + # X invalidated block + # N1 Node 1 + # + # Start by mining a simple chain that all nodes have + # N0=N1=N2 **...*(995) + + print("Check that we haven't started pruning yet because we're below PruneAfterHeight") + self.test_height_min() + # Extend this chain past the PruneAfterHeight + # N0=N1=N2 **...*(1020) + + print("Check that we'll exceed disk space target if we have a very high stale block rate") + self.create_chain_with_staleblocks() + # Disconnect N0 + # And mine a 24 block chain on N1 and a separate 25 block chain on N0 + # N1=N2 **...*+...+(1044) + # N0 **...**...**(1045) + # + # reconnect nodes causing reorg on N1 and N2 + # N1=N2 **...*(1020) *...**(1045) + # \ + # +...+(1044) + # + # repeat this process until you have 12 stale forks hanging off the + # main chain on N1 and N2 + # N0 *************************...***************************(1320) + # + # N1=N2 **...*(1020) *...**(1045) *.. ..**(1295) *...**(1320) + # \ \ \ + # +...+(1044) &.. $...$(1319) + + # Save some current chain state for later use + self.mainchainheight = self.nodes[2].getblockcount() #1320 + self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight) + + print("Check that we can survive a 288 block reorg still") + (self.forkheight,self.forkhash) = self.reorg_test() #(1033, ) + # Now create a 288 block reorg by mining a longer chain on N1 + # First disconnect N1 + # Then invalidate 1033 on main chain and 1032 on fork so height is 1032 on main chain + # N1 **...*(1020) **...**(1032)X.. + # \ + # ++...+(1031)X.. + # + # Now mine 300 more blocks on N1 + # N1 **...*(1020) **...**(1032) @@...@(1332) + # \ \ + # \ X... + # \ \ + # ++...+(1031)X.. .. + # + # Reconnect nodes and mine 220 more blocks on N1 + # N1 **...*(1020) **...**(1032) @@...@@@(1552) + # \ \ + # \ X... + # \ \ + # ++...+(1031)X.. .. + # + # N2 **...*(1020) **...**(1032) @@...@@@(1552) + # \ \ + # \ *...**(1320) + # \ \ + # ++...++(1044) .. + # + # N0 ********************(1032) @@...@@@(1552) + # \ + # *...**(1320) + + print("Test that we can rerequest a block we previously pruned if needed for a reorg") + self.reorg_back() + # Verify that N2 still has block 1033 on current chain (@), but not on main chain (*) + # Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to + # original main chain (*), but will require redownload of some blocks + # In order to have a peer we think we can download from, must also perform this invalidation + # on N0 and mine a new longest chain to trigger. + # Final result: + # N0 ********************(1032) **...****(1553) + # \ + # X@...@@@(1552) + # + # N2 **...*(1020) **...**(1032) **...****(1553) + # \ \ + # \ X@...@@@(1552) + # \ + # +.. + # + # N1 doesn't change because 1033 on main chain (*) is invalid + + print("Done") + +if __name__ == '__main__': + PruneTest().main() diff --git a/depend/zcash/qa/rpc-tests/rawtransactions.py b/depend/zcash/qa/rpc-tests/rawtransactions.py new file mode 100755 index 000000000..a32db8321 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/rawtransactions.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test re-org scenarios with a mempool that contains transactions +# that spend (directly or indirectly) coinbase transactions. +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, \ + start_nodes, connect_nodes_bi, assert_raises + +from decimal import Decimal + +# Create one-input, one-output, no-fee transaction: +class RawTransactionsTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + + #connect to a local machine for debugging + #url = "http://bitcoinrpc:DP6DvqZtqXarpeNWyN3LZTFchCCyCUuHwNF7E8pX99x1@%s:%d" % ('127.0.0.1', 18232) + #proxy = AuthServiceProxy(url) + #proxy.url = url # store URL on proxy for info + #self.nodes.append(proxy) + + 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): + + #prepare some coins for multiple *rawtransaction commands + self.nodes[2].generate(1) + self.sync_all() + self.nodes[0].generate(101) + self.sync_all() + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0); + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0); + self.sync_all() + self.nodes[0].generate(5) + self.sync_all() + + ######################################### + # sendrawtransaction with missing input # + ######################################### + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists + outputs = { self.nodes[0].getnewaddress() : 4.998 } + rawtx = self.nodes[2].createrawtransaction(inputs, outputs) + rawtx = self.nodes[2].signrawtransaction(rawtx) + + errorString = "" + try: + rawtx = self.nodes[2].sendrawtransaction(rawtx['hex']) + except JSONRPCException as e: + errorString = e.error['message'] + + assert_equal("Missing inputs" in errorString, True); + + ##################################### + # getrawtransaction with block hash # + ##################################### + + # make a tx by sending then generate 2 blocks; block1 has the tx in it + tx = self.nodes[2].sendtoaddress(self.nodes[1].getnewaddress(), 1) + block1, block2 = self.nodes[2].generate(2) + self.sync_all() + # We should be able to get the raw transaction by providing the correct block + gottx = self.nodes[0].getrawtransaction(tx, 1, block1) + assert_equal(gottx['txid'], tx) + assert_equal(gottx['in_active_chain'], True) + # We should not have the 'in_active_chain' flag when we don't provide a block + gottx = self.nodes[0].getrawtransaction(tx, 1) + assert_equal(gottx['txid'], tx) + assert 'in_active_chain' not in gottx + # We should have hex for the transaction from the getblock and getrawtransaction calls. + blk = self.nodes[0].getblock(block1, 2) + assert_equal(gottx['hex'], blk['tx'][1]['hex']) + # We should not get the tx if we provide an unrelated block + assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, block2) + # An invalid block hash should raise errors + assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, True) + assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "foobar") + assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "abcd1234") + assert_raises(JSONRPCException, self.nodes[0].getrawtransaction, tx, 1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + + ######################### + # RAW TX MULTISIG TESTS # + ######################### + # 2of2 test + addr1 = self.nodes[2].getnewaddress() + addr2 = self.nodes[2].getnewaddress() + + addr1Obj = self.nodes[2].validateaddress(addr1) + addr2Obj = self.nodes[2].validateaddress(addr2) + + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']]) + mSigObjValid = self.nodes[2].validateaddress(mSigObj) + + #use balance deltas instead of absolute values + bal = self.nodes[2].getbalance() + + # send 1.2 BTC to msig adr + txId = self.nodes[0].sendtoaddress(mSigObj, 1.2); + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance + + + # 2of3 test from different nodes + bal = self.nodes[2].getbalance() + addr1 = self.nodes[1].getnewaddress() + addr2 = self.nodes[2].getnewaddress() + addr3 = self.nodes[2].getnewaddress() + + addr1Obj = self.nodes[1].validateaddress(addr1) + addr2Obj = self.nodes[2].validateaddress(addr2) + addr3Obj = self.nodes[2].validateaddress(addr3) + + mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) + mSigObjValid = self.nodes[2].validateaddress(mSigObj) + assert_equal(mSigObjValid['isvalid'], True) + + txId = self.nodes[0].sendtoaddress(mSigObj, 2.2); + decTx = self.nodes[0].gettransaction(txId) + rawTx = self.nodes[0].decoderawtransaction(decTx['hex']) + sPK = rawTx['vout'][0]['scriptPubKey']['hex'] + [sPK] # hush pyflakes + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # THIS IS A INCOMPLETE FEATURE + # NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION + assert_equal(self.nodes[2].getbalance(), bal) # for now, assume the funds of a 2of3 multisig tx are not marked as spendable + + txDetails = self.nodes[0].gettransaction(txId, True) + rawTx = self.nodes[0].decoderawtransaction(txDetails['hex']) + vout = False + for outpoint in rawTx['vout']: + if outpoint['value'] == Decimal('2.20000000'): + vout = outpoint + break; + + bal = self.nodes[0].getbalance() + inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}] + outputs = { self.nodes[0].getnewaddress() : 2.199 } + rawTx = self.nodes[2].createrawtransaction(inputs, outputs) + rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs) + assert_equal(rawTxPartialSigned['complete'], False) # node1 only has one key, can't comp. sign the tx + + rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs) + assert_equal(rawTxSigned['complete'], True) # node2 can sign the tx compl., own two of three keys + self.nodes[2].sendrawtransaction(rawTxSigned['hex']) + rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex']) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), bal+Decimal('10.00000000')+Decimal('2.19900000')) #block reward + tx + + inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}] + outputs = { self.nodes[0].getnewaddress() : 1 } + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + decrawtx= self.nodes[0].decoderawtransaction(rawtx) + assert_equal(decrawtx['vin'][0]['sequence'], 1000) + +if __name__ == '__main__': + RawTransactionsTest().main() diff --git a/depend/zcash/qa/rpc-tests/receivedby.py b/depend/zcash/qa/rpc-tests/receivedby.py new file mode 100755 index 000000000..e124b0fde --- /dev/null +++ b/depend/zcash/qa/rpc-tests/receivedby.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Exercise the listreceivedbyaddress API + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal + +from decimal import Decimal + +def get_sub_array_from_array(object_array, to_match): + ''' + Finds and returns a sub array from an array of arrays. + to_match should be a unique idetifier of a sub array + ''' + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + return item + return [] + +def check_array_result(object_array, to_match, expected, should_not_find = False): + ''' + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + If the should_not_find flag is true, to_match should not be found in object_array + ''' + if should_not_find == True: + expected = { } + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0 and should_not_find != True: + raise AssertionError("No objects matched %s"%(str(to_match))) + if num_matched > 0 and should_not_find == True: + raise AssertionError("Objects was matched %s"%(str(to_match))) + +class ReceivedByTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def run_test(self): + ''' + listreceivedbyaddress Test + ''' + # Send from node 0 to 1 + addr = self.nodes[1].getnewaddress() + txid = self.nodes[0].sendtoaddress(addr, 0.1) + self.sync_all() + + # Check not listed in listreceivedbyaddress because has 0 confirmations + check_array_result(self.nodes[1].listreceivedbyaddress(), + {"address":addr}, + { }, + True) + # Bury Tx under 10 block so it will be returned by listreceivedbyaddress + self.nodes[1].generate(10) + self.sync_all() + check_array_result(self.nodes[1].listreceivedbyaddress(), + {"address":addr}, + {"address":addr, "account":"", "amount":Decimal("0.1"), "amountZat":10000000, "confirmations":10, "txids":[txid,]}) + # With min confidence < 10 + check_array_result(self.nodes[1].listreceivedbyaddress(5), + {"address":addr}, + {"address":addr, "account":"", "amount":Decimal("0.1"), "amountZat":10000000, "confirmations":10, "txids":[txid,]}) + # With min confidence > 10, should not find Tx + check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True) + + # Empty Tx + addr = self.nodes[1].getnewaddress() + check_array_result(self.nodes[1].listreceivedbyaddress(0,True), + {"address":addr}, + {"address":addr, "account":"", "amount":0, "confirmations":0, "amountZat":0, "txids":[]}) + + ''' + getreceivedbyaddress Test + ''' + # Send from node 0 to 1 + addr = self.nodes[1].getnewaddress() + txid = self.nodes[0].sendtoaddress(addr, 0.1) + self.sync_all() + + # Check balance is 0 because of 0 confirmations + balance = self.nodes[1].getreceivedbyaddress(addr) + assert_equal(balance, Decimal("0.0"), "Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) + + + # Check balance is 0.1 + balance = self.nodes[1].getreceivedbyaddress(addr,0) + assert_equal(balance, Decimal("0.1"), "Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) + + # Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress + self.nodes[1].generate(10) + self.sync_all() + balance = self.nodes[1].getreceivedbyaddress(addr) + assert_equal(balance, Decimal("0.1"), "Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) + + # Get balance as integer + balance = self.nodes[1].getreceivedbyaddress(addr, 1, True) + assert_equal(balance, 10000000, "Wrong balance returned by getreceivedbyaddress, %i"%(balance)) + + ''' + listreceivedbyaccount + getreceivedbyaccount Test + ''' + # set pre-state + addrArr = self.nodes[1].getnewaddress() + account = self.nodes[1].getaccount(addrArr) + received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(),{"account":account}) + + if len(received_by_account_json) == 0: + raise AssertionError("No accounts found in node") + balance_by_account = self.nodes[1].getreceivedbyaccount(account) + + txid = self.nodes[0].sendtoaddress(addr, 0.1) + self.sync_all() + + # listreceivedbyaccount should return received_by_account_json because of 0 confirmations + check_array_result(self.nodes[1].listreceivedbyaccount(), + {"account":account}, + received_by_account_json) + + # getreceivedbyaccount should return same balance because of 0 confirmations + balance = self.nodes[1].getreceivedbyaccount(account) + assert_equal(balance, balance_by_account, "Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) + + self.nodes[1].generate(10) + self.sync_all() + # listreceivedbyaccount should return updated account balance + check_array_result(self.nodes[1].listreceivedbyaccount(), + {"account":account}, + {"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1")), "amountZat":30000000}) + + # getreceivedbyaccount should return updates balance + balance = self.nodes[1].getreceivedbyaccount(account) + assert_equal(balance, balance_by_account + Decimal("0.1"), "Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) + + # Get balance as integer + balance = self.nodes[1].getreceivedbyaccount(account, 1, True) + assert_equal(balance, 30000000, "Wrong balance returned by getreceivedbyaccount, %i"%(balance)) + + # Create a new account named "mynewaccount" that has a 0 balance + self.nodes[1].getaccountaddress("mynewaccount") + received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(0,True),{"account":"mynewaccount"}) + if len(received_by_account_json) == 0: + raise AssertionError("No accounts found in node") + + # Test listreceivedbyaccount for 0 amount accounts + assert_equal(received_by_account_json["amount"], Decimal("0.0"), "Wrong balance returned by listreceivedbyaccount, %0.2f"%(received_by_account_json["amount"])) + + # Test getreceivedbyaccount for 0 amount accounts + balance = self.nodes[1].getreceivedbyaccount("mynewaccount") + assert_equal(balance, Decimal("0.0"), "Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) + +if __name__ == '__main__': + ReceivedByTest().main() diff --git a/depend/zcash/qa/rpc-tests/regtest_signrawtransaction.py b/depend/zcash/qa/rpc-tests/regtest_signrawtransaction.py new file mode 100755 index 000000000..f2b1f0429 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/regtest_signrawtransaction.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import wait_and_assert_operationid_status + +class RegtestSignrawtransactionTest (BitcoinTestFramework): + + def run_test(self): + self.nodes[0].generate(1) + self.sync_all() + taddr = self.nodes[1].getnewaddress() + zaddr1 = self.nodes[1].z_getnewaddress() + + self.nodes[0].sendtoaddress(taddr, 2.0) + self.nodes[0].generate(1) + self.sync_all() + + # Create and sign Sapling transaction. + # If the incorrect consensus branch id is selected, there will be a signing error. + opid = self.nodes[1].z_sendmany(taddr, [{'address': zaddr1, 'amount': 1}], 1) + wait_and_assert_operationid_status(self.nodes[1], opid) + +if __name__ == '__main__': + RegtestSignrawtransactionTest().main() diff --git a/depend/zcash/qa/rpc-tests/reindex.py b/depend/zcash/qa/rpc-tests/reindex.py new file mode 100755 index 000000000..66e96a854 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/reindex.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test -reindex and -reindex-chainstate with CheckBlockIndex +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + start_node, stop_node, wait_bitcoinds +import time + +class ReindexTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir)) + + def reindex(self, justchainstate=False): + self.nodes[0].generate(3) + blockcount = self.nodes[0].getblockcount() + stop_node(self.nodes[0], 0) + wait_bitcoinds() + self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) + while self.nodes[0].getblockcount() < blockcount: + time.sleep(0.1) + assert_equal(self.nodes[0].getblockcount(), blockcount) + print("Success") + + def run_test(self): + self.reindex(False) + self.reindex(True) + self.reindex(False) + self.reindex(True) + +if __name__ == '__main__': + ReindexTest().main() diff --git a/depend/zcash/qa/rpc-tests/remove_sprout_shielding.py b/depend/zcash/qa/rpc-tests/remove_sprout_shielding.py new file mode 100755 index 000000000..d5d001700 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/remove_sprout_shielding.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_raises_message, + start_nodes, get_coinbase_address, + wait_and_assert_operationid_status, + nuparams, + BLOSSOM_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + CANOPY_BRANCH_ID, + NU5_BRANCH_ID, +) + +import logging + +HAS_CANOPY = [ + '-nurejectoldversions=false', + '-anchorconfirmations=1', + nuparams(BLOSSOM_BRANCH_ID, 205), + nuparams(HEARTWOOD_BRANCH_ID, 210), + nuparams(CANOPY_BRANCH_ID, 220), + nuparams(NU5_BRANCH_ID, 225), +] + +class RemoveSproutShieldingTest (BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[HAS_CANOPY] * self.num_nodes) + + def run_test (self): + + # Generate blocks up to Heartwood activation + logging.info("Generating initial blocks. Current height is 200, advance to 210 (activate Heartwood but not Canopy)") + self.nodes[0].generate(10) + self.sync_all() + + # Shield coinbase to Sprout on node 0. Should pass + sprout_addr = self.nodes[0].z_getnewaddress('sprout') + sprout_addr_node2 = self.nodes[2].z_getnewaddress('sprout') + myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sprout_addr, 0)['opid'] + wait_and_assert_operationid_status(self.nodes[0], myopid) + print("taddr -> Sprout z_shieldcoinbase tx accepted before Canopy on node 0") + + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].z_getbalance(sprout_addr), Decimal('10')) + + # Fund taddr_0 from shielded coinbase on node 0 + taddr_0 = self.nodes[0].getnewaddress() + for _ in range(3): + recipients = [{"address": taddr_0, "amount": Decimal('1')}] + myopid = self.nodes[0].z_sendmany(sprout_addr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Create mergetoaddress taddr -> Sprout transaction and mine on node 0 before it is Canopy-aware. Should pass + merge_tx_0 = self.nodes[0].z_mergetoaddress(["ANY_TADDR"], self.nodes[1].z_getnewaddress('sprout')) + wait_and_assert_operationid_status(self.nodes[0], merge_tx_0['opid']) + print("taddr -> Sprout z_mergetoaddress tx accepted before Canopy on node 0") + + # Mine to one block before Canopy activation on node 0; adding value + # to the Sprout pool will fail now since the transaction must be + # included in the next (or later) block, after Canopy has activated. + self.nodes[0].generate(5) + self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'pending') + + # Shield coinbase to Sprout on node 0. Should fail + sprout_addr = self.nodes[0].z_getnewaddress('sprout') + assert_raises_message( + JSONRPCException, + "Sprout shielding is not supported after Canopy", + self.nodes[0].z_shieldcoinbase, + get_coinbase_address(self.nodes[0]), sprout_addr, 0) + print("taddr -> Sprout z_shieldcoinbase tx rejected at Canopy activation on node 0") + + # Create taddr -> Sprout z_sendmany transaction on node 0. Should fail + sprout_addr = self.nodes[1].z_getnewaddress('sprout') + assert_raises_message( + JSONRPCException, + "Sending funds into the Sprout value pool is not supported by z_sendmany", + self.nodes[0].z_sendmany, + taddr_0, [{"address": sprout_addr, "amount": 1}]) + print("taddr -> Sprout z_sendmany tx rejected at Canopy activation on node 0") + + # Create z_mergetoaddress [taddr, Sprout] -> Sprout transaction on node 0. Should fail + assert_raises_message( + JSONRPCException, + "Sprout shielding is not supported after Canopy", + self.nodes[0].z_mergetoaddress, + ["ANY_TADDR", "ANY_SPROUT"], self.nodes[1].z_getnewaddress('sprout')) + print("[taddr, Sprout] -> Sprout z_mergetoaddress tx rejected at Canopy activation on node 0") + + # Create z_mergetoaddress Sprout -> Sprout transaction on node 0. Should pass + merge_tx_1 = self.nodes[0].z_mergetoaddress(["ANY_SPROUT"], self.nodes[1].z_getnewaddress('sprout')) + wait_and_assert_operationid_status(self.nodes[0], merge_tx_1['opid']) + print("Sprout -> Sprout z_mergetoaddress tx accepted at Canopy activation on node 0") + + # Activate Canopy + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'active') + + # Generating a Sprout address should fail after Canopy. + assert_raises_message( + JSONRPCException, + "Invalid address type, \"sprout\" is not allowed after Canopy", + self.nodes[0].z_getnewaddress, 'sprout') + print("Sprout z_getnewaddress rejected at Canopy activation on node 0") + + # Shield coinbase to Sapling on node 0. Should pass + sapling_addr = self.nodes[0].z_getnewaddress('sapling') + myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sapling_addr, 0)['opid'] + wait_and_assert_operationid_status(self.nodes[0], myopid) + print("taddr -> Sapling z_shieldcoinbase tx accepted after Canopy on node 0") + + # Mine to one block before NU5 activation. + self.nodes[0].generate(4) + self.sync_all() + + # Create z_mergetoaddress Sprout -> Sprout transaction on node 1. Should pass + merge_tx_2 = self.nodes[1].z_mergetoaddress(["ANY_SPROUT"], sprout_addr_node2) + wait_and_assert_operationid_status(self.nodes[1], merge_tx_2['opid']) + print("Sprout -> Sprout z_mergetoaddress tx accepted at NU5 activation on node 1") + + self.nodes[1].generate(1) + self.sync_all() + +if __name__ == '__main__': + RemoveSproutShieldingTest().main() diff --git a/depend/zcash/qa/rpc-tests/reorg_limit.py b/depend/zcash/qa/rpc-tests/reorg_limit.py new file mode 100755 index 000000000..47286db13 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/reorg_limit.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test reorg limit +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + check_node, + connect_nodes_bi, + start_node, + sync_blocks, +) + +import tempfile +from time import sleep + +def check_stopped(i, timeout=10): + stopped = False + for x in range(1, timeout): + ret = check_node(i) + if ret is None: + sleep(1) + else: + stopped = True + break + return stopped + +class ReorgLimitTest(BitcoinTestFramework): + + def setup_nodes(self): + self.log_stderr = tempfile.SpooledTemporaryFile(max_size=2**16) + + nodes = [] + nodes.append(start_node(0, self.options.tmpdir, stderr=self.log_stderr)) + nodes.append(start_node(1, self.options.tmpdir)) + nodes.append(start_node(2, self.options.tmpdir)) + nodes.append(start_node(3, self.options.tmpdir)) + + return nodes + + def run_test(self): + assert(self.nodes[0].getblockcount() == 200) + assert(self.nodes[2].getblockcount() == 200) + + self.split_network() + + print("Test the maximum-allowed reorg:") + print("Mine 99 blocks on Node 0") + self.nodes[0].generate(99) + assert(self.nodes[0].getblockcount() == 299) + assert(self.nodes[2].getblockcount() == 200) + + print("Mine competing 100 blocks on Node 2") + self.nodes[2].generate(100) + assert(self.nodes[0].getblockcount() == 299) + assert(self.nodes[2].getblockcount() == 300) + + print("Connect nodes to force a reorg") + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + + print("Check Node 0 is still running and on the correct chain") + assert(self.nodes[0].getblockcount() == 300) + + self.split_network() + + print("Test the minimum-rejected reorg:") + print("Mine 100 blocks on Node 0") + self.nodes[0].generate(100) + assert(self.nodes[0].getblockcount() == 400) + assert(self.nodes[2].getblockcount() == 300) + + print("Mine competing 101 blocks on Node 2") + self.nodes[2].generate(101) + assert(self.nodes[0].getblockcount() == 400) + assert(self.nodes[2].getblockcount() == 401) + + try: + print("Sync nodes to force a reorg") + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + # sync_blocks uses RPC calls to wait for nodes to be synced, so don't + # call it here, because it will have a non-specific connection error + # when Node 0 stops. Instead, we explicitly check for the process itself + # to stop. + + print("Check Node 0 is no longer running") + assert(check_stopped(0)) + + # Check that node 0 stopped for the expected reason. + self.log_stderr.seek(0) + stderr = self.log_stderr.read().decode('utf-8') + expected_msg = "A block chain reorganization has been detected that would roll back 100 blocks!" + if expected_msg not in stderr: + raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) + finally: + self.log_stderr.close() + # Dummy stop to enable the test to tear down + self.nodes[0].stop = lambda: True + +if __name__ == '__main__': + ReorgLimitTest().main() diff --git a/depend/zcash/qa/rpc-tests/rest.py b/depend/zcash/qa/rpc-tests/rest.py new file mode 100755 index 000000000..1cf49c60c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/rest.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test REST interface +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_greater_than, \ + hex_str_to_bytes, start_nodes, connect_nodes_bi + +import struct +import json +from io import BytesIO +from codecs import encode +from decimal import Decimal + +import http.client +import urllib.parse + +def deser_uint256(f): + r = 0 + for i in range(8): + t = struct.unpack(b" 0) + +if __name__ == '__main__': + SignOfflineTest().main() diff --git a/depend/zcash/qa/rpc-tests/signrawtransactions.py b/depend/zcash/qa/rpc-tests/signrawtransactions.py new file mode 100755 index 000000000..2c8e36817 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/signrawtransactions.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, start_nodes + + +class SignRawTransactionsTest(BitcoinTestFramework): + """Tests transaction signing via RPC command "signrawtransaction".""" + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 1 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + self.is_network_split = False + + def successful_signing_test(self): + """Creates and signs a valid raw transaction with one input. + + Expected results: + + 1) The transaction has a complete set of signatures + 2) No script verification error occurred""" + privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'] + + inputs = [ + # Valid pay-to-pubkey script + {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0, + 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'} + ] + + outputs = {'tmJXomn8fhYy3AFqDEteifjHRMUdKtBuTGM': 0.1} + + # Also test setting an expiry height of 0. + rawTx = self.nodes[0].createrawtransaction(inputs, outputs, 0, 0) + rawTxSigned = self.nodes[0].signrawtransaction(rawTx, inputs, privKeys) + + # 1) The transaction has a complete set of signatures + assert 'complete' in rawTxSigned + assert_equal(rawTxSigned['complete'], True) + + # 2) No script verification error occurred + assert 'errors' not in rawTxSigned + + def script_verification_error_test(self): + """Creates and signs a raw transaction with valid (vin 0), invalid (vin 1) and one missing (vin 2) input script. + + Expected results: + + 3) The transaction has no complete set of signatures + 4) Two script verification errors occurred + 5) Script verification errors have certain properties ("txid", "vout", "scriptSig", "sequence", "error") + 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2)""" + privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'] + + inputs = [ + # Valid pay-to-pubkey script + {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0}, + # Invalid script + {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7}, + # Missing scriptPubKey + {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 1}, + ] + + scripts = [ + # Valid pay-to-pubkey script + {'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0, + 'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'}, + # Invalid script + {'txid': '5b8673686910442c644b1f4993d8f7753c7c8fcb5c87ee40d56eaeef25204547', 'vout': 7, + 'scriptPubKey': 'badbadbadbad'} + ] + + outputs = {'tmJXomn8fhYy3AFqDEteifjHRMUdKtBuTGM': 0.1} + + rawTx = self.nodes[0].createrawtransaction(inputs, outputs) + rawTxSigned = self.nodes[0].signrawtransaction(rawTx, scripts, privKeys) + + # 3) The transaction has no complete set of signatures + assert 'complete' in rawTxSigned + assert_equal(rawTxSigned['complete'], False) + + # 4) Two script verification errors occurred + assert 'errors' in rawTxSigned + assert_equal(len(rawTxSigned['errors']), 2) + + # 5) Script verification errors have certain properties + assert 'txid' in rawTxSigned['errors'][0] + assert 'vout' in rawTxSigned['errors'][0] + assert 'scriptSig' in rawTxSigned['errors'][0] + assert 'sequence' in rawTxSigned['errors'][0] + assert 'error' in rawTxSigned['errors'][0] + + # 6) The verification errors refer to the invalid (vin 1) and missing input (vin 2) + assert_equal(rawTxSigned['errors'][0]['txid'], inputs[1]['txid']) + assert_equal(rawTxSigned['errors'][0]['vout'], inputs[1]['vout']) + assert_equal(rawTxSigned['errors'][1]['txid'], inputs[2]['txid']) + assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout']) + + def run_test(self): + self.successful_signing_test() + self.script_verification_error_test() + + +if __name__ == '__main__': + SignRawTransactionsTest().main() diff --git a/depend/zcash/qa/rpc-tests/smartfees.py b/depend/zcash/qa/rpc-tests/smartfees.py new file mode 100755 index 000000000..cc3659dad --- /dev/null +++ b/depend/zcash/qa/rpc-tests/smartfees.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test fee estimation code +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_node, connect_nodes, \ + sync_blocks, sync_mempools + +import random +from decimal import Decimal, ROUND_DOWN + +# Construct 2 trivial P2SH's and the ScriptSigs that spend them +# So we can create many transactions without needing to spend +# time signing. +P2SH_1 = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP" +P2SH_2 = "2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA" # P2SH of "OP_2 OP_DROP" +# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2 +# 4 bytes of OP_TRUE and push 2-byte redeem script of "OP_1 OP_DROP" or "OP_2 OP_DROP" +SCRIPT_SIG = ["0451025175", "0451025275"] + +def satoshi_round(amount): + return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + +def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment): + ''' + Create and send a transaction with a random fee. + The transaction pays to a trivial P2SH script, and assumes that its inputs + are of the same form. + The function takes a list of confirmed outputs and unconfirmed outputs + and attempts to use the confirmed list first for its inputs. + It adds the newly created outputs to the unconfirmed list. + Returns (raw transaction, fee) + ''' + # It's best to exponentially distribute our random fees + # because the buckets are exponentially spaced. + # Exponentially distributed from 1-128 * fee_increment + rand_fee = float(fee_increment)*(1.1892**random.randint(0,28)) + # Total fee ranges from min_fee to min_fee + 127*fee_increment + fee = min_fee - fee_increment + satoshi_round(rand_fee) + inputs = [] + total_in = Decimal("0.00000000") + while total_in <= (amount + fee) and len(conflist) > 0: + t = conflist.pop(0) + total_in += t["amount"] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} ) + if total_in <= amount + fee: + while total_in <= (amount + fee) and len(unconflist) > 0: + t = unconflist.pop(0) + total_in += t["amount"] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} ) + if total_in <= amount + fee: + raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in)) + outputs = {} + outputs[P2SH_1] = total_in - amount - fee + outputs[P2SH_2] = amount + rawtx = from_node.createrawtransaction(inputs, outputs) + # Createrawtransaction constructions a transaction that is ready to be signed + # These transactions don't need to be signed, but we still have to insert the ScriptSig + # that will satisfy the ScriptPubKey. + completetx = rawtx[0:10] + inputnum = 0 + for inp in inputs: + completetx += rawtx[10+82*inputnum:82+82*inputnum] + completetx += SCRIPT_SIG[inp["vout"]] + completetx += rawtx[84+82*inputnum:92+82*inputnum] + inputnum += 1 + completetx += rawtx[10+82*inputnum:] + txid = from_node.sendrawtransaction(completetx, True) + unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee}) + unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount}) + + return (completetx, fee) + +def split_inputs(from_node, txins, txouts, initial_split = False): + ''' + We need to generate a lot of very small inputs so we can generate a ton of transactions + and they will have low priority. + This function takes an input from txins, and creates and sends a transaction + which splits the value into 2 outputs which are appended to txouts. + ''' + prevtxout = txins.pop() + inputs = [] + outputs = {} + inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] }) + half_change = satoshi_round(prevtxout["amount"]/2) + rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000") + outputs[P2SH_1] = half_change + outputs[P2SH_2] = rem_change + rawtx = from_node.createrawtransaction(inputs, outputs) + # If this is the initial split we actually need to sign the transaction + # Otherwise we just need to insert the property ScriptSig + if (initial_split) : + completetx = from_node.signrawtransaction(rawtx)["hex"] + else : + completetx = rawtx[0:82] + SCRIPT_SIG[prevtxout["vout"]] + rawtx[84:] + txid = from_node.sendrawtransaction(completetx, True) + txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change}) + txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change}) + +def check_estimates(node, fees_seen, max_invalid, print_estimates = True): + ''' + This function calls estimatefee and verifies that the estimates + meet certain invariants. + ''' + all_estimates = [ node.estimatefee(i) for i in range(1,26) ] + if print_estimates: + print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]]) + delta = 1.0e-6 # account for rounding error + last_e = max(fees_seen) + for e in [x for x in all_estimates if x >= 0]: + # Estimates should be within the bounds of what transactions fees actually were: + if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen): + raise AssertionError("Estimated fee (%f) out of range (%f,%f)" + %(float(e), min(fees_seen), max(fees_seen))) + # Estimates should be monotonically decreasing + if float(e)-delta > last_e: + raise AssertionError("Estimated fee (%f) larger than last fee (%f) for lower number of confirms" + %(float(e),float(last_e))) + last_e = e + valid_estimate = False + invalid_estimates = 0 + for e in all_estimates: + if e >= 0: + valid_estimate = True + else: + invalid_estimates += 1 + # Once we're at a high enough confirmation count that we can give an estimate + # We should have estimates for all higher confirmation counts + if valid_estimate and e < 0: + raise AssertionError("Invalid estimate appears at higher confirm count than valid estimate") + # Check on the expected number of different confirmation counts + # that we might not have valid estimates for + if invalid_estimates > max_invalid: + raise AssertionError("More than (%d) invalid estimates"%(max_invalid)) + return all_estimates + + +class EstimateFeeTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = False + + def setup_network(self): + ''' + We'll setup the network to have 3 nodes that all mine with different parameters. + But first we need to use one node to create a lot of small low priority outputs + which we will use to generate our transactions. + ''' + self.nodes = [] + # Use node0 to mine blocks for input splitting + self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", + "-relaypriority=0", "-whitelist=127.0.0.1"])) + + print("This test is time consuming, please be patient") + print("Splitting inputs to small size so we can generate low priority tx's") + self.txouts = [] + self.txouts2 = [] + # Split a coinbase into two transaction puzzle outputs + split_inputs(self.nodes[0], self.nodes[0].listunspent(0), self.txouts, True) + + # Mine + while (len(self.nodes[0].getrawmempool()) > 0): + self.nodes[0].generate(1) + + # Repeatedly split those 2 outputs, doubling twice for each rep + # Use txouts to monitor the available utxo, since these won't be tracked in wallet + reps = 0 + while (reps < 5): + #Double txouts to txouts2 + while (len(self.txouts)>0): + split_inputs(self.nodes[0], self.txouts, self.txouts2) + while (len(self.nodes[0].getrawmempool()) > 0): + self.nodes[0].generate(1) + #Double txouts2 to txouts + while (len(self.txouts2)>0): + split_inputs(self.nodes[0], self.txouts2, self.txouts) + while (len(self.nodes[0].getrawmempool()) > 0): + self.nodes[0].generate(1) + reps += 1 + print("Finished splitting") + + # Now we can connect the other nodes, didn't want to connect them earlier + # so the estimates would not be affected by the splitting transactions + # Node1 mines small blocks but that are bigger than the expected transaction rate, + # and allows free transactions. + # NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes, + # (17k is room enough for 110 or so transactions) + self.nodes.append(start_node(1, self.options.tmpdir, + ["-blockprioritysize=1500", "-blockmaxsize=18000", + "-maxorphantx=1000", "-relaypriority=0", "-debug=estimatefee"])) + connect_nodes(self.nodes[1], 0) + + # Node2 is a stingy miner, that + # produces too small blocks (room for only 70 or so transactions) + node2args = ["-blockprioritysize=0", "-blockmaxsize=12000", "-maxorphantx=1000", "-relaypriority=0"] + + self.nodes.append(start_node(2, self.options.tmpdir, node2args)) + connect_nodes(self.nodes[0], 2) + connect_nodes(self.nodes[2], 1) + + self.is_network_split = False + self.sync_all() + + def transact_and_mine(self, numblocks, mining_node): + min_fee = Decimal("0.00001") + # We will now mine numblocks blocks generating on average 100 transactions between each block + # We shuffle our confirmed txout set before each set of transactions + # small_txpuzzle_randfee will use the transactions that have inputs already in the chain when possible + # resorting to tx's that depend on the mempool when those run out + for i in range(numblocks): + random.shuffle(self.confutxo) + for j in range(random.randrange(100-50,100+50)): + from_index = random.randint(1,2) + (txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo, + self.memutxo, Decimal("0.005"), min_fee, min_fee) + tx_kbytes = (len(txhex) // 2) / 1000.0 + self.fees_per_kb.append(float(fee)/tx_kbytes) + sync_mempools(self.nodes[0:3],.1) + mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"] + sync_blocks(self.nodes[0:3],.1) + #update which txouts are confirmed + newmem = [] + for utx in self.memutxo: + if utx["txid"] in mined: + self.confutxo.append(utx) + else: + newmem.append(utx) + self.memutxo = newmem + + def run_test(self): + self.fees_per_kb = [] + self.memutxo = [] + self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting + print("Checking estimates for 1/2/3/6/15/25 blocks") + print("Creating transactions and mining them with a huge block size") + # Create transactions and mine 20 big blocks with node 0 such that the mempool is always emptied + self.transact_and_mine(30, self.nodes[0]) + check_estimates(self.nodes[1], self.fees_per_kb, 1) + + print("Creating transactions and mining them with a block size that can't keep up") + # Create transactions and mine 30 small blocks with node 2, but create txs faster than we can mine + self.transact_and_mine(20, self.nodes[2]) + check_estimates(self.nodes[1], self.fees_per_kb, 3) + + print("Creating transactions and mining them at a block size that is just big enough") + # Generate transactions while mining 40 more blocks, this time with node1 + # which mines blocks with capacity just above the rate that transactions are being created + self.transact_and_mine(40, self.nodes[1]) + check_estimates(self.nodes[1], self.fees_per_kb, 2) + + # Finish by mining a normal-sized block: + while len(self.nodes[1].getrawmempool()) > 0: + self.nodes[1].generate(1) + + sync_blocks(self.nodes[0:3],.1) + print("Final estimates after emptying mempools") + check_estimates(self.nodes[1], self.fees_per_kb, 2) + +if __name__ == '__main__': + EstimateFeeTest().main() diff --git a/depend/zcash/qa/rpc-tests/spentindex.py b/depend/zcash/qa/rpc-tests/spentindex.py new file mode 100755 index 000000000..a152ddba5 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/spentindex.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# +# Test spentindex generation and fetching for insightexplorer + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException + +from test_framework.util import ( + assert_equal, + initialize_chain_clean, + start_nodes, + stop_nodes, + connect_nodes, + wait_bitcoinds, + fail, +) + +from test_framework.mininode import COIN + + +class SpentIndexTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self): + # -insightexplorer causes spentindex to be enabled (fSpentIndex = true) + + self.nodes = start_nodes( + 3, self.options.tmpdir, + [['-debug', '-txindex', '-experimentalfeatures', '-insightexplorer']]*3) + connect_nodes(self.nodes[0], 1) + connect_nodes(self.nodes[0], 2) + + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(105) + self.sync_all() + + chain_height = self.nodes[1].getblockcount() + assert_equal(chain_height, 105) + + # Test getrawtransaction changes and the getspentinfo RPC + + # send coinbase to address addr1 + addr1 = self.nodes[1].getnewaddress() + txid1 = self.nodes[0].sendtoaddress(addr1, 2) + self.sync_all() + block_hash1 = self.nodes[0].generate(1) + self.sync_all() + + # send from addr1 to addr2 + # (the only utxo on node 1 is from address addr1) + addr2 = self.nodes[2].getnewaddress() + txid2 = self.nodes[1].sendtoaddress(addr2, 1) + self.sync_all() + + # addr1 to addr2 transaction is not confirmed, so it has no height + tx2 = self.nodes[2].getrawtransaction(txid2, 1) + assert('height' not in tx2) + + # confirm addr1 to addr2 transaction + block_hash2 = self.nodes[0].generate(1) + self.sync_all() + + # Restart all nodes to ensure index files are saved to disk and recovered + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Check new fields added to getrawtransaction + tx1 = self.nodes[2].getrawtransaction(txid1, 1) + assert_equal(tx1['vin'][0]['value'], 10) # coinbase + assert_equal(tx1['vin'][0]['valueSat'], 10*COIN) + # we want the non-change (payment) output + vout = list(filter(lambda o: o['value'] == 2, tx1['vout'])) + n = vout[0]['n'] + assert_equal(vout[0]['spentTxId'], txid2) + assert_equal(vout[0]['spentIndex'], 0) + assert_equal(vout[0]['spentHeight'], 107) + assert_equal(tx1['height'], 106) + + tx2 = self.nodes[2].getrawtransaction(txid2, 1) + assert_equal(tx2['vin'][0]['address'], addr1) + assert_equal(tx2['vin'][0]['value'], 2) + assert_equal(tx2['vin'][0]['valueSat'], 2*COIN) + # since this transaction's outputs haven't yet been + # spent, these fields should not be present + assert('spentTxId' not in tx2['vout'][0]) + assert('spentIndex' not in tx2['vout'][0]) + assert('spentHeight' not in tx2['vout'][0]) + assert_equal(tx2['height'], 107) + + # Given a transaction output, getspentinfo() returns a reference + # to the (later, confirmed) transaction that spent that output, + # that is, the transaction that used this output as an input. + spentinfo = self.nodes[2].getspentinfo({'txid': txid1, 'index': n}) + assert_equal(spentinfo['height'], 107) + assert_equal(spentinfo['index'], 0) + assert_equal(spentinfo['txid'], txid2) + + # specifying an output that hasn't been spent should fail + try: + self.nodes[1].getspentinfo({'txid': txid2, 'index': 0}) + fail('getspentinfo should have thrown an exception') + except JSONRPCException as e: + assert_equal(e.error['message'], "Unable to get spent info") + + block_hash_next = self.nodes[0].generate(1) + self.sync_all() + + # Test the getblockdeltas RPC + blockdeltas = self.nodes[2].getblockdeltas(block_hash1[0]) + assert_equal(blockdeltas['confirmations'], 3) + assert_equal(blockdeltas['height'], 106) + assert_equal(blockdeltas['version'], 4) + assert_equal(blockdeltas['hash'], block_hash1[0]) + assert_equal(blockdeltas['nextblockhash'], block_hash2[0]) + deltas = blockdeltas['deltas'] + # block contains two transactions, coinbase, and earlier coinbase to addr1 + assert_equal(len(deltas), 2) + coinbase_tx = deltas[0] + assert_equal(coinbase_tx['index'], 0) + assert_equal(len(coinbase_tx['inputs']), 0) + assert_equal(len(coinbase_tx['outputs']), 2) + assert_equal(coinbase_tx['outputs'][0]['index'], 0) + assert_equal(coinbase_tx['outputs'][1]['index'], 1) + assert_equal(coinbase_tx['outputs'][1]['satoshis'], 2.5*COIN) + + to_a_tx = deltas[1] + assert_equal(to_a_tx['index'], 1) + assert_equal(to_a_tx['txid'], txid1) + + assert_equal(len(to_a_tx['inputs']), 1) + assert_equal(to_a_tx['inputs'][0]['index'], 0) + assert_equal(to_a_tx['inputs'][0]['prevout'], 0) + assert_equal(to_a_tx['inputs'][0]['satoshis'], -10*COIN) + + assert_equal(len(to_a_tx['outputs']), 2) + # find the nonchange output, which is the payment to addr1 + out = list(filter(lambda o: o['satoshis'] == 2*COIN, to_a_tx['outputs'])) + assert_equal(len(out), 1) + assert_equal(out[0]['address'], addr1) + + blockdeltas = self.nodes[2].getblockdeltas(block_hash2[0]) + assert_equal(blockdeltas['confirmations'], 2) + assert_equal(blockdeltas['height'], 107) + assert_equal(blockdeltas['version'], 4) + assert_equal(blockdeltas['hash'], block_hash2[0]) + assert_equal(blockdeltas['previousblockhash'], block_hash1[0]) + assert_equal(blockdeltas['nextblockhash'], block_hash_next[0]) + deltas = blockdeltas['deltas'] + assert_equal(len(deltas), 2) + coinbase_tx = deltas[0] + assert_equal(coinbase_tx['index'], 0) + assert_equal(len(coinbase_tx['inputs']), 0) + assert_equal(len(coinbase_tx['outputs']), 2) + assert_equal(coinbase_tx['outputs'][0]['index'], 0) + assert_equal(coinbase_tx['outputs'][1]['index'], 1) + assert_equal(coinbase_tx['outputs'][1]['satoshis'], 2.5*COIN) + + to_b_tx = deltas[1] + assert_equal(to_b_tx['index'], 1) + assert_equal(to_b_tx['txid'], txid2) + + assert_equal(len(to_b_tx['inputs']), 1) + assert_equal(to_b_tx['inputs'][0]['index'], 0) + assert_equal(to_b_tx['inputs'][0]['prevtxid'], txid1) + assert_equal(to_b_tx['inputs'][0]['satoshis'], -2*COIN) + + assert_equal(len(to_b_tx['outputs']), 2) + # find the nonchange output, which is the payment to addr2 + out = list(filter(lambda o: o['satoshis'] == 1*COIN, to_b_tx['outputs'])) + assert_equal(len(out), 1) + assert_equal(out[0]['address'], addr2) + + +if __name__ == '__main__': + SpentIndexTest().main() diff --git a/depend/zcash/qa/rpc-tests/sprout_sapling_migration.py b/depend/zcash/qa/rpc-tests/sprout_sapling_migration.py new file mode 100755 index 000000000..680e4a040 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/sprout_sapling_migration.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, get_coinbase_address, \ + start_nodes, wait_and_assert_operationid_status, \ + wait_and_assert_operationid_status_result, DEFAULT_FEE + +SAPLING_ADDR = 'zregtestsapling1ssqj3f3majnl270985gqcdqedd9t4nlttjqskccwevj2v20sc25deqspv3masufnwcdy67cydyy' +SAPLING_KEY = 'secret-extended-key-regtest1qv62zt2fqyqqpqrh2qzc08h7gncf4447jh9kvnnnhjg959fkwt7mhw9j8e9at7attx8z6u3953u86vcnsujdc2ckdlcmztjt44x3uxpah5mxtncxd0mqcnz9eq8rghh5m4j44ep5d9702sdvvwawqassulktfegrcp4twxgqdxx4eww3lau0mywuaeztpla2cmvagr5nj98elt45zh6fjznadl6wz52n2uyhdwcm2wlsu8fnxstrk6s4t55t8dy6jkgx5g0cwpchh5qffp8x5' + +DISABLED_NO_FUNDS = 0 +ENABLED_NO_FUNDS = 1 +DISABLED_BEFORE_MIGRATION = 2 +ENABLED_BEFORE_MIGRATION = 3 +DURING_MIGRATION = 4 +AFTER_MIGRATION = 5 +ALL_MIGRATION_STATES = [DISABLED_NO_FUNDS, ENABLED_NO_FUNDS, DISABLED_BEFORE_MIGRATION, ENABLED_BEFORE_MIGRATION, DURING_MIGRATION, AFTER_MIGRATION] + + +def check_migration_status(node, destination_address, migration_state): + status = node.z_getmigrationstatus() + assert_equal(destination_address, status['destination_address'], "Migration destination address; status=%r" % status) + assert_true(migration_state in ALL_MIGRATION_STATES, "Unexpected migration state %r" % migration_state) + + expected_enabled = migration_state not in [DISABLED_NO_FUNDS, DISABLED_BEFORE_MIGRATION] + expected_sprout_funds = migration_state in [DISABLED_BEFORE_MIGRATION, ENABLED_BEFORE_MIGRATION] + positive_unfinalized_amount = migration_state == DURING_MIGRATION + positive_finalized_amount = migration_state == AFTER_MIGRATION + num_migration_txids = 1 if migration_state in [DURING_MIGRATION, AFTER_MIGRATION] else 0 + num_finalized_migration_transactions = 1 if migration_state == AFTER_MIGRATION else 0 + + assert_equal(expected_enabled, status['enabled'], "Expected enabled: %s" % expected_enabled) + # During and after the migration there may be no remaining sprout funds if + # we have randomly picked to migrate them all at once, so we only check + # this field in the one case. + if expected_sprout_funds: + assert_true(Decimal(status['unmigrated_amount']) > Decimal('0.00'), "Expected sprout funds; status=%r" % (status,)) + # For the other two amount fields we know whether or not they will be positive + unfinalized_msg = "Positive unfinalized amount: %s; status=%r " % (positive_unfinalized_amount, status) + assert_equal(positive_unfinalized_amount, Decimal(status['unfinalized_migrated_amount']) > Decimal('0'), unfinalized_msg) + finalized_msg = "Positive finalized amount: %s; status=%r " % (positive_finalized_amount, status) + assert_equal(positive_finalized_amount, Decimal(status['finalized_migrated_amount']) > Decimal('0'), finalized_msg) + assert_equal(num_finalized_migration_transactions, status['finalized_migration_transactions'], "Num finalized transactions; status=%r" % (status,)) + assert_equal(num_migration_txids, len(status['migration_txids']), "Num migration txids; status=%r" % (status,)) + + +class SproutSaplingMigration(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_nodes(self): + extra_args = [[ + ]] * self.num_nodes + # Add migration parameters to nodes[0] + extra_args[0] = extra_args[0] + [ + '-migration', + '-migrationdestaddress=' + SAPLING_ADDR, + '-debug=zrpcunsafe' + ] + assert_equal(3, len(extra_args[0])) + assert_equal(0, len(extra_args[1])) + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + + def run_migration_test(self, node, sproutAddr, saplingAddr, target_height): + # Make sure we are in a good state to run the test + assert_equal(102, node.getblockcount() % 500, "Should be at block 102 % 500") + assert_equal(node.z_getbalance(sproutAddr), Decimal('10')) + assert_equal(node.z_getbalance(saplingAddr), Decimal('0')) + check_migration_status(node, saplingAddr, DISABLED_BEFORE_MIGRATION) + + # Migrate + node.z_setmigration(True) + print("Mining to block 494 % 500...") + node.generate(392) # 102 % 500 -> 494 % 500 + self.sync_all() + + # At 494 % 500 we should have no async operations + assert_equal(0, len(node.z_getoperationstatus()), "num async operations at 494 % 500") + check_migration_status(node, saplingAddr, ENABLED_BEFORE_MIGRATION) + + node.generate(1) + self.sync_all() + + # At 495 % 500 we should have an async operation + operationstatus = node.z_getoperationstatus() + print("migration operation: {}".format(operationstatus)) + assert_equal(1, len(operationstatus), "num async operations at 495 % 500") + assert_equal('saplingmigration', operationstatus[0]['method']) + assert_equal(target_height, operationstatus[0]['target_height']) + + result = wait_and_assert_operationid_status_result(node, operationstatus[0]['id']) + print("result: {}".format(result)) + assert_equal('saplingmigration', result['method']) + assert_equal(target_height, result['target_height']) + assert_equal(1, result['result']['num_tx_created']) + assert_equal(1, len(result['result']['migration_txids'])) + assert_true(Decimal(result['result']['amount_migrated']) > Decimal('0')) + + assert_equal(0, len(node.getrawmempool()), "mempool size at 495 % 500") + + node.generate(3) + self.sync_all() + + # At 498 % 500 the mempool will be empty and no funds will have moved + assert_equal(0, len(node.getrawmempool()), "mempool size at 498 % 500") + assert_equal(node.z_getbalance(sproutAddr), Decimal('10')) + assert_equal(node.z_getbalance(saplingAddr), Decimal('0')) + + node.generate(1) + self.sync_all() + + # At 499 % 500 there will be a transaction in the mempool and the note will be locked + mempool = node.getrawmempool() + print("mempool: {}".format(mempool)) + assert_equal(1, len(mempool), "mempool size at 499 % 500") + assert_equal(node.z_getbalance(sproutAddr), Decimal('0')) + assert_equal(node.z_getbalance(saplingAddr), Decimal('0')) + assert_true(node.z_getbalance(saplingAddr, 0) > Decimal('0'), "Unconfirmed sapling balance at 499 % 500") + # Check that unmigrated amount + unfinalized = starting balance - fee + status = node.z_getmigrationstatus() + print("status: {}".format(status)) + assert_equal(Decimal('10.0') - DEFAULT_FEE, Decimal(status['unmigrated_amount']) + Decimal(status['unfinalized_migrated_amount'])) + + # The transaction in the mempool should be the one listed in migration_txids, + # and it should expire at the next 450 % 500. + assert_equal(1, len(status['migration_txids'])) + txid = status['migration_txids'][0] + assert_equal(txid, mempool[0]) + tx = node.getrawtransaction(txid, 1) + assert_equal(target_height + 450, tx['expiryheight']) + + node.generate(1) + self.sync_all() + + # At 0 % 500 funds will have moved + sprout_balance = node.z_getbalance(sproutAddr) + sapling_balance = node.z_getbalance(saplingAddr) + print("sprout balance: {}, sapling balance: {}".format(sprout_balance, sapling_balance)) + assert_true(sprout_balance < Decimal('10'), "Should have less Sprout funds") + assert_true(sapling_balance > Decimal('0'), "Should have more Sapling funds") + assert_true(sprout_balance + sapling_balance, Decimal('10.0') - DEFAULT_FEE) + + check_migration_status(node, saplingAddr, DURING_MIGRATION) + # At 10 % 500 the transactions will be considered 'finalized' + node.generate(10) + self.sync_all() + check_migration_status(node, saplingAddr, AFTER_MIGRATION) + # Check exact migration status amounts to make sure we account for fee + status = node.z_getmigrationstatus() + assert_equal(sprout_balance, Decimal(status['unmigrated_amount'])) + assert_equal(sapling_balance, Decimal(status['finalized_migrated_amount'])) + + def send_to_sprout_zaddr(self, tAddr, sproutAddr): + # Send some ZEC to a Sprout address + result = self.nodes[0].z_shieldcoinbase(tAddr, sproutAddr, 0, 1) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.nodes[0].generate(1) + self.sync_all() + + def run_test(self): + # Check enabling via '-migration' and disabling via rpc + check_migration_status(self.nodes[0], SAPLING_ADDR, ENABLED_NO_FUNDS) + self.nodes[0].z_setmigration(False) + check_migration_status(self.nodes[0], SAPLING_ADDR, DISABLED_NO_FUNDS) + + # 1. Test using self.nodes[0] which has the parameter + print("Running test using '-migrationdestaddress'...") + print("Mining blocks...") + self.nodes[0].generate(101) + self.sync_all() + tAddr = get_coinbase_address(self.nodes[0]) + + # Import a previously generated key to test '-migrationdestaddress' + self.nodes[0].z_importkey(SAPLING_KEY) + sproutAddr0 = self.nodes[0].z_getnewaddress('sprout') + + self.send_to_sprout_zaddr(tAddr, sproutAddr0) + self.run_migration_test(self.nodes[0], sproutAddr0, SAPLING_ADDR, 500) + # Disable migration so only self.nodes[1] has a transaction in the mempool at block 999 + self.nodes[0].z_setmigration(False) + + # 2. Test using self.nodes[1] which will use the default Sapling address + print("Running test using default Sapling address...") + # Mine more blocks so we start at 102 % 500 + print("Mining blocks...") + self.nodes[1].generate(91) # 511 -> 602 + self.sync_all() + + sproutAddr1 = self.nodes[1].z_getnewaddress('sprout') + saplingAddr1 = self.nodes[1].z_getnewaddress('sapling') + + self.send_to_sprout_zaddr(tAddr, sproutAddr1) + self.run_migration_test(self.nodes[1], sproutAddr1, saplingAddr1, 1000) + + +if __name__ == '__main__': + SproutSaplingMigration().main() diff --git a/depend/zcash/qa/rpc-tests/test_framework/__init__.py b/depend/zcash/qa/rpc-tests/test_framework/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/depend/zcash/qa/rpc-tests/test_framework/authproxy.py b/depend/zcash/qa/rpc-tests/test_framework/authproxy.py new file mode 100644 index 000000000..391482c89 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/authproxy.py @@ -0,0 +1,166 @@ +""" + Copyright 2011 Jeff Garzik + + AuthServiceProxy has the following improvements over python-jsonrpc's + ServiceProxy class: + + - HTTP connections persist for the life of the AuthServiceProxy object + (if server supports HTTP/1.1) + - sends protocol 'version', per JSON-RPC 1.1 + - sends proper, incrementing 'id' + - sends Basic HTTP authentication headers + - parses all JSON numbers that look like floats as Decimal + - uses standard Python json lib + + Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: + + Copyright (c) 2007 Jan-Klaas Kollhof + + This file is part of jsonrpc. + + jsonrpc is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This software 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this software; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" + +import base64 +import decimal +import simplejson as json +import logging +from http.client import HTTPConnection, HTTPSConnection, BadStatusLine +from urllib.parse import urlparse + +USER_AGENT = "AuthServiceProxy/0.1" + +HTTP_TIMEOUT = 600 + +log = logging.getLogger("BitcoinRPC") + +class JSONRPCException(Exception): + def __init__(self, rpc_error): + Exception.__init__(self, rpc_error.get("message")) + self.error = rpc_error + +def EncodeDecimal(o): + if isinstance(o, decimal.Decimal): + return str(o) + raise TypeError(repr(o) + " is not JSON serializable") + + +class AuthServiceProxy(): + __id_count = 0 + + def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): + self.__service_url = service_url + self._service_name = service_name + self.__url = urlparse(service_url) + (user, passwd) = (self.__url.username, self.__url.password) + try: + user = user.encode('utf8') + except AttributeError: + pass + try: + passwd = passwd.encode('utf8') + except AttributeError: + pass + authpair = user + b':' + passwd + self.__auth_header = b'Basic ' + base64.b64encode(authpair) + + self.timeout = timeout + self._set_conn(connection) + + def _set_conn(self, connection=None): + port = 80 if self.__url.port is None else self.__url.port + if connection: + self.__conn = connection + self.timeout = connection.timeout + elif self.__url.scheme == 'https': + self.__conn = HTTPSConnection(self.__url.hostname, port, timeout=self.timeout) + else: + self.__conn = HTTPConnection(self.__url.hostname, port, timeout=self.timeout) + + def __getattr__(self, name): + if name.startswith('__') and name.endswith('__'): + # Python internal stuff + raise AttributeError + if self._service_name is not None: + name = "%s.%s" % (self._service_name, name) + return AuthServiceProxy(self.__service_url, name, connection=self.__conn) + + def _request(self, method, path, postdata): + ''' + Do a HTTP request, with retry if we get disconnected (e.g. due to a timeout). + This is a workaround for https://bugs.python.org/issue3566 which is fixed in Python 3.5. + ''' + headers = {'Host': self.__url.hostname, + 'User-Agent': USER_AGENT, + 'Authorization': self.__auth_header, + 'Content-type': 'application/json'} + try: + self.__conn.request(method, path, postdata, headers) + return self._get_response() + except Exception as e: + # If connection was closed, try again. + # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. + # ConnectionResetError happens on FreeBSD with Python 3.4. + # This can be simplified now that we depend on Python 3 (previously, we could not + # refer to BrokenPipeError or ConnectionResetError which did not exist on Python 2) + if ((isinstance(e, BadStatusLine) and e.line == "''") + or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): + self.__conn.close() + self.__conn.request(method, path, postdata, headers) + return self._get_response() + else: + raise + + def __call__(self, *args): + AuthServiceProxy.__id_count += 1 + + log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self._service_name, + json.dumps(args, default=EncodeDecimal))) + postdata = json.dumps({'version': '1.1', + 'method': self._service_name, + 'params': args, + 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) + response = self._request('POST', self.__url.path, postdata) + if response['error'] is not None: + raise JSONRPCException(response['error']) + elif 'result' not in response: + raise JSONRPCException({ + 'code': -343, 'message': 'missing JSON-RPC result'}) + else: + return response['result'] + + def _batch(self, rpc_call_list): + postdata = json.dumps(list(rpc_call_list), default=EncodeDecimal) + log.debug("--> "+postdata) + return self._request('POST', self.__url.path, postdata) + + def _get_response(self): + http_response = self.__conn.getresponse() + if http_response is None: + raise JSONRPCException({ + 'code': -342, 'message': 'missing HTTP response from server'}) + + content_type = http_response.getheader('Content-Type') + if content_type != 'application/json': + raise JSONRPCException({ + 'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)}) + + responsedata = http_response.read().decode('utf8') + response = json.loads(responsedata, parse_float=decimal.Decimal) + if "error" in response and response["error"] is None: + log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) + else: + log.debug("<-- "+responsedata) + return response diff --git a/depend/zcash/qa/rpc-tests/test_framework/bignum.py b/depend/zcash/qa/rpc-tests/test_framework/bignum.py new file mode 100644 index 000000000..f56cea98e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/bignum.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# bignum.py +# +# This file is copied from python-bitcoinlib. +# +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# + +"""Bignum routines""" + +import struct + + +# generic big endian MPI format + +def bn_bytes(v, have_ext=False): + ext = 0 + if have_ext: + ext = 1 + return ((v.bit_length()+7)//8) + ext + +def bn2bin(v): + s = bytearray() + i = bn_bytes(v) + while i > 0: + s.append((v >> ((i-1) * 8)) & 0xff) + i -= 1 + return s + +def bin2bn(s): + l = 0 + for ch in s: + l = (l << 8) | ch + return l + +def bn2mpi(v): + have_ext = False + if v.bit_length() > 0: + have_ext = (v.bit_length() & 0x07) == 0 + + neg = False + if v < 0: + neg = True + v = -v + + s = struct.pack(b">I", bn_bytes(v, have_ext)) + ext = bytearray() + if have_ext: + ext.append(0) + v_bin = bn2bin(v) + if neg: + if have_ext: + ext[0] |= 0x80 + else: + v_bin[0] |= 0x80 + return s + ext + v_bin + +def mpi2bn(s): + if len(s) < 4: + return None + s_size = bytes(s[:4]) + v_len = struct.unpack(b">I", s_size)[0] + if len(s) != (v_len + 4): + return None + if v_len == 0: + return 0 + + v_str = bytearray(s[4:]) + neg = False + i = v_str[0] + if i & 0x80: + neg = True + i &= ~0x80 + v_str[0] = i + + v = bin2bn(v_str) + + if neg: + return -v + return v + +# bitcoin-specific little endian format, with implicit size +def mpi2vch(s): + r = s[4:] # strip size + r = r[::-1] # reverse string, converting BE->LE + return r + +def bn2vch(v): + return bytes(mpi2vch(bn2mpi(v))) + +def vch2mpi(s): + r = struct.pack(b">I", len(s)) # size + r += s[::-1] # reverse string, converting LE->BE + return r + +def vch2bn(s): + return mpi2bn(vch2mpi(s)) + diff --git a/depend/zcash/qa/rpc-tests/test_framework/blockstore.py b/depend/zcash/qa/rpc-tests/test_framework/blockstore.py new file mode 100644 index 000000000..e83ee5fab --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/blockstore.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +# BlockStore: a helper class that keeps a map of blocks and implements +# helper functions for responding to getheaders and getdata, +# and for constructing a getheaders message +# + +from .mininode import CBlock, CBlockHeader, CBlockLocator, CTransaction, msg_block, msg_headers, msg_tx + +import sys +from io import BytesIO +import dbm.ndbm + +class BlockStore(): + def __init__(self, datadir): + self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') + self.currentBlock = 0 + self.headers_map = dict() + + def close(self): + self.blockDB.close() + + def get(self, blockhash): + serialized_block = None + try: + serialized_block = self.blockDB[repr(blockhash)] + except KeyError: + return None + f = BytesIO(serialized_block) + ret = CBlock() + ret.deserialize(f) + ret.calc_sha256() + return ret + + def get_header(self, blockhash): + try: + return self.headers_map[blockhash] + except KeyError: + return None + + # Note: this pulls full blocks out of the database just to retrieve + # the headers -- perhaps we could keep a separate data structure + # to avoid this overhead. + def headers_for(self, locator, hash_stop, current_tip=None): + if current_tip is None: + current_tip = self.currentBlock + current_block_header = self.get_header(current_tip) + if current_block_header is None: + return None + + response = msg_headers() + headersList = [ current_block_header ] + maxheaders = 2000 + while (headersList[0].sha256 not in locator.vHave): + prevBlockHash = headersList[0].hashPrevBlock + prevBlockHeader = self.get_header(prevBlockHash) + if prevBlockHeader is not None: + headersList.insert(0, prevBlockHeader) + else: + break + headersList = headersList[:maxheaders] # truncate if we have too many + hashList = [x.sha256 for x in headersList] + index = len(headersList) + if (hash_stop in hashList): + index = hashList.index(hash_stop)+1 + response.headers = headersList[:index] + return response + + def add_block(self, block): + block.calc_sha256() + try: + self.blockDB[repr(block.sha256)] = bytes(block.serialize()) + except TypeError as e: + print("Unexpected error: ", sys.exc_info()[0], e.args) + self.currentBlock = block.sha256 + self.headers_map[block.sha256] = CBlockHeader(block) + + def add_header(self, header): + self.headers_map[header.sha256] = header + + def get_blocks(self, inv): + responses = [] + for i in inv: + if (i.type == 2): # MSG_BLOCK + block = self.get(i.hash) + if block is not None: + responses.append(msg_block(block)) + return responses + + def get_locator(self, current_tip=None): + if current_tip is None: + current_tip = self.currentBlock + r = [] + counter = 0 + step = 1 + lastBlock = self.get(current_tip) + while lastBlock is not None: + r.append(lastBlock.hashPrevBlock) + for i in range(step): + lastBlock = self.get(lastBlock.hashPrevBlock) + if lastBlock is None: + break + counter += 1 + if counter > 10: + step *= 2 + locator = CBlockLocator() + locator.vHave = r + return locator + +class TxStore(object): + def __init__(self, datadir): + self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') + + def close(self): + self.txDB.close() + + def get(self, txhash): + serialized_tx = None + try: + serialized_tx = self.txDB[repr(txhash)] + except KeyError: + return None + f = BytesIO(serialized_tx) + ret = CTransaction() + ret.deserialize(f) + ret.calc_sha256() + return ret + + def add_transaction(self, tx): + tx.calc_sha256() + try: + self.txDB[repr(tx.sha256)] = bytes(tx.serialize()) + except TypeError as e: + print("Unexpected error: ", sys.exc_info()[0], e.args) + + def get_transactions(self, inv): + responses = [] + for i in inv: + if (i.type == 1): # MSG_TX + tx = self.get(i.hash) + if tx is not None: + responses.append(msg_tx(tx)) + return responses diff --git a/depend/zcash/qa/rpc-tests/test_framework/blocktools.py b/depend/zcash/qa/rpc-tests/test_framework/blocktools.py new file mode 100644 index 000000000..107075aca --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/blocktools.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# blocktools.py - utilities for manipulating blocks and transactions +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from hashlib import blake2b + +from .mininode import CBlock, CTransaction, CTxIn, CTxOut, COutPoint +from .script import CScript, OP_0, OP_EQUAL, OP_HASH160, OP_TRUE, OP_CHECKSIG + +# Create a block (with regtest difficulty) +def create_block(hashprev, coinbase, nTime=None, nBits=None, hashFinalSaplingRoot=None): + block = CBlock() + if nTime is None: + import time + block.nTime = int(time.time()+600) + else: + block.nTime = nTime + block.hashPrevBlock = hashprev + if hashFinalSaplingRoot is None: + # By default NUs up to Sapling are active from block 1, so we set this to the empty root. + hashFinalSaplingRoot = 0x3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb + block.hashFinalSaplingRoot = hashFinalSaplingRoot + if nBits is None: + block.nBits = 0x200f0f0f # difficulty retargeting is disabled in REGTEST chainparams + else: + block.nBits = nBits + block.vtx.append(coinbase) + block.hashMerkleRoot = block.calc_merkle_root() + block.hashAuthDataRoot = block.calc_auth_data_root() + block.calc_sha256() + return block + +def derive_block_commitments_hash(chain_history_root, auth_data_root): + digest = blake2b( + digest_size=32, + person=b'ZcashBlockCommit') + digest.update(chain_history_root) + digest.update(auth_data_root) + digest.update(b'\x00' * 32) + return digest.digest() + +def serialize_script_num(value): + r = bytearray(0) + if value == 0: + return r + neg = value < 0 + absvalue = -value if neg else value + while (absvalue): + r.append(int(absvalue & 0xff)) + absvalue >>= 8 + if r[-1] & 0x80: + r.append(0x80 if neg else 0) + elif neg: + r[-1] |= 0x80 + return r + +# Create a coinbase transaction, assuming no miner fees. +# If pubkey is passed in, the coinbase output will be a P2PK output; +# otherwise an anyone-can-spend output. +def create_coinbase(height, pubkey = None): + coinbase = CTransaction() + coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff), + CScript([height, OP_0]), 0xffffffff)) + coinbaseoutput = CTxOut() + coinbaseoutput.nValue = int(12.5*100000000) + halvings = int(height/150) # regtest + coinbaseoutput.nValue >>= halvings + if (pubkey != None): + coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG]) + else: + coinbaseoutput.scriptPubKey = CScript([OP_TRUE]) + coinbase.vout = [ coinbaseoutput ] + if halvings == 0: # regtest + froutput = CTxOut() + froutput.nValue = coinbaseoutput.nValue // 5 + # regtest + fraddr = bytearray([0x67, 0x08, 0xe6, 0x67, 0x0d, 0xb0, 0xb9, 0x50, + 0xda, 0xc6, 0x80, 0x31, 0x02, 0x5c, 0xc5, 0xb6, + 0x32, 0x13, 0xa4, 0x91]) + froutput.scriptPubKey = CScript([OP_HASH160, fraddr, OP_EQUAL]) + coinbaseoutput.nValue -= froutput.nValue + coinbase.vout = [ coinbaseoutput, froutput ] + coinbase.calc_sha256() + return coinbase + +# Create a transaction with an anyone-can-spend output, that spends the +# nth output of prevtx. +def create_transaction(prevtx, n, sig, value): + tx = CTransaction() + assert(n < len(prevtx.vout)) + tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) + tx.vout.append(CTxOut(value, b"")) + tx.calc_sha256() + return tx diff --git a/depend/zcash/qa/rpc-tests/test_framework/comptool.py b/depend/zcash/qa/rpc-tests/test_framework/comptool.py new file mode 100755 index 000000000..a09fbfe20 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/comptool.py @@ -0,0 +1,429 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from .blockstore import BlockStore, TxStore +from .mininode import ( + CBlock, + CBlockHeader, + CTransaction, + CInv, + msg_block, + msg_getheaders, + msg_inv, + msg_mempool, + msg_ping, + mininode_lock, + MAX_INV_SZ, + NodeConn, + NodeConnCB, +) +from .util import p2p_port + +import time + +''' +This is a tool for comparing two or more bitcoinds to each other +using a script provided. + +To use, create a class that implements get_tests(), and pass it in +as the test generator to TestManager. get_tests() should be a python +generator that returns TestInstance objects. See below for definition. + +In practice get_tests is always implemented on a subclass of ComparisonTestFramework. +''' + +# TestNode behaves as follows: +# Configure with a BlockStore and TxStore +# on_inv: log the message but don't request +# on_headers: log the chain tip +# on_pong: update ping response map (for synchronization) +# on_getheaders: provide headers via BlockStore +# on_getdata: provide blocks via BlockStore + +def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): + attempt = 0 + elapsed = 0 + + while attempt < attempts and elapsed < timeout: + with mininode_lock: + if predicate(): + return True + attempt += 1 + elapsed += 0.05 + time.sleep(0.05) + + return False + +class RejectResult(object): + ''' + Outcome that expects rejection of a transaction or block. + ''' + def __init__(self, code, reason=b''): + self.code = code + self.reason = reason + def match(self, other): + if self.code != other.code: + return False + return other.reason.startswith(self.reason) + def __repr__(self): + return '%i:%s' % (self.code,self.reason or '*') + +class TestNode(NodeConnCB): + + def __init__(self, block_store, tx_store): + NodeConnCB.__init__(self) + self.create_callback_map() + self.conn = None + self.bestblockhash = None + self.block_store = block_store + self.block_request_map = {} + self.tx_store = tx_store + self.tx_request_map = {} + self.block_reject_map = {} + self.tx_reject_map = {} + + # When the pingmap is non-empty we're waiting for + # a response + self.pingMap = {} + self.lastInv = [] + self.closed = False + + def on_close(self, conn): + self.closed = True + + def add_connection(self, conn): + self.conn = conn + + def on_headers(self, conn, message): + if len(message.headers) > 0: + best_header = message.headers[-1] + best_header.calc_sha256() + self.bestblockhash = best_header.sha256 + + def on_getheaders(self, conn, message): + response = self.block_store.headers_for(message.locator, message.hashstop) + if response is not None: + conn.send_message(response) + + def on_getdata(self, conn, message): + [conn.send_message(r) for r in self.block_store.get_blocks(message.inv)] + [conn.send_message(r) for r in self.tx_store.get_transactions(message.inv)] + + for i in message.inv: + if i.type == 1: + self.tx_request_map[i.hash] = True + elif i.type == 2: + self.block_request_map[i.hash] = True + + def on_inv(self, conn, message): + self.lastInv = [x.hash for x in message.inv] + + def on_pong(self, conn, message): + try: + del self.pingMap[message.nonce] + except KeyError: + raise AssertionError("Got pong for unknown ping [%s]" % repr(message)) + + def on_reject(self, conn, message): + if message.message == b'tx': + self.tx_reject_map[message.data] = RejectResult(message.code, message.reason) + if message.message == b'block': + self.block_reject_map[message.data] = RejectResult(message.code, message.reason) + + def send_inv(self, obj): + mtype = 2 if isinstance(obj, CBlock) else 1 + self.conn.send_message(msg_inv([CInv(mtype, obj.sha256)])) + + def send_getheaders(self): + # We ask for headers from their last tip. + m = msg_getheaders() + m.locator = self.block_store.get_locator(self.bestblockhash) + self.conn.send_message(m) + + # This assumes BIP31 + def send_ping(self, nonce): + self.pingMap[nonce] = True + self.conn.send_message(msg_ping(nonce)) + + def received_ping_response(self, nonce): + return nonce not in self.pingMap + + def send_mempool(self): + self.lastInv = [] + self.conn.send_message(msg_mempool()) + +# TestInstance: +# +# Instances of these are generated by the test generator, and fed into the +# comptool. +# +# "blocks_and_transactions" should be an array of +# [obj, True/False/None, hash/None]: +# - obj is either a CBlock, CBlockHeader, or a CTransaction, and +# - the second value indicates whether the object should be accepted +# into the blockchain or mempool (for tests where we expect a certain +# answer), or "None" if we don't expect a certain answer and are just +# comparing the behavior of the nodes being tested. +# - the third value is the hash to test the tip against (if None or omitted, +# use the hash of the block) +# - NOTE: if a block header, no test is performed; instead the header is +# just added to the block_store. This is to facilitate block delivery +# when communicating with headers-first clients (when withholding an +# intermediate block). +# sync_every_block: if True, then each block will be inv'ed, synced, and +# nodes will be tested based on the outcome for the block. If False, +# then inv's accumulate until all blocks are processed (or max inv size +# is reached) and then sent out in one inv message. Then the final block +# will be synced across all connections, and the outcome of the final +# block will be tested. +# sync_every_tx: analogous to behavior for sync_every_block, except if outcome +# on the final tx is None, then contents of entire mempool are compared +# across all connections. (If outcome of final tx is specified as true +# or false, then only the last tx is tested against outcome.) + +class TestInstance(object): + def __init__(self, objects=None, sync_every_block=True, sync_every_tx=False): + self.blocks_and_transactions = objects if objects else [] + self.sync_every_block = sync_every_block + self.sync_every_tx = sync_every_tx + +class TestManager(object): + + def __init__(self, testgen, datadir): + self.test_generator = testgen + self.connections = [] + self.test_nodes = [] + self.block_store = BlockStore(datadir) + self.tx_store = TxStore(datadir) + self.ping_counter = 1 + + def add_all_connections(self, nodes): + for i in range(len(nodes)): + # Create a p2p connection to each node + test_node = TestNode(self.block_store, self.tx_store) + self.test_nodes.append(test_node) + self.connections.append(NodeConn('127.0.0.1', p2p_port(i), nodes[i], test_node)) + # Make sure the TestNode (callback class) has a reference to its + # associated NodeConn + test_node.add_connection(self.connections[-1]) + + def wait_for_disconnections(self): + def disconnected(): + return all(node.closed for node in self.test_nodes) + return wait_until(disconnected, timeout=10) + + def wait_for_verack(self): + def veracked(): + return all(node.verack_received for node in self.test_nodes) + return wait_until(veracked, timeout=10) + + def wait_for_pings(self, counter): + def received_pongs(): + return all(node.received_ping_response(counter) for node in self.test_nodes) + return wait_until(received_pongs) + + # sync_blocks: Wait for all connections to request the blockhash given + # then send get_headers to find out the tip of each node, and synchronize + # the response by using a ping (and waiting for pong with same nonce). + def sync_blocks(self, blockhash, num_blocks): + def blocks_requested(): + return all( + blockhash in node.block_request_map and node.block_request_map[blockhash] + for node in self.test_nodes + ) + + # --> error if not requested + if not wait_until(blocks_requested, attempts=20*num_blocks): + # print [ c.cb.block_request_map for c in self.connections ] + raise AssertionError("Not all nodes requested block") + + # Send getheaders message + [ c.cb.send_getheaders() for c in self.connections ] + + # Send ping and wait for response -- synchronization hack + [ c.cb.send_ping(self.ping_counter) for c in self.connections ] + self.wait_for_pings(self.ping_counter) + self.ping_counter += 1 + + # Analogous to sync_block (see above) + def sync_transaction(self, txhash, num_events): + # Wait for nodes to request transaction (50ms sleep * 20 tries * num_events) + def transaction_requested(): + return all( + txhash in node.tx_request_map and node.tx_request_map[txhash] + for node in self.test_nodes + ) + + # --> error if not requested + if not wait_until(transaction_requested, attempts=20*num_events): + # print [ c.cb.tx_request_map for c in self.connections ] + raise AssertionError("Not all nodes requested transaction") + + # Get the mempool + [ c.cb.send_mempool() for c in self.connections ] + + # Send ping and wait for response -- synchronization hack + [ c.cb.send_ping(self.ping_counter) for c in self.connections ] + self.wait_for_pings(self.ping_counter) + self.ping_counter += 1 + + # Sort inv responses from each node + with mininode_lock: + [ c.cb.lastInv.sort() for c in self.connections ] + + # Verify that the tip of each connection all agree with each other, and + # with the expected outcome (if given) + def check_results(self, blockhash, outcome): + with mininode_lock: + for c in self.connections: + if outcome is None: + if c.cb.bestblockhash != self.connections[0].cb.bestblockhash: + return False + elif isinstance(outcome, RejectResult): # Check that block was rejected w/ code + if c.cb.bestblockhash == blockhash: + return False + if blockhash not in c.cb.block_reject_map: + print('Block not in reject map: %064x' % (blockhash)) + return False + if not outcome.match(c.cb.block_reject_map[blockhash]): + print('Block rejected with %s instead of expected %s: %064x' % (c.cb.block_reject_map[blockhash], outcome, blockhash)) + return False + elif ((c.cb.bestblockhash == blockhash) != outcome): + if outcome is True and blockhash in c.cb.block_reject_map: + print('Block rejected with %s instead of accepted: %064x' % (c.cb.block_reject_map[blockhash], blockhash)) + return False + return True + + # Either check that the mempools all agree with each other, or that + # txhash's presence in the mempool matches the outcome specified. + # This is somewhat of a strange comparison, in that we're either comparing + # a particular tx to an outcome, or the entire mempools altogether; + # perhaps it would be useful to add the ability to check explicitly that + # a particular tx's existence in the mempool is the same across all nodes. + def check_mempool(self, txhash, outcome): + with mininode_lock: + for c in self.connections: + if outcome is None: + # Make sure the mempools agree with each other + if c.cb.lastInv != self.connections[0].cb.lastInv: + # print c.rpc.getrawmempool() + return False + elif isinstance(outcome, RejectResult): # Check that tx was rejected w/ code + if txhash in c.cb.lastInv: + return False + if txhash not in c.cb.tx_reject_map: + print('Tx not in reject map: %064x' % (txhash)) + return False + if not outcome.match(c.cb.tx_reject_map[txhash]): + print('Tx rejected with %s instead of expected %s: %064x' % (c.cb.tx_reject_map[txhash], outcome, txhash)) + return False + elif ((txhash in c.cb.lastInv) != outcome): + # print c.rpc.getrawmempool(), c.cb.lastInv + return False + return True + + def run(self): + # Wait until verack is received + self.wait_for_verack() + + test_number = 1 + for test_instance in self.test_generator.get_tests(): + # We use these variables to keep track of the last block + # and last transaction in the tests, which are used + # if we're not syncing on every block or every tx. + [ block, block_outcome, tip ] = [ None, None, None ] + [ tx, tx_outcome ] = [ None, None ] + invqueue = [] + + for test_obj in test_instance.blocks_and_transactions: + b_or_t = test_obj[0] + outcome = test_obj[1] + # Determine if we're dealing with a block or tx + if isinstance(b_or_t, CBlock): # Block test runner + block = b_or_t + block_outcome = outcome + tip = block.sha256 + # each test_obj can have an optional third argument + # to specify the tip we should compare with + # (default is to use the block being tested) + if len(test_obj) >= 3: + tip = test_obj[2] + + # Add to shared block_store, set as current block + # If there was an open getdata request for the block + # previously, and we didn't have an entry in the + # block_store, then immediately deliver, because the + # node wouldn't send another getdata request while + # the earlier one is outstanding. + first_block_with_hash = True + if self.block_store.get(block.sha256) is not None: + first_block_with_hash = False + with mininode_lock: + self.block_store.add_block(block) + for c in self.connections: + if first_block_with_hash and block.sha256 in c.cb.block_request_map and c.cb.block_request_map[block.sha256] == True: + # There was a previous request for this block hash + # Most likely, we delivered a header for this block + # but never had the block to respond to the getdata + c.send_message(msg_block(block)) + else: + c.cb.block_request_map[block.sha256] = False + # Either send inv's to each node and sync, or add + # to invqueue for later inv'ing. + if (test_instance.sync_every_block): + [ c.cb.send_inv(block) for c in self.connections ] + self.sync_blocks(block.sha256, 1) + if (not self.check_results(tip, outcome)): + raise AssertionError("Test failed at test %d" % test_number) + else: + invqueue.append(CInv(2, block.sha256)) + elif isinstance(b_or_t, CBlockHeader): + block_header = b_or_t + self.block_store.add_header(block_header) + else: # Tx test runner + assert(isinstance(b_or_t, CTransaction)) + tx = b_or_t + tx_outcome = outcome + # Add to shared tx store and clear map entry + with mininode_lock: + self.tx_store.add_transaction(tx) + for c in self.connections: + c.cb.tx_request_map[tx.sha256] = False + # Again, either inv to all nodes or save for later + if (test_instance.sync_every_tx): + [ c.cb.send_inv(tx) for c in self.connections ] + self.sync_transaction(tx.sha256, 1) + if (not self.check_mempool(tx.sha256, outcome)): + raise AssertionError("Test failed at test %d" % test_number) + else: + invqueue.append(CInv(1, tx.sha256)) + # Ensure we're not overflowing the inv queue + if len(invqueue) == MAX_INV_SZ: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + + # Do final sync if we weren't syncing on every block or every tx. + if (not test_instance.sync_every_block and block is not None): + if len(invqueue) > 0: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + self.sync_blocks(block.sha256, len(test_instance.blocks_and_transactions)) + if (not self.check_results(tip, block_outcome)): + raise AssertionError("Block test failed at test %d" % test_number) + if (not test_instance.sync_every_tx and tx is not None): + if len(invqueue) > 0: + [ c.send_message(msg_inv(invqueue)) for c in self.connections ] + invqueue = [] + self.sync_transaction(tx.sha256, len(test_instance.blocks_and_transactions)) + if (not self.check_mempool(tx.sha256, tx_outcome)): + raise AssertionError("Mempool test failed at test %d" % test_number) + + print("Test %d: PASS" % test_number, [ c.rpc.getblockcount() for c in self.connections ]) + test_number += 1 + + [ c.disconnect_node() for c in self.connections ] + self.wait_for_disconnections() + self.block_store.close() + self.tx_store.close() diff --git a/depend/zcash/qa/rpc-tests/test_framework/coverage.py b/depend/zcash/qa/rpc-tests/test_framework/coverage.py new file mode 100644 index 000000000..d36f14ab0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/coverage.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +""" +This module contains utilities for doing coverage analysis on the RPC +interface. + +It provides a way to track which RPC commands are exercised during +testing. + +""" +import os + + +REFERENCE_FILENAME = 'rpc_interface.txt' + + +class AuthServiceProxyWrapper(object): + """ + An object that wraps AuthServiceProxy to record specific RPC calls. + + """ + def __init__(self, auth_service_proxy_instance, coverage_logfile=None): + """ + Kwargs: + auth_service_proxy_instance (AuthServiceProxy): the instance + being wrapped. + coverage_logfile (str): if specified, write each service_name + out to a file when called. + + """ + self.auth_service_proxy_instance = auth_service_proxy_instance + self.coverage_logfile = coverage_logfile + + def __getattr__(self, *args, **kwargs): + return_val = self.auth_service_proxy_instance.__getattr__( + *args, **kwargs) + + return AuthServiceProxyWrapper(return_val, self.coverage_logfile) + + def __call__(self, *args, **kwargs): + """ + Delegates to AuthServiceProxy, then writes the particular RPC method + called to a file. + + """ + return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs) + rpc_method = self.auth_service_proxy_instance._service_name + + if self.coverage_logfile: + with open(self.coverage_logfile, 'a+', encoding='utf8') as f: + f.write("%s\n" % rpc_method) + + return return_val + + @property + def url(self): + return self.auth_service_proxy_instance.url + + +def get_filename(dirname, n_node): + """ + Get a filename unique to the test process ID and node. + + This file will contain a list of RPC commands covered. + """ + pid = str(os.getpid()) + return os.path.join( + dirname, "coverage.pid%s.node%s.txt" % (pid, str(n_node))) + + +def write_all_rpc_commands(dirname, node): + """ + Write out a list of all RPC functions available in `bitcoin-cli` for + coverage comparison. This will only happen once per coverage + directory. + + Args: + dirname (str): temporary test dir + node (AuthServiceProxy): client + + Returns: + bool. if the RPC interface file was written. + + """ + filename = os.path.join(dirname, REFERENCE_FILENAME) + + if os.path.isfile(filename): + return False + + help_output = node.help().split('\n') + commands = set() + + for line in help_output: + line = line.strip() + + # Ignore blanks and headers + if line and not line.startswith('='): + commands.add("%s\n" % line.split()[0]) + + with open(filename, 'w', encoding='utf8') as f: + f.writelines(list(commands)) + + return True diff --git a/depend/zcash/qa/rpc-tests/test_framework/equihash.py b/depend/zcash/qa/rpc-tests/test_framework/equihash.py new file mode 100755 index 000000000..e05544fb4 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/equihash.py @@ -0,0 +1,294 @@ +from operator import itemgetter +import struct +from functools import reduce + +DEBUG = False +VERBOSE = False + + +word_size = 32 +word_mask = (1<= 8 and word_size >= 7+bit_len + bit_len_mask = (1<= bit_len: + acc_bits -= bit_len + for x in range(byte_pad, out_width): + out[j+x] = ( + # Big-endian + acc_value >> (acc_bits+(8*(out_width-x-1))) + ) & ( + # Apply bit_len_mask across byte boundaries + (bit_len_mask >> (8*(out_width-x-1))) & 0xFF + ) + j += out_width + + return out + +def compress_array(inp, out_len, bit_len, byte_pad=0): + assert bit_len >= 8 and word_size >= 7+bit_len + + in_width = (bit_len+7)//8 + byte_pad + assert out_len == bit_len*len(inp)//(8*in_width) + out = bytearray(out_len) + + bit_len_mask = (1 << bit_len) - 1 + + # The acc_bits least-significant bits of acc_value represent a bit sequence + # in big-endian order. + acc_bits = 0; + acc_value = 0; + + j = 0 + for i in range(out_len): + # When we have fewer than 8 bits left in the accumulator, read the next + # input element. + if acc_bits < 8: + acc_value = ((acc_value << bit_len) & word_mask) | inp[j] + for x in range(byte_pad, in_width): + acc_value = acc_value | ( + ( + # Apply bit_len_mask across byte boundaries + inp[j+x] & ((bit_len_mask >> (8*(in_width-x-1))) & 0xFF) + ) << (8*(in_width-x-1))); # Big-endian + j += in_width + acc_bits += bit_len + + acc_bits -= 8 + out[i] = (acc_value >> acc_bits) & 0xFF + + return out + +def get_indices_from_minimal(minimal, bit_len): + eh_index_size = 4 + assert (bit_len+7)//8 <= eh_index_size + len_indices = 8*eh_index_size*len(minimal)//bit_len + byte_pad = eh_index_size - (bit_len+7)//8 + expanded = expand_array(minimal, len_indices, bit_len, byte_pad) + return [struct.unpack('>I', expanded[i:i+4])[0] for i in range(0, len_indices, eh_index_size)] + +def get_minimal_from_indices(indices, bit_len): + eh_index_size = 4 + assert (bit_len+7)//8 <= eh_index_size + len_indices = len(indices)*eh_index_size + min_len = bit_len*len_indices//(8*eh_index_size) + byte_pad = eh_index_size - (bit_len+7)//8 + byte_indices = bytearray(b''.join([struct.pack('>I', i) for i in indices])) + return compress_array(byte_indices, min_len, bit_len, byte_pad) + + +def hash_nonce(digest, nonce): + for i in range(8): + digest.update(struct.pack('> (32*i))) + +def hash_xi(digest, xi): + digest.update(struct.pack(' 0: + # 2b) Find next set of unordered pairs with collisions on first n/(k+1) bits + j = 1 + while j < len(X): + if not has_collision(X[-1][0], X[-1-j][0], i, collision_length): + break + j += 1 + + # 2c) Store tuples (X_i ^ X_j, (i, j)) on the table + for l in range(0, j-1): + for m in range(l+1, j): + # Check that there are no duplicate indices in tuples i and j + if distinct_indices(X[-1-l][1], X[-1-m][1]): + if X[-1-l][1][0] < X[-1-m][1][0]: + concat = X[-1-l][1] + X[-1-m][1] + else: + concat = X[-1-m][1] + X[-1-l][1] + Xc.append((xor(X[-1-l][0], X[-1-m][0]), concat)) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + # 2e) Replace previous list with new list + X = Xc + + # k+1) Find a collision on last 2n(k+1) bits + if DEBUG: + print('Final round:') + print('- Sorting list') + X.sort(key=itemgetter(0)) + if DEBUG and VERBOSE: + for Xi in X[-32:]: + print('%s %s' % (print_hash(Xi[0]), Xi[1])) + if DEBUG: print('- Finding collisions') + solns = [] + while len(X) > 0: + j = 1 + while j < len(X): + if not (has_collision(X[-1][0], X[-1-j][0], k, collision_length) and + has_collision(X[-1][0], X[-1-j][0], k+1, collision_length)): + break + j += 1 + + for l in range(0, j-1): + for m in range(l+1, j): + res = xor(X[-1-l][0], X[-1-m][0]) + if count_zeroes(res) == 8*hash_length and distinct_indices(X[-1-l][1], X[-1-m][1]): + if DEBUG and VERBOSE: + print('Found solution:') + print('- %s %s' % (print_hash(X[-1-l][0]), X[-1-l][1])) + print('- %s %s' % (print_hash(X[-1-m][0]), X[-1-m][1])) + if X[-1-l][1][0] < X[-1-m][1][0]: + solns.append(list(X[-1-l][1] + X[-1-m][1])) + else: + solns.append(list(X[-1-m][1] + X[-1-l][1])) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + return [get_minimal_from_indices(soln, collision_length+1) for soln in solns] + +def gbp_validate(digest, minimal, n, k): + validate_params(n, k) + collision_length = n//(k+1) + hash_length = (k+1)*((collision_length+7)//8) + indices_per_hash_output = 512//n + solution_width = (1 << k)*(collision_length+1)//8 + + if len(minimal) != solution_width: + print('Invalid solution length: %d (expected %d)' % \ + (len(minimal), solution_width)) + return False + + X = [] + for i in get_indices_from_minimal(minimal, collision_length+1): + r = i % indices_per_hash_output + # X_i = H(I||V||x_i) + curr_digest = digest.copy() + hash_xi(curr_digest, i//indices_per_hash_output) + tmp_hash = curr_digest.digest() + X.append(( + expand_array(bytearray(tmp_hash[r*n//8:(r+1)*n//8]), + hash_length, collision_length), + (i,) + )) + + for r in range(1, k+1): + Xc = [] + for i in range(0, len(X), 2): + if not has_collision(X[i][0], X[i+1][0], r, collision_length): + print('Invalid solution: invalid collision length between StepRows') + return False + if X[i+1][1][0] < X[i][1][0]: + print('Invalid solution: Index tree incorrectly ordered') + return False + if not distinct_indices(X[i][1], X[i+1][1]): + print('Invalid solution: duplicate indices') + return False + Xc.append((xor(X[i][0], X[i+1][0]), X[i][1] + X[i+1][1])) + X = Xc + + if len(X) != 1: + print('Invalid solution: incorrect length after end of rounds: %d' % len(X)) + return False + + if count_zeroes(X[0][0]) != 8*hash_length: + print('Invalid solution: incorrect number of zeroes: %d' % count_zeroes(X[0][0])) + return False + + return True + +def zcash_person(n, k): + return b'ZcashPoW' + struct.pack('= n): + raise ValueError('n must be larger than k') + if (((n//(k+1))+1) >= 32): + raise ValueError('Parameters must satisfy n/(k+1)+1 < 32') diff --git a/depend/zcash/qa/rpc-tests/test_framework/flyclient.py b/depend/zcash/qa/rpc-tests/test_framework/flyclient.py new file mode 100644 index 000000000..4e01cf76c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/flyclient.py @@ -0,0 +1,210 @@ +from hashlib import blake2b +import struct +from typing import (List, Optional) + +from .mininode import (CBlockHeader, block_work_from_compact, ser_compactsize, ser_uint256) +from .util import ( + NU5_BRANCH_ID, + assert_equal, +) + +def H(msg: bytes, consensusBranchId: int) -> bytes: + digest = blake2b( + digest_size=32, + person=b'ZcashHistory' + struct.pack(" 'ZcashMMRNode': + '''Create a leaf node from a block''' + if v2_data is not None: + assert_equal(consensusBranchId, NU5_BRANCH_ID) + orchard_root = v2_data[0] + orchard_tx_count = v2_data[1] + else: + orchard_root = None + orchard_tx_count = None + + node = Z() + node.left_child = None + node.right_child = None + node.hashSubtreeCommitment = ser_uint256(block.rehash()) + node.nEarliestTimestamp = block.nTime + node.nLatestTimestamp = block.nTime + node.nEarliestTargetBits = block.nBits + node.nLatestTargetBits = block.nBits + node.hashEarliestSaplingRoot = sapling_root + node.hashLatestSaplingRoot = sapling_root + node.nSubTreeTotalWork = block_work_from_compact(block.nBits) + node.nEarliestHeight = height + node.nLatestHeight = height + node.nSaplingTxCount = sapling_tx_count + node.hashEarliestOrchardRoot = orchard_root + node.hashLatestOrchardRoot = orchard_root + node.nOrchardTxCount = orchard_tx_count + node.consensusBranchId = consensusBranchId + return node + + def serialize(self) -> bytes: + '''serializes a node''' + buf = b'' + buf += self.hashSubtreeCommitment + buf += struct.pack(" ZcashMMRNode: + parent = ZcashMMRNode() + parent.left_child = left_child + parent.right_child = right_child + parent.hashSubtreeCommitment = H( + left_child.serialize() + right_child.serialize(), + left_child.consensusBranchId, + ) + parent.nEarliestTimestamp = left_child.nEarliestTimestamp + parent.nLatestTimestamp = right_child.nLatestTimestamp + parent.nEarliestTargetBits = left_child.nEarliestTargetBits + parent.nLatestTargetBits = right_child.nLatestTargetBits + parent.hashEarliestSaplingRoot = left_child.hashEarliestSaplingRoot + parent.hashLatestSaplingRoot = right_child.hashLatestSaplingRoot + parent.nSubTreeTotalWork = left_child.nSubTreeTotalWork + right_child.nSubTreeTotalWork + parent.nEarliestHeight = left_child.nEarliestHeight + parent.nLatestHeight = right_child.nLatestHeight + parent.nSaplingTxCount = left_child.nSaplingTxCount + right_child.nSaplingTxCount + parent.hashEarliestOrchardRoot = left_child.hashEarliestOrchardRoot + parent.hashLatestOrchardRoot = right_child.hashLatestOrchardRoot + parent.nOrchardTxCount = ( + left_child.nOrchardTxCount + right_child.nOrchardTxCount + if left_child.nOrchardTxCount is not None and right_child.nOrchardTxCount is not None + else None) + parent.consensusBranchId = left_child.consensusBranchId + return parent + +def make_root_commitment(root: ZcashMMRNode) -> bytes: + '''Makes the root commitment for a blockheader''' + return H(root.serialize(), root.consensusBranchId) + +def get_peaks(node: ZcashMMRNode) -> List[ZcashMMRNode]: + peaks: List[ZcashMMRNode] = [] + + # Get number of leaves. + leaves = node.nLatestHeight - (node.nEarliestHeight - 1) + assert(leaves > 0) + + # Check if the number of leaves in this subtree is a power of two. + if (leaves & (leaves - 1)) == 0: + # This subtree is full, and therefore a single peak. This also covers + # the case of a single isolated leaf. + peaks.append(node) + else: + # This is one of the generated nodes; search within its children. + peaks.extend(get_peaks(node.left_child)) + peaks.extend(get_peaks(node.right_child)) + + return peaks + + +def bag_peaks(peaks: List[ZcashMMRNode]) -> ZcashMMRNode: + ''' + "Bag" a list of peaks, and return the final root + ''' + root = peaks[0] + for i in range(1, len(peaks)): + root = make_parent(root, peaks[i]) + return root + + +def append(root: ZcashMMRNode, leaf: ZcashMMRNode) -> ZcashMMRNode: + '''Append a leaf to an existing tree, return the new tree root''' + # recursively find a list of peaks in the current tree + peaks: List[ZcashMMRNode] = get_peaks(root) + merged: List[ZcashMMRNode] = [] + + # Merge peaks from right to left. + # This will produce a list of peaks in reverse order + current = leaf + for peak in peaks[::-1]: + current_leaves = current.nLatestHeight - (current.nEarliestHeight - 1) + peak_leaves = peak.nLatestHeight - (peak.nEarliestHeight - 1) + + if current_leaves == peak_leaves: + current = make_parent(peak, current) + else: + merged.append(current) + current = peak + merged.append(current) + + # finally, bag the merged peaks + return bag_peaks(merged[::-1]) + +def delete(root: ZcashMMRNode) -> ZcashMMRNode: + ''' + Delete the rightmost leaf node from an existing MMR + Return the new tree root + ''' + + n_leaves = root.nLatestHeight - (root.nEarliestHeight - 1) + # if there were an odd number of leaves, + # simply replace root with left_child + if n_leaves & 1: + return root.left_child + + # otherwise, we need to re-bag the peaks. + else: + # first peak + peaks = [root.left_child] + + # we do this traversing the right (unbalanced) side of the tree + # we keep the left side (balanced subtree or leaf) of each subtree + # until we reach a leaf + subtree_root = root.right_child + while subtree_root.left_child: + peaks.append(subtree_root.left_child) + subtree_root = subtree_root.right_child + + new_root = bag_peaks(peaks) + return new_root diff --git a/depend/zcash/qa/rpc-tests/test_framework/key.py b/depend/zcash/qa/rpc-tests/test_framework/key.py new file mode 100644 index 000000000..ba3038fe0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/key.py @@ -0,0 +1,215 @@ +# Copyright (c) 2011 Sam Rushing +# +# key.py - OpenSSL wrapper +# +# This file is modified from python-bitcoinlib. +# + +"""ECC secp256k1 crypto routines + +WARNING: This module does not mlock() secrets; your private keys may end up on +disk in swap! Use with caution! +""" + +import ctypes +import ctypes.util +import hashlib +import sys + +ssl = ctypes.cdll.LoadLibrary(ctypes.util.find_library ('ssl') or 'libeay32') + +ssl.BN_new.restype = ctypes.c_void_p +ssl.BN_new.argtypes = [] + +ssl.BN_bin2bn.restype = ctypes.c_void_p +ssl.BN_bin2bn.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.c_void_p] + +ssl.BN_CTX_free.restype = None +ssl.BN_CTX_free.argtypes = [ctypes.c_void_p] + +ssl.BN_CTX_new.restype = ctypes.c_void_p +ssl.BN_CTX_new.argtypes = [] + +ssl.ECDH_compute_key.restype = ctypes.c_int +ssl.ECDH_compute_key.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_sign.restype = ctypes.c_int +ssl.ECDSA_sign.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +ssl.ECDSA_verify.restype = ctypes.c_int +ssl.ECDSA_verify.argtypes = [ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p] + +ssl.EC_KEY_free.restype = None +ssl.EC_KEY_free.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.argtypes = [ctypes.c_int] + +ssl.EC_KEY_get0_group.restype = ctypes.c_void_p +ssl.EC_KEY_get0_group.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_get0_public_key.restype = ctypes.c_void_p +ssl.EC_KEY_get0_public_key.argtypes = [ctypes.c_void_p] + +ssl.EC_KEY_set_private_key.restype = ctypes.c_int +ssl.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_KEY_set_conv_form.restype = None +ssl.EC_KEY_set_conv_form.argtypes = [ctypes.c_void_p, ctypes.c_int] + +ssl.EC_KEY_set_public_key.restype = ctypes.c_int +ssl.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.i2o_ECPublicKey.restype = ctypes.c_void_p +ssl.i2o_ECPublicKey.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + +ssl.EC_POINT_new.restype = ctypes.c_void_p +ssl.EC_POINT_new.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_free.restype = None +ssl.EC_POINT_free.argtypes = [ctypes.c_void_p] + +ssl.EC_POINT_mul.restype = ctypes.c_int +ssl.EC_POINT_mul.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] + +# this specifies the curve used with ECDSA. +NID_secp256k1 = 714 # from openssl/obj_mac.h + +# Thx to Sam Devlin for the ctypes magic 64-bit fix. +def _check_result(val, func, args): + if val == 0: + raise ValueError + else: + return ctypes.c_void_p (val) + +ssl.EC_KEY_new_by_curve_name.restype = ctypes.c_void_p +ssl.EC_KEY_new_by_curve_name.errcheck = _check_result + +class CECKey(object): + """Wrapper around OpenSSL's EC_KEY""" + + POINT_CONVERSION_COMPRESSED = 2 + POINT_CONVERSION_UNCOMPRESSED = 4 + + def __init__(self): + self.k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) + + def __del__(self): + if ssl: + ssl.EC_KEY_free(self.k) + self.k = None + + def set_secretbytes(self, secret): + priv_key = ssl.BN_bin2bn(secret, 32, ssl.BN_new()) + group = ssl.EC_KEY_get0_group(self.k) + pub_key = ssl.EC_POINT_new(group) + ctx = ssl.BN_CTX_new() + if not ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx): + raise ValueError("Could not derive public key from the supplied secret.") + ssl.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx) + ssl.EC_KEY_set_private_key(self.k, priv_key) + ssl.EC_KEY_set_public_key(self.k, pub_key) + ssl.EC_POINT_free(pub_key) + ssl.BN_CTX_free(ctx) + return self.k + + def set_privkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.d2i_ECPrivateKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def set_pubkey(self, key): + self.mb = ctypes.create_string_buffer(key) + return ssl.o2i_ECPublicKey(ctypes.byref(self.k), ctypes.byref(ctypes.pointer(self.mb)), len(key)) + + def get_privkey(self): + size = ssl.i2d_ECPrivateKey(self.k, 0) + mb_pri = ctypes.create_string_buffer(size) + ssl.i2d_ECPrivateKey(self.k, ctypes.byref(ctypes.pointer(mb_pri))) + return mb_pri.raw + + def get_pubkey(self): + size = ssl.i2o_ECPublicKey(self.k, 0) + mb = ctypes.create_string_buffer(size) + ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) + return mb.raw + + def get_raw_ecdh_key(self, other_pubkey): + ecdh_keybuffer = ctypes.create_string_buffer(32) + r = ssl.ECDH_compute_key(ctypes.pointer(ecdh_keybuffer), 32, + ssl.EC_KEY_get0_public_key(other_pubkey.k), + self.k, 0) + if r != 32: + raise Exception('CKey.get_ecdh_key(): ECDH_compute_key() failed') + return ecdh_keybuffer.raw + + def get_ecdh_key(self, other_pubkey, kdf=lambda k: hashlib.sha256(k).digest()): + # FIXME: be warned it's not clear what the kdf should be as a default + r = self.get_raw_ecdh_key(other_pubkey) + return kdf(r) + + def sign(self, hash): + # FIXME: need unit tests for below cases + if not isinstance(hash, bytes): + raise TypeError('Hash must be bytes instance; got %r' % hash.__class__) + if len(hash) != 32: + raise ValueError('Hash must be exactly 32 bytes long') + + sig_size0 = ctypes.c_uint32() + sig_size0.value = ssl.ECDSA_size(self.k) + mb_sig = ctypes.create_string_buffer(sig_size0.value) + result = ssl.ECDSA_sign(0, hash, len(hash), mb_sig, ctypes.byref(sig_size0), self.k) + assert 1 == result + return mb_sig.raw[:sig_size0.value] + + def verify(self, hash, sig): + """Verify a DER signature""" + return ssl.ECDSA_verify(0, hash, len(hash), sig, len(sig), self.k) == 1 + + def set_compressed(self, compressed): + if compressed: + form = self.POINT_CONVERSION_COMPRESSED + else: + form = self.POINT_CONVERSION_UNCOMPRESSED + ssl.EC_KEY_set_conv_form(self.k, form) + + +class CPubKey(bytes): + """An encapsulated public key + + Attributes: + + is_valid - Corresponds to CPubKey.IsValid() + is_fullyvalid - Corresponds to CPubKey.IsFullyValid() + is_compressed - Corresponds to CPubKey.IsCompressed() + """ + + def __new__(cls, buf, _cec_key=None): + self = super(CPubKey, cls).__new__(cls, buf) + if _cec_key is None: + _cec_key = CECKey() + self._cec_key = _cec_key + self.is_fullyvalid = _cec_key.set_pubkey(self) != 0 + return self + + @property + def is_valid(self): + return len(self) > 0 + + @property + def is_compressed(self): + return len(self) == 33 + + def verify(self, hash, sig): + return self._cec_key.verify(hash, sig) + + def __str__(self): + return repr(self) + + def __repr__(self): + # Always have represent as b'' so test cases don't have to + # change for py2/3 + if sys.version > '3': + return '%s(%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + else: + return '%s(b%s)' % (self.__class__.__name__, super(CPubKey, self).__repr__()) + diff --git a/depend/zcash/qa/rpc-tests/test_framework/mininode.py b/depend/zcash/qa/rpc-tests/test_framework/mininode.py new file mode 100755 index 000000000..abbccf16a --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/mininode.py @@ -0,0 +1,2115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2010 ArtForz -- public domain half-a-node +# Copyright (c) 2012 Jeff Garzik +# Copyright (c) 2010-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# mininode.py - Bitcoin P2P network half-a-node +# +# This python code was modified from ArtForz' public domain half-a-node, as +# found in the mini-node branch of https://github.com/jgarzik/pynode. +# +# NodeConn: an object which manages p2p connectivity to a bitcoin node +# NodeConnCB: a base class that describes the interface for receiving +# callbacks with network messages from a NodeConn +# CBlock, CTransaction, CBlockHeader, CTxIn, CTxOut, etc....: +# data structures that should map to corresponding structures in +# bitcoin/primitives +# msg_block, msg_tx, msg_headers, etc.: +# data structures that represent network messages +# ser_*, deser_*: functions that handle serialization/deserialization + + +import struct +import socket +import asyncore +import time +import sys +import random +from binascii import hexlify +from io import BytesIO +from codecs import encode +import hashlib +from threading import RLock +from threading import Thread +import logging +import copy +from hashlib import blake2b + +from .equihash import ( + gbp_basic, + gbp_validate, + hash_nonce, + zcash_person, +) +from .util import bytes_to_hex_str + + +BIP0031_VERSION = 60000 +SPROUT_PROTO_VERSION = 170002 # past bip-31 for ping/pong +OVERWINTER_PROTO_VERSION = 170003 +SAPLING_PROTO_VERSION = 170006 +BLOSSOM_PROTO_VERSION = 170008 +NU5_PROTO_VERSION = 170050 + +MY_SUBVERSION = b"/python-mininode-tester:0.0.3/" + +SPROUT_VERSION_GROUP_ID = 0x00000000 +OVERWINTER_VERSION_GROUP_ID = 0x03C48270 +SAPLING_VERSION_GROUP_ID = 0x892F2085 +ZIP225_VERSION_GROUP_ID = 0x26A7270A +# No transaction format change in Blossom. + +MAX_INV_SZ = 50000 + +COIN = 100000000 # 1 zec in zatoshis + +# The placeholder value used for the auth digest of pre-v5 transactions. +LEGACY_TX_AUTH_DIGEST = (1 << 256) - 1 + +# Keep our own socket map for asyncore, so that we can track disconnects +# ourselves (to workaround an issue with closing an asyncore socket when +# using select) +mininode_socket_map = dict() + +# One lock for synchronizing all data access between the networking thread (see +# NetworkThread below) and the thread running the test logic. For simplicity, +# NodeConn acquires this lock whenever delivering a message to to a NodeConnCB, +# and whenever adding anything to the send buffer (in send_message()). This +# lock should be acquired in the thread running the test logic to synchronize +# access to any data shared with the NodeConnCB or NodeConn. +mininode_lock = RLock() + +# Serialization/deserialization tools +def sha256(s): + return hashlib.new('sha256', s).digest() + +def hash256(s): + return sha256(sha256(s)) + +def nuparams(branch_id, height): + return '-nuparams=%x:%d' % (branch_id, height) + +def fundingstream(idx, start_height, end_height, addrs): + return '-fundingstream=%d:%d:%d:%s' % (idx, start_height, end_height, ",".join(addrs)) + +def ser_compactsize(n): + if n < 253: + return struct.pack("B", n) + elif n < 0x10000: + return struct.pack(">= 32 + return rs + + +def uint256_from_str(s): + r = 0 + t = struct.unpack("> 24) & 0xFF + v = (c & 0xFFFFFF) << (8 * (nbytes - 3)) + return v + + +def block_work_from_compact(c): + target = uint256_from_compact(c) + return 2**256 // (target + 1) + + +def deser_vector(f, c): + nit = struct.unpack("H", f.read(2))[0] + + def serialize(self): + r = b"" + r += struct.pack("H", self.port) + return r + + def __repr__(self): + return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, + self.ip, self.port) + + +class CInv(object): + typemap = { + 0: b"Error", + 1: b"TX", + 2: b"Block", + 5: b"WTX", + } + + def __init__(self, t=0, h=0, h_aux=0): + self.type = t + self.hash = h + self.hash_aux = h_aux + if self.type == 1: + self.hash_aux = LEGACY_TX_AUTH_DIGEST + + def deserialize(self, f): + self.type = struct.unpack(" 0: + flags = struct.unpack("B", f.read(1))[0] + self.enableSpends = (flags & ORCHARD_FLAGS_ENABLE_SPENDS) != 0 + self.enableOutputs = (flags & ORCHARD_FLAGS_ENABLE_OUTPUTS) != 0 + self.valueBalance = struct.unpack(" 0: + r += struct.pack("B", self.flags()) + r += struct.pack(" 0 + if has_sapling: + self.valueBalance = struct.unpack(" 0: + self.anchor = deser_uint256(f) + for i in range(len(self.spends)): + self.spends[i].zkproof = Groth16Proof() + self.spends[i].zkproof.deserialize(f) + for i in range(len(self.spends)): + self.spends[i].spendAuthSig = RedJubjubSignature() + self.spends[i].spendAuthSig.deserialize(f) + for i in range(len(self.outputs)): + self.outputs[i].zkproof = Groth16Proof() + self.outputs[i].zkproof.deserialize(f) + if has_sapling: + self.bindingSig = RedJubjubSignature() + self.bindingSig.deserialize(f) + + def serialize(self): + r = b"" + r += ser_vector(self.spends) + r += ser_vector(self.outputs) + has_sapling = (len(self.spends) + len(self.outputs)) > 0 + if has_sapling: + r += struct.pack(" 0: + r += ser_uint256(self.anchor) + for spend in self.spends: + r += spend.zkproof.serialize() + for spend in self.spends: + r += spend.spendAuthSig.serialize() + for output in self.outputs: + r += output.zkproof.serialize() + if has_sapling: + r += self.bindingSig.serialize() + return r + + def __repr__(self): + return "SaplingBundle(spends=%r, outputs=%r, valueBalance=%i, bindingSig=%064x)" \ + % ( + self.spends, + self.outputs, + self.valueBalance, + self.bindingSig, + ) + + +G1_PREFIX_MASK = 0x02 +G2_PREFIX_MASK = 0x0a + +class ZCProof(object): + def __init__(self): + self.g_A = None + self.g_A_prime = None + self.g_B = None + self.g_B_prime = None + self.g_C = None + self.g_C_prime = None + self.g_K = None + self.g_H = None + + def deserialize(self, f): + def deser_g1(self, f): + leadingByte = struct.unpack("> 31) + self.nVersion = header & 0x7FFFFFFF + self.nVersionGroupId = (struct.unpack("= 2: + self.vJoinSplit = deser_vector(f, JSDescription) + if len(self.vJoinSplit) > 0: + self.joinSplitPubKey = deser_uint256(f) + self.joinSplitSig = f.read(64) + + if isSaplingV4 and not (len(self.shieldedSpends) == 0 and len(self.shieldedOutputs) == 0): + self.bindingSig = RedJubjubSignature() + self.bindingSig.deserialize(f) + + self.sha256 = None + self.hash = None + + def serialize(self): + header = (int(self.fOverwintered)<<31) | self.nVersion + isOverwinterV3 = (self.fOverwintered and + self.nVersionGroupId == OVERWINTER_VERSION_GROUP_ID and + self.nVersion == 3) + isSaplingV4 = (self.fOverwintered and + self.nVersionGroupId == SAPLING_VERSION_GROUP_ID and + self.nVersion == 4) + isNu5V5 = (self.fOverwintered and + self.nVersionGroupId == ZIP225_VERSION_GROUP_ID and + self.nVersion == 5) + + if isNu5V5: + r = b"" + + # Common transaction fields + r += struct.pack("= 2: + r += ser_vector(self.vJoinSplit) + if len(self.vJoinSplit) > 0: + r += ser_uint256(self.joinSplitPubKey) + r += self.joinSplitSig + if isSaplingV4 and not (len(self.shieldedSpends) == 0 and len(self.shieldedOutputs) == 0): + r += self.bindingSig.serialize() + return r + + def rehash(self): + self.sha256 = None + self.calc_sha256() + + def calc_sha256(self): + if self.nVersion >= 5: + from . import zip244 + txid = zip244.txid_digest(self) + self.auth_digest = zip244.auth_digest(self) + else: + txid = hash256(self.serialize()) + self.auth_digest = b'\xFF'*32 + if self.sha256 is None: + self.sha256 = uint256_from_str(txid) + self.hash = encode(txid[::-1], 'hex_codec').decode('ascii') + self.auth_digest_hex = encode(self.auth_digest[::-1], 'hex_codec').decode('ascii') + + def is_valid(self): + self.calc_sha256() + for tout in self.vout: + if tout.nValue < 0 or tout.nValue > 21000000 * 100000000: + return False + return True + + def __repr__(self): + r = ("CTransaction(fOverwintered=%r nVersion=%i nVersionGroupId=0x%08x " + "vin=%r vout=%r nLockTime=%i nExpiryHeight=%i " + "valueBalance=%i shieldedSpends=%r shieldedOutputs=%r" + % (self.fOverwintered, self.nVersion, self.nVersionGroupId, + self.vin, self.vout, self.nLockTime, self.nExpiryHeight, + self.valueBalance, self.shieldedSpends, self.shieldedOutputs)) + if self.nVersion >= 2: + r += " vJoinSplit=%r" % (self.vJoinSplit,) + if len(self.vJoinSplit) > 0: + r += " joinSplitPubKey=%064x joinSplitSig=%s" \ + % (self.joinSplitPubKey, bytes_to_hex_str(self.joinSplitSig)) + if len(self.shieldedSpends) > 0 or len(self.shieldedOutputs) > 0: + r += " bindingSig=%r" % self.bindingSig + r += ")" + return r + + +class CBlockHeader(object): + def __init__(self, header=None): + if header is None: + self.set_null() + else: + self.nVersion = header.nVersion + self.hashPrevBlock = header.hashPrevBlock + self.hashMerkleRoot = header.hashMerkleRoot + self.hashFinalSaplingRoot = header.hashFinalSaplingRoot + self.nTime = header.nTime + self.nBits = header.nBits + self.nNonce = header.nNonce + self.nSolution = header.nSolution + self.sha256 = header.sha256 + self.hash = header.hash + self.calc_sha256() + + def set_null(self): + self.nVersion = 4 + self.hashPrevBlock = 0 + self.hashMerkleRoot = 0 + self.hashFinalSaplingRoot = 0 + self.nTime = 0 + self.nBits = 0 + self.nNonce = 0 + self.nSolution = [] + self.sha256 = None + self.hash = None + + def deserialize(self, f): + self.nVersion = struct.unpack(" 1: + newhashes = [] + for i in range(0, len(hashes), 2): + i2 = min(i+1, len(hashes)-1) + newhashes.append(hash256(hashes[i] + hashes[i2])) + hashes = newhashes + return uint256_from_str(hashes[0]) + + def calc_auth_data_root(self): + hashes = [] + nleaves = 0 + for tx in self.vtx: + tx.calc_sha256() + hashes.append(tx.auth_digest) + nleaves += 1 + # Continue adding leaves (of zeros) until reaching a power of 2 + while nleaves & (nleaves-1) > 0: + hashes.append(b'\x00'*32) + nleaves += 1 + while len(hashes) > 1: + newhashes = [] + for i in range(0, len(hashes), 2): + digest = blake2b(digest_size=32, person=b'ZcashAuthDatHash') + digest.update(hashes[i]) + digest.update(hashes[i+1]) + newhashes.append(digest.digest()) + hashes = newhashes + return uint256_from_str(hashes[0]) + + def is_valid(self, n=48, k=5): + # H(I||... + digest = blake2b(digest_size=(512//n)*n//8, person=zcash_person(n, k)) + digest.update(super(CBlock, self).serialize()[:108]) + hash_nonce(digest, self.nNonce) + if not gbp_validate(self.nSolution, digest, n, k): + return False + self.calc_sha256() + target = uint256_from_compact(self.nBits) + if self.sha256 > target: + return False + for tx in self.vtx: + if not tx.is_valid(): + return False + if self.calc_merkle_root() != self.hashMerkleRoot: + return False + return True + + def solve(self, n=48, k=5): + target = uint256_from_compact(self.nBits) + # H(I||... + digest = blake2b(digest_size=(512//n)*n//8, person=zcash_person(n, k)) + digest.update(super(CBlock, self).serialize()[:108]) + self.nNonce = 0 + while True: + # H(I||V||... + curr_digest = digest.copy() + hash_nonce(curr_digest, self.nNonce) + # (x_1, x_2, ...) = A(I, V, n, k) + solns = gbp_basic(curr_digest, n, k) + for soln in solns: + assert(gbp_validate(curr_digest, soln, n, k)) + self.nSolution = soln + self.rehash() + if self.sha256 <= target: + return + self.nNonce += 1 + + def __repr__(self): + return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x hashFinalSaplingRoot=%064x nTime=%s nBits=%08x nNonce=%064x nSolution=%r vtx=%r)" \ + % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, + self.hashFinalSaplingRoot, time.ctime(self.nTime), self.nBits, + self.nNonce, self.nSolution, self.vtx) + + +class CUnsignedAlert(object): + def __init__(self): + self.nVersion = 1 + self.nRelayUntil = 0 + self.nExpiration = 0 + self.nID = 0 + self.nCancel = 0 + self.setCancel = [] + self.nMinVer = 0 + self.nMaxVer = 0 + self.setSubVer = [] + self.nPriority = 0 + self.strComment = b"" + self.strStatusBar = b"" + self.strReserved = b"" + + def deserialize(self, f): + self.nVersion = struct.unpack("= 106: + self.addrFrom = CAddress() + self.addrFrom.deserialize(f) + self.nNonce = struct.unpack("= 209: + self.nStartingHeight = struct.unpack(" +class msg_headers(object): + command = b"headers" + + def __init__(self): + self.headers = [] + + def deserialize(self, f): + # comment in bitcoind indicates these should be deserialized as blocks + blocks = deser_vector(f, CBlock) + for x in blocks: + self.headers.append(CBlockHeader(x)) + + def serialize(self): + blocks = [CBlock(x) for x in self.headers] + return ser_vector(blocks) + + def __repr__(self): + return "msg_headers(headers=%s)" % repr(self.headers) + + +class msg_reject(object): + command = b"reject" + REJECT_MALFORMED = 1 + + def __init__(self): + self.message = b"" + self.code = 0 + self.reason = b"" + self.data = 0 + + def deserialize(self, f): + self.message = deser_string(f) + self.code = struct.unpack("= 209: + conn.send_message(msg_verack()) + conn.ver_send = min(SPROUT_PROTO_VERSION, message.nVersion) + if message.nVersion < 209: + conn.ver_recv = conn.ver_send + + def on_verack(self, conn, message): + conn.ver_recv = conn.ver_send + self.verack_received = True + + def on_inv(self, conn, message): + want = msg_getdata() + for i in message.inv: + if i.type != 0: + want.inv.append(i) + if len(want.inv): + conn.send_message(want) + + def on_addr(self, conn, message): pass + def on_alert(self, conn, message): pass + def on_getdata(self, conn, message): pass + def on_notfound(self, conn, message): pass + def on_getblocks(self, conn, message): pass + def on_tx(self, conn, message): pass + def on_block(self, conn, message): pass + def on_getaddr(self, conn, message): pass + def on_headers(self, conn, message): pass + def on_getheaders(self, conn, message): pass + def on_ping(self, conn, message): + if conn.ver_send > BIP0031_VERSION: + conn.send_message(msg_pong(message.nonce)) + def on_reject(self, conn, message): pass + def on_close(self, conn): pass + def on_mempool(self, conn): pass + def on_pong(self, conn, message): pass + + +# The actual NodeConn class +# This class provides an interface for a p2p connection to a specified node +class NodeConn(asyncore.dispatcher): + messagemap = { + b"version": msg_version, + b"verack": msg_verack, + b"addr": msg_addr, + b"alert": msg_alert, + b"inv": msg_inv, + b"getdata": msg_getdata, + b"notfound": msg_notfound, + b"getblocks": msg_getblocks, + b"tx": msg_tx, + b"block": msg_block, + b"getaddr": msg_getaddr, + b"ping": msg_ping, + b"pong": msg_pong, + b"headers": msg_headers, + b"getheaders": msg_getheaders, + b"reject": msg_reject, + b"mempool": msg_mempool + } + MAGIC_BYTES = { + "mainnet": b"\x24\xe9\x27\x64", # mainnet + "testnet3": b"\xfa\x1a\xf9\xbf", # testnet3 + "regtest": b"\xaa\xe8\x3f\x5f" # regtest + } + + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", protocol_version=SAPLING_PROTO_VERSION): + asyncore.dispatcher.__init__(self, map=mininode_socket_map) + self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) + self.dstaddr = dstaddr + self.dstport = dstport + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + self.sendbuf = b"" + self.recvbuf = b"" + self.ver_send = 209 + self.ver_recv = 209 + self.last_sent = 0 + self.state = "connecting" + self.network = net + self.cb = callback + self.disconnect = False + + # stuff version msg into sendbuf + vt = msg_version(protocol_version) + vt.addrTo.ip = self.dstaddr + vt.addrTo.port = self.dstport + vt.addrFrom.ip = "0.0.0.0" + vt.addrFrom.port = 0 + self.send_message(vt, True) + print('MiniNode: Connecting to Bitcoin Node IP # ' + dstaddr + ':' \ + + str(dstport) + ' using version ' + str(protocol_version)) + + try: + self.connect((dstaddr, dstport)) + except: + self.handle_close() + self.rpc = rpc + + def show_debug_msg(self, msg): + self.log.debug(msg) + + def handle_connect(self): + self.show_debug_msg("MiniNode: Connected & Listening: \n") + self.state = b"connected" + + def handle_close(self): + self.show_debug_msg("MiniNode: Closing Connection to %s:%d... " + % (self.dstaddr, self.dstport)) + self.state = b"closed" + self.recvbuf = b"" + self.sendbuf = b"" + try: + self.close() + except: + pass + self.cb.on_close(self) + + def handle_read(self): + try: + t = self.recv(8192) + if len(t) > 0: + self.recvbuf += t + self.got_data() + except: + pass + + def readable(self): + return True + + def writable(self): + with mininode_lock: + length = len(self.sendbuf) + return (length > 0) + + def handle_write(self): + with mininode_lock: + try: + sent = self.send(self.sendbuf) + except: + self.handle_close() + return + self.sendbuf = self.sendbuf[sent:] + + def got_data(self): + try: + while True: + if len(self.recvbuf) < 4: + return + if self.recvbuf[:4] != self.MAGIC_BYTES[self.network]: + raise ValueError("got garbage %r" % (self.recvbuf,)) + if self.ver_recv < 209: + if len(self.recvbuf) < 4 + 12 + 4: + return + command = self.recvbuf[4:4+12].split(b"\x00", 1)[0] + msglen = struct.unpack("= 209: + th = sha256(data) + h = sha256(th) + tmsg += h[:4] + tmsg += data + with mininode_lock: + self.sendbuf += tmsg + self.last_sent = time.time() + + def got_message(self, message): + if message.command == b"version": + if message.nVersion <= BIP0031_VERSION: + self.messagemap[b'ping'] = msg_ping_prebip31 + if self.last_sent + 30 * 60 < time.time(): + self.send_message(self.messagemap[b'ping']()) + self.show_debug_msg("Recv %s" % repr(message)) + self.cb.deliver(self, message) + + def disconnect_node(self): + self.disconnect = True + + +class NetworkThread(Thread): + def run(self): + while mininode_socket_map: + # We check for whether to disconnect outside of the asyncore + # loop to workaround the behavior of asyncore when using + # select + disconnected = [] + for fd, obj in mininode_socket_map.items(): + if obj.disconnect: + disconnected.append(obj) + [ obj.handle_close() for obj in disconnected ] + asyncore.loop(0.1, use_poll=True, map=mininode_socket_map, count=1) + + +# An exception we can raise if we detect a potential disconnect +# (p2p or rpc) before the test is complete +class EarlyDisconnectError(Exception): + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) diff --git a/depend/zcash/qa/rpc-tests/test_framework/netutil.py b/depend/zcash/qa/rpc-tests/test_framework/netutil.py new file mode 100644 index 000000000..c8e69fbb2 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/netutil.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Linux network utilities + +import sys +import socket +import struct +import array +import os +from binascii import unhexlify, hexlify + +# Roughly based on https://web.archive.org/web/20190424172231/http://voorloopnul.com:80/blog/a-python-netstat-in-less-than-100-lines-of-code/ by Ricardo Pascal +STATE_ESTABLISHED = '01' +STATE_SYN_SENT = '02' +STATE_SYN_RECV = '03' +STATE_FIN_WAIT1 = '04' +STATE_FIN_WAIT2 = '05' +STATE_TIME_WAIT = '06' +STATE_CLOSE = '07' +STATE_CLOSE_WAIT = '08' +STATE_LAST_ACK = '09' +STATE_LISTEN = '0A' +STATE_CLOSING = '0B' + +def get_socket_inodes(pid): + ''' + Get list of socket inodes for process pid. + ''' + base = '/proc/%i/fd' % pid + inodes = [] + for item in os.listdir(base): + target = os.readlink(os.path.join(base, item)) + if target.startswith('socket:'): + inodes.append(int(target[8:-1])) + return inodes + +def _remove_empty(array): + return [x for x in array if x !=''] + +def _convert_ip_port(array): + host,port = array.split(':') + # convert host from mangled-per-four-bytes form as used by kernel + host = unhexlify(host) + host_out = '' + for x in range(0, len(host) // 4): + (val,) = struct.unpack('=I', host[x*4:(x+1)*4]) + host_out += '%08x' % val + + return host_out,int(port,16) + +def netstat(typ='tcp'): + ''' + Function to return a list with status of tcp connections at linux systems + To get pid of all network process running on system, you must run this script + as superuser + ''' + with open('/proc/net/'+typ,'r',encoding='utf8') as f: + content = f.readlines() + content.pop(0) + result = [] + for line in content: + line_array = _remove_empty(line.split(' ')) # Split lines and remove empty spaces. + tcp_id = line_array[0] + l_addr = _convert_ip_port(line_array[1]) + r_addr = _convert_ip_port(line_array[2]) + state = line_array[3] + inode = int(line_array[9]) # Need the inode to match with process pid. + nline = [tcp_id, l_addr, r_addr, state, inode] + result.append(nline) + return result + +def get_bind_addrs(pid): + ''' + Get bind addresses as (host,port) tuples for process pid. + ''' + inodes = get_socket_inodes(pid) + bind_addrs = [] + for conn in netstat('tcp') + netstat('tcp6'): + if conn[3] == STATE_LISTEN and conn[4] in inodes: + bind_addrs.append(conn[1]) + return bind_addrs + +# from: https://code.activestate.com/recipes/439093/ +def all_interfaces(): + ''' + Return all interfaces that are up + ''' + import fcntl + + is_64bits = sys.maxsize > 2**32 + struct_size = 40 if is_64bits else 32 + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + max_possible = 8 # initial value + while True: + bytes = max_possible * struct_size + names = array.array('B', b'\0' * bytes) + outbytes = struct.unpack('iL', fcntl.ioctl( + s.fileno(), + 0x8912, # SIOCGIFCONF + struct.pack('iL', bytes, names.buffer_info()[0]) + ))[0] + if outbytes == bytes: + max_possible *= 2 + else: + break + namestr = names.tostring() + return [(namestr[i:i+16].split(b'\0', 1)[0], + socket.inet_ntoa(namestr[i+20:i+24])) + for i in range(0, outbytes, struct_size)] + +def addr_to_hex(addr): + ''' + Convert string IPv4 or IPv6 address to binary address as returned by + get_bind_addrs. + Very naive implementation that certainly doesn't work for all IPv6 variants. + ''' + if '.' in addr: # IPv4 + addr = [int(x) for x in addr.split('.')] + elif ':' in addr: # IPv6 + sub = [[], []] # prefix, suffix + x = 0 + addr = addr.split(':') + for i,comp in enumerate(addr): + if comp == '': + if i == 0 or i == (len(addr)-1): # skip empty component at beginning or end + continue + x += 1 # :: skips to suffix + assert(x < 2) + else: # two bytes per component + val = int(comp, 16) + sub[x].append(val >> 8) + sub[x].append(val & 0xff) + nullbytes = 16 - len(sub[0]) - len(sub[1]) + assert((x == 0 and nullbytes == 0) or (x == 1 and nullbytes > 0)) + addr = sub[0] + ([0] * nullbytes) + sub[1] + else: + raise ValueError('Could not parse address %s' % addr) + return hexlify(bytearray(addr)).decode('ascii') + +def test_ipv6_local(): + ''' + Check for (local) IPv6 support. + ''' + import socket + # By using SOCK_DGRAM this will not actually make a connection, but it will + # fail if there is no route to IPv6 localhost. + have_ipv6 = True + try: + s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + s.connect(('::1', 0)) + except socket.error: + have_ipv6 = False + return have_ipv6 diff --git a/depend/zcash/qa/rpc-tests/test_framework/script.py b/depend/zcash/qa/rpc-tests/test_framework/script.py new file mode 100644 index 000000000..49192770d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/script.py @@ -0,0 +1,978 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# script.py +# +# This file is modified from python-bitcoinlib. +# + +"""Scripts + +Functionality to build scripts, as well as SignatureHash(). +""" + +import sys +bchr = chr +bord = ord +if sys.version > '3': + long = int + bchr = lambda x: bytes([x]) + bord = lambda x: x + +from hashlib import blake2b + +from binascii import hexlify +import struct + +from test_framework.bignum import bn2vch +from test_framework.mininode import (CTransaction, CTxOut, hash256, ser_string, ser_uint256) + +MAX_SCRIPT_SIZE = 10000 +MAX_SCRIPT_ELEMENT_SIZE = 520 +MAX_SCRIPT_OPCODES = 201 + +OPCODE_NAMES = {} + +_opcode_instances = [] +class CScriptOp(int): + """A single script opcode""" + __slots__ = [] + + @staticmethod + def encode_op_pushdata(d): + """Encode a PUSHDATA op, returning bytes""" + if len(d) < 0x4c: + return b'' + struct.pack('B', len(d)) + d # OP_PUSHDATA + elif len(d) <= 0xff: + return b'\x4c' + struct.pack('B', len(d)) + d # OP_PUSHDATA1 + elif len(d) <= 0xffff: + return b'\x4d' + struct.pack(b'>= 8 + if r[-1] & 0x80: + r.append(0x80 if neg else 0) + elif neg: + r[-1] |= 0x80 + return struct.pack("B", len(r)) + r + + +class CScript(bytes): + """Serialized script + + A bytes subclass, so you can use this directly whenever bytes are accepted. + Note that this means that indexing does *not* work - you'll get an index by + byte rather than opcode. This format was chosen for efficiency so that the + general case would not require creating a lot of little CScriptOP objects. + + iter(script) however does iterate by opcode. + """ + @classmethod + def __coerce_instance(cls, other): + # Coerce other into bytes + if isinstance(other, CScriptOp): + other = bytes([other]) + elif isinstance(other, CScriptNum): + if (other.value == 0): + other = bytes([CScriptOp(OP_0)]) + else: + other = CScriptNum.encode(other) + elif isinstance(other, int): + if 0 <= other <= 16: + other = bytes([CScriptOp.encode_op_n(other)]) + elif other == -1: + other = bytes([OP_1NEGATE]) + else: + other = CScriptOp.encode_op_pushdata(bn2vch(other)) + elif isinstance(other, (bytes, bytearray)): + other = bytes(CScriptOp.encode_op_pushdata(other)) + return other + + def __add__(self, other): + # Do the coercion outside of the try block so that errors in it are + # noticed. + other = self.__coerce_instance(other) + + try: + # bytes.__add__ always returns bytes instances unfortunately + return CScript(super(CScript, self).__add__(other)) + except TypeError: + raise TypeError('Can not add a %r instance to a CScript' % other.__class__) + + def join(self, iterable): + # join makes no sense for a CScript() + raise NotImplementedError + + def __new__(cls, value=b''): + if isinstance(value, bytes) or isinstance(value, bytearray): + return super(CScript, cls).__new__(cls, value) + else: + def coerce_iterable(iterable): + for instance in iterable: + yield cls.__coerce_instance(instance) + # Annoyingly on both python2 and python3 bytes.join() always + # returns a bytes instance even when subclassed. + return super(CScript, cls).__new__(cls, b''.join(coerce_iterable(value))) + + def raw_iter(self): + """Raw iteration + + Yields tuples of (opcode, data, sop_idx) so that the different possible + PUSHDATA encodings can be accurately distinguished, as well as + determining the exact opcode byte indexes. (sop_idx) + """ + i = 0 + while i < len(self): + sop_idx = i + opcode = bord(self[i]) + i += 1 + + if opcode > OP_PUSHDATA4: + yield (opcode, None, sop_idx) + else: + datasize = None + pushdata_type = None + if opcode < OP_PUSHDATA1: + pushdata_type = 'PUSHDATA(%d)' % opcode + datasize = opcode + + elif opcode == OP_PUSHDATA1: + pushdata_type = 'PUSHDATA1' + if i >= len(self): + raise CScriptInvalidError('PUSHDATA1: missing data length') + datasize = bord(self[i]) + i += 1 + + elif opcode == OP_PUSHDATA2: + pushdata_type = 'PUSHDATA2' + if i + 1 >= len(self): + raise CScriptInvalidError('PUSHDATA2: missing data length') + datasize = bord(self[i]) + (bord(self[i+1]) << 8) + i += 2 + + elif opcode == OP_PUSHDATA4: + pushdata_type = 'PUSHDATA4' + if i + 3 >= len(self): + raise CScriptInvalidError('PUSHDATA4: missing data length') + datasize = bord(self[i]) + (bord(self[i+1]) << 8) + (bord(self[i+2]) << 16) + (bord(self[i+3]) << 24) + i += 4 + + else: + assert False # shouldn't happen + + + data = bytes(self[i:i+datasize]) + + # Check for truncation + if len(data) < datasize: + raise CScriptTruncatedPushDataError('%s: truncated data' % pushdata_type, data) + + i += datasize + + yield (opcode, data, sop_idx) + + def __iter__(self): + """'Cooked' iteration + + Returns either a CScriptOP instance, an integer, or bytes, as + appropriate. + + See raw_iter() if you need to distinguish the different possible + PUSHDATA encodings. + """ + for (opcode, data, sop_idx) in self.raw_iter(): + if data is not None: + yield data + else: + opcode = CScriptOp(opcode) + + if opcode.is_small_int(): + yield opcode.decode_op_n() + else: + yield CScriptOp(opcode) + + def __repr__(self): + # For Python3 compatibility add b before strings so testcases don't + # need to change + def _repr(o): + if isinstance(o, bytes): + return b"x('%s')" % hexlify(o).decode('ascii') + else: + return repr(o) + + ops = [] + i = iter(self) + while True: + op = None + try: + op = _repr(next(i)) + except CScriptTruncatedPushDataError as err: + op = '%s...' % (_repr(err.data), err) + break + except CScriptInvalidError as err: + op = '' % err + break + except StopIteration: + break + finally: + if op is not None: + ops.append(op) + + return "CScript([%s])" % ', '.join(ops) + + def GetSigOpCount(self, fAccurate): + """Get the SigOp count. + + fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details. + + Note that this is consensus-critical. + """ + n = 0 + lastOpcode = OP_INVALIDOPCODE + for (opcode, data, sop_idx) in self.raw_iter(): + if opcode in (OP_CHECKSIG, OP_CHECKSIGVERIFY): + n += 1 + elif opcode in (OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY): + if fAccurate and (OP_1 <= lastOpcode <= OP_16): + n += opcode.decode_op_n() + else: + n += 20 + lastOpcode = opcode + return n + + +SIGHASH_ALL = 1 +SIGHASH_NONE = 2 +SIGHASH_SINGLE = 3 +SIGHASH_ANYONECANPAY = 0x80 + +def getHashPrevouts(tx, person=b'ZcashPrevoutHash'): + digest = blake2b(digest_size=32, person=person) + for x in tx.vin: + digest.update(x.prevout.serialize()) + return digest.digest() + +def getHashSequence(tx, person=b'ZcashSequencHash'): + digest = blake2b(digest_size=32, person=person) + for x in tx.vin: + digest.update(struct.pack('= len(txTo.vin): + raise ValueError("inIdx %d out of range (%d)" % (inIdx, len(txTo.vin))) + + if consensusBranchId != 0: + # ZIP 243 + hashPrevouts = b'\x00'*32 + hashSequence = b'\x00'*32 + hashOutputs = b'\x00'*32 + hashJoinSplits = b'\x00'*32 + hashShieldedSpends = b'\x00'*32 + hashShieldedOutputs = b'\x00'*32 + + if not (hashtype & SIGHASH_ANYONECANPAY): + hashPrevouts = getHashPrevouts(txTo) + + if (not (hashtype & SIGHASH_ANYONECANPAY)) and \ + (hashtype & 0x1f) != SIGHASH_SINGLE and \ + (hashtype & 0x1f) != SIGHASH_NONE: + hashSequence = getHashSequence(txTo) + + if (hashtype & 0x1f) != SIGHASH_SINGLE and \ + (hashtype & 0x1f) != SIGHASH_NONE: + hashOutputs = getHashOutputs(txTo) + elif (hashtype & 0x1f) == SIGHASH_SINGLE and \ + 0 <= inIdx and inIdx < len(txTo.vout): + digest = blake2b(digest_size=32, person=b'ZcashOutputsHash') + digest.update(txTo.vout[inIdx].serialize()) + hashOutputs = digest.digest() + + if len(txTo.vJoinSplit) > 0: + hashJoinSplits = getHashJoinSplits(txTo) + + if len(txTo.shieldedSpends) > 0: + hashShieldedSpends = getHashShieldedSpends(txTo) + + if len(txTo.shieldedOutputs) > 0: + hashShieldedOutputs = getHashShieldedOutputs(txTo) + + digest = blake2b( + digest_size=32, + person=b'ZcashSigHash' + struct.pack('= len(txtmp.vout): + raise ValueError("outIdx %d out of range (%d)" % (outIdx, len(txtmp.vout))) + + tmp = txtmp.vout[outIdx] + txtmp.vout = [] + for i in range(outIdx): + txtmp.vout.append(CTxOut()) + txtmp.vout.append(tmp) + + for i in range(len(txtmp.vin)): + if i != inIdx: + txtmp.vin[i].nSequence = 0 + + if hashtype & SIGHASH_ANYONECANPAY: + tmp = txtmp.vin[inIdx] + txtmp.vin = [] + txtmp.vin.append(tmp) + + s = txtmp.serialize() + s += struct.pack(b" 0: + d = s.recv(n) + if not d: + raise IOError('Unexpected end of stream') + rv.extend(d) + n -= len(d) + return rv + +### Implementation classes +class Socks5Configuration(object): + '''Proxy configuration''' + def __init__(self): + self.addr = None # Bind address (must be set) + self.af = socket.AF_INET # Bind address family + self.unauth = False # Support unauthenticated + self.auth = False # Support authentication + +class Socks5Command(object): + '''Information about an incoming socks5 command''' + def __init__(self, cmd, atyp, addr, port, username, password): + self.cmd = cmd # Command (one of Command.*) + self.atyp = atyp # Address type (one of AddressType.*) + self.addr = addr # Address + self.port = port # Port to connect to + self.username = username + self.password = password + def __repr__(self): + return 'Socks5Command(%s,%s,%s,%s,%s,%s)' % (self.cmd, self.atyp, self.addr, self.port, self.username, self.password) + +class Socks5Connection(object): + def __init__(self, serv, conn, peer): + self.serv = serv + self.conn = conn + self.peer = peer + + def handle(self): + ''' + Handle socks5 request according to RFC1928 + ''' + try: + # Verify socks version + ver = recvall(self.conn, 1)[0] + if ver != 0x05: + raise IOError('Invalid socks version %i' % ver) + # Choose authentication method + nmethods = recvall(self.conn, 1)[0] + methods = bytearray(recvall(self.conn, nmethods)) + method = None + if 0x02 in methods and self.serv.conf.auth: + method = 0x02 # username/password + elif 0x00 in methods and self.serv.conf.unauth: + method = 0x00 # unauthenticated + if method is None: + raise IOError('No supported authentication method was offered') + # Send response + self.conn.sendall(bytearray([0x05, method])) + # Read authentication (optional) + username = None + password = None + if method == 0x02: + ver = recvall(self.conn, 1)[0] + if ver != 0x01: + raise IOError('Invalid auth packet version %i' % ver) + ulen = recvall(self.conn, 1)[0] + username = str(recvall(self.conn, ulen)) + plen = recvall(self.conn, 1)[0] + password = str(recvall(self.conn, plen)) + # Send authentication response + self.conn.sendall(bytearray([0x01, 0x00])) + + # Read connect request + (ver,cmd,rsv,atyp) = recvall(self.conn, 4) + if ver != 0x05: + raise IOError('Invalid socks version %i in connect request' % ver) + if cmd != Command.CONNECT: + raise IOError('Unhandled command %i in connect request' % cmd) + + if atyp == AddressType.IPV4: + addr = recvall(self.conn, 4) + elif atyp == AddressType.DOMAINNAME: + n = recvall(self.conn, 1)[0] + addr = recvall(self.conn, n) + elif atyp == AddressType.IPV6: + addr = recvall(self.conn, 16) + else: + raise IOError('Unknown address type %i' % atyp) + port_hi,port_lo = recvall(self.conn, 2) + port = (port_hi << 8) | port_lo + + # Send dummy response + self.conn.sendall(bytearray([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) + + cmdin = Socks5Command(cmd, atyp, addr, port, username, password) + self.serv.queue.put(cmdin) + print('Proxy: ', cmdin) + # Fall through to disconnect + except Exception as e: + traceback.print_exc(file=sys.stderr) + self.serv.queue.put(e) + finally: + self.conn.close() + +class Socks5Server(object): + def __init__(self, conf): + self.conf = conf + self.s = socket.socket(conf.af) + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.s.bind(conf.addr) + self.s.listen(5) + self.running = False + self.thread = None + self.queue = queue.Queue() # report connections and exceptions to client + + def run(self): + while self.running: + (sockconn, peer) = self.s.accept() + if self.running: + conn = Socks5Connection(self, sockconn, peer) + thread = threading.Thread(None, conn.handle) + thread.daemon = True + thread.start() + + def start(self): + assert(not self.running) + self.running = True + self.thread = threading.Thread(None, self.run) + self.thread.daemon = True + self.thread.start() + + def stop(self): + self.running = False + # connect to self to end run loop + s = socket.socket(self.conf.af) + s.connect(self.conf.addr) + s.close() + self.thread.join() + diff --git a/depend/zcash/qa/rpc-tests/test_framework/test_framework.py b/depend/zcash/qa/rpc-tests/test_framework/test_framework.py new file mode 100755 index 000000000..d83692504 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/test_framework.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# Base class for RPC testing + +import logging +import optparse +import os +import sys +import shutil +import tempfile +import traceback + +from .authproxy import JSONRPCException +from .util import ( + ZCASHD_BINARY, + initialize_chain, + start_nodes, + connect_nodes_bi, + sync_blocks, + sync_mempools, + stop_nodes, + wait_bitcoinds, + enable_coverage, + check_json_precision, + initialize_chain_clean, + PortSeed, +) + + +class BitcoinTestFramework(object): + + def __init__(self): + self.num_nodes = 4 + self.setup_clean_chain = False + self.nodes = None + + def run_test(self): + raise NotImplementedError + + def add_options(self, parser): + pass + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + if self.setup_clean_chain: + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + else: + initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir) + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir) + + def setup_network(self, split = False, do_mempool_sync = True): + self.nodes = self.setup_nodes() + + # Connect the nodes as a "chain". This allows us + # to split the network between nodes 1 and 2 to get + # two halves that can work on competing chains. + + # If we joined network halves, connect the nodes from the joint + # on outward. This ensures that chains are properly reorganised. + if not split: + connect_nodes_bi(self.nodes, 1, 2) + sync_blocks(self.nodes[1:3]) + if do_mempool_sync: + sync_mempools(self.nodes[1:3]) + + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 2, 3) + self.is_network_split = split + self.sync_all(do_mempool_sync) + + def split_network(self): + """ + Split the network of four nodes into nodes 0/1 and 2/3. + """ + assert not self.is_network_split + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network(True) + + def sync_all(self, do_mempool_sync = True): + if self.is_network_split: + sync_blocks(self.nodes[:2]) + sync_blocks(self.nodes[2:]) + if do_mempool_sync: + sync_mempools(self.nodes[:2]) + sync_mempools(self.nodes[2:]) + else: + sync_blocks(self.nodes) + if do_mempool_sync: + sync_mempools(self.nodes) + + def join_network(self): + """ + Join the (previously split) network halves together. + """ + assert self.is_network_split + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network(False, False) + + def main(self): + + parser = optparse.OptionParser(usage="%prog [options]") + parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true", + help="Leave bitcoinds and test.* datadir on exit or error") + parser.add_option("--noshutdown", dest="noshutdown", default=False, action="store_true", + help="Don't stop bitcoinds after the test execution") + parser.add_option("--srcdir", dest="srcdir", default="../../src", + help="Source directory containing bitcoind/bitcoin-cli (default: %default)") + parser.add_option("--cachedir", dest="cachedir", default=os.path.normpath(os.path.dirname(os.path.realpath(__file__))+"/../../cache"), + help="Directory for caching pregenerated datadirs") + parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"), + help="Root directory for datadirs") + parser.add_option("--tracerpc", dest="trace_rpc", default=False, action="store_true", + help="Print out all RPC calls as they are made") + parser.add_option("--portseed", dest="port_seed", default=os.getpid(), type='int', + help="The seed to use for assigning port numbers (default: current process id)") + parser.add_option("--coveragedir", dest="coveragedir", + help="Write tested RPC commands into this directory") + self.add_options(parser) + (self.options, self.args) = parser.parse_args() + + self.options.tmpdir += '/' + str(self.options.port_seed) + + if self.options.trace_rpc: + logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) + + if self.options.coveragedir: + enable_coverage(self.options.coveragedir) + + PortSeed.n = self.options.port_seed + + os.environ['PATH'] = self.options.srcdir+":"+os.environ['PATH'] + + check_json_precision() + + success = False + try: + os.makedirs(self.options.tmpdir, exist_ok=False) + self.setup_chain() + self.setup_network() + self.run_test() + success = True + except JSONRPCException as e: + print("JSONRPC error: "+e.error['message']) + traceback.print_tb(sys.exc_info()[2]) + except AssertionError as e: + print("Assertion failed: " + str(e)) + traceback.print_tb(sys.exc_info()[2]) + except KeyError as e: + print("key not found: "+ str(e)) + traceback.print_tb(sys.exc_info()[2]) + except Exception as e: + print("Unexpected exception caught during testing: "+str(e)) + traceback.print_tb(sys.exc_info()[2]) + except KeyboardInterrupt as e: + print("Exiting after " + repr(e)) + + if not self.options.noshutdown: + print("Stopping nodes") + stop_nodes(self.nodes) + wait_bitcoinds() + else: + print("Note: bitcoinds were not stopped and may still be running") + + if not self.options.nocleanup and not self.options.noshutdown: + print("Cleaning up") + shutil.rmtree(self.options.tmpdir) + + if success: + print("Tests successful") + sys.exit(0) + else: + print("Failed") + sys.exit(1) + + +# Test framework for doing p2p comparison testing, which sets up some bitcoind +# binaries: +# 1 binary: test binary +# 2 binaries: 1 test binary, 1 ref binary +# n>2 binaries: 1 test binary, n-1 ref binaries + +class ComparisonTestFramework(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 1 + self.setup_clean_chain = True + + def add_options(self, parser): + parser.add_option("--testbinary", dest="testbinary", + default=os.getenv("ZCASHD", ZCASHD_BINARY), + help="zcashd binary to test") + parser.add_option("--refbinary", dest="refbinary", + default=os.getenv("ZCASHD", ZCASHD_BINARY), + help="zcashd binary to use for reference nodes (if any)") + + def setup_network(self): + self.nodes = start_nodes( + self.num_nodes, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']] * self.num_nodes, + binary=[self.options.testbinary] + + [self.options.refbinary]*(self.num_nodes-1)) + + def get_tests(self): + raise NotImplementedError diff --git a/depend/zcash/qa/rpc-tests/test_framework/util.py b/depend/zcash/qa/rpc-tests/test_framework/util.py new file mode 100644 index 000000000..04cccee84 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/util.py @@ -0,0 +1,675 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +# +# Helpful routines for regression testing +# + +import os +import sys + +from binascii import hexlify, unhexlify +from base64 import b64encode +from decimal import Decimal, ROUND_DOWN +import json +import http.client +import random +import shutil +import subprocess +import tempfile +import time +import re +import errno + +from . import coverage +from .authproxy import AuthServiceProxy, JSONRPCException + +ZCASHD_BINARY = os.path.join('src', 'zcashd') + +DEFAULT_FEE = Decimal('0.00001') +DEFAULT_FEE_ZATS = 1000 + +COVERAGE_DIR = None +PRE_BLOSSOM_BLOCK_TARGET_SPACING = 150 +POST_BLOSSOM_BLOCK_TARGET_SPACING = 75 + +SPROUT_BRANCH_ID = 0x00000000 +OVERWINTER_BRANCH_ID = 0x5BA81B19 +SAPLING_BRANCH_ID = 0x76B809BB +BLOSSOM_BRANCH_ID = 0x2BB40E60 +HEARTWOOD_BRANCH_ID = 0xF5B9230B +CANOPY_BRANCH_ID = 0xE9FF75A6 +NU5_BRANCH_ID = 0xC2D6D0B4 + +# The maximum number of nodes a single test can spawn +MAX_NODES = 8 +# Don't assign rpc or p2p ports lower than this +PORT_MIN = 11000 +# The number of ports to "reserve" for p2p and rpc, each +PORT_RANGE = 5000 + + +class PortSeed: + # Must be initialized with a unique integer for each process + n = None + +def enable_coverage(dirname): + """Maintain a log of which RPC calls are made during testing.""" + global COVERAGE_DIR + COVERAGE_DIR = dirname + + +def get_rpc_proxy(url, node_number, timeout=None): + """ + Args: + url (str): URL of the RPC server to call + node_number (int): the node number (or id) that this calls to + + Kwargs: + timeout (int): HTTP timeout in seconds + + Returns: + AuthServiceProxy. convenience object for making RPC calls. + + """ + proxy_kwargs = {} + if timeout is not None: + proxy_kwargs['timeout'] = timeout + + proxy = AuthServiceProxy(url, **proxy_kwargs) + proxy.url = url # store URL on proxy for info + + coverage_logfile = coverage.get_filename( + COVERAGE_DIR, node_number) if COVERAGE_DIR else None + + return coverage.AuthServiceProxyWrapper(proxy, coverage_logfile) + + +def p2p_port(n): + assert(n <= MAX_NODES) + return PORT_MIN + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) + +def rpc_port(n): + return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) + +def check_json_precision(): + """Make sure json library being used does not lose precision converting BTC values""" + n = Decimal("20000000.00000003") + satoshis = int(json.loads(json.dumps(float(n)))*1.0e8) + if satoshis != 2000000000000003: + raise RuntimeError("JSON encode/decode loses precision") + +def bytes_to_hex_str(byte_str): + return hexlify(byte_str).decode('ascii') + +def hex_str_to_bytes(hex_str): + return unhexlify(hex_str.encode('ascii')) + +def str_to_b64str(string): + return b64encode(string.encode('utf-8')).decode('ascii') + +def sync_blocks(rpc_connections, wait=0.125, timeout=60, allow_different_tips=False): + """ + Wait until everybody has the same tip, and has notified + all internal listeners of them. + + If allow_different_tips is True, waits until everyone has + the same block count. + """ + while timeout > 0: + if allow_different_tips: + tips = [ x.getblockcount() for x in rpc_connections ] + else: + tips = [ x.getbestblockhash() for x in rpc_connections ] + if tips == [ tips[0] ]*len(tips): + break + time.sleep(wait) + timeout -= wait + + # Now that the block counts are in sync, wait for the internal + # notifications to finish + while timeout > 0: + notified = [ x.getblockchaininfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + return True + time.sleep(wait) + timeout -= wait + + raise AssertionError("Block sync failed") + +def sync_mempools(rpc_connections, wait=0.5, timeout=60): + """ + Wait until everybody has the same transactions in their memory + pools, and has notified all internal listeners of them + """ + while timeout > 0: + pool = set(rpc_connections[0].getrawmempool()) + num_match = 1 + for i in range(1, len(rpc_connections)): + if set(rpc_connections[i].getrawmempool()) == pool: + num_match = num_match+1 + if num_match == len(rpc_connections): + break + time.sleep(wait) + timeout -= wait + + # Now that the mempools are in sync, wait for the internal + # notifications to finish + while timeout > 0: + notified = [ x.getmempoolinfo()['fullyNotified'] for x in rpc_connections ] + if notified == [ True ] * len(notified): + return True + time.sleep(wait) + timeout -= wait + + raise AssertionError("Mempool sync failed") + +bitcoind_processes = {} + +def initialize_datadir(dirname, n): + datadir = os.path.join(dirname, "node"+str(n)) + if not os.path.isdir(datadir): + os.makedirs(datadir) + rpc_u, rpc_p = rpc_auth_pair(n) + with open(os.path.join(datadir, "zcash.conf"), 'w', encoding='utf8') as f: + f.write("regtest=1\n") + f.write("showmetrics=0\n") + f.write("rpcuser=" + rpc_u + "\n") + f.write("rpcpassword=" + rpc_p + "\n") + f.write("port="+str(p2p_port(n))+"\n") + f.write("rpcport="+str(rpc_port(n))+"\n") + f.write("listenonion=0\n") + return datadir + +def rpc_auth_pair(n): + return 'rpcuser💻' + str(n), 'rpcpass🔑' + str(n) + +def rpc_url(i, rpchost=None): + rpc_u, rpc_p = rpc_auth_pair(i) + host = '127.0.0.1' + port = rpc_port(i) + if rpchost: + parts = rpchost.split(':') + if len(parts) == 2: + host, port = parts + else: + host = rpchost + return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, host, int(port)) + +def wait_for_bitcoind_start(process, url, i): + ''' + Wait for bitcoind to start. This means that RPC is accessible and fully initialized. + Raise an exception if bitcoind exits during initialization. + ''' + while True: + if process.poll() is not None: + raise Exception('bitcoind exited with status %i during initialization' % process.returncode) + try: + rpc = get_rpc_proxy(url, i) + rpc.getblockcount() + break # break out of loop on success + except IOError as e: + if e.errno != errno.ECONNREFUSED: # Port not yet open? + raise # unknown IO error + except JSONRPCException as e: # Initialization phase + if e.error['code'] != -28: # RPC in warmup? + raise # unknown JSON RPC exception + time.sleep(0.25) + +def initialize_chain(test_dir, num_nodes, cachedir): + """ + Create a cache of a 200-block-long chain (with wallet) for MAX_NODES + Afterward, create num_nodes copies from the cache + """ + + # Due to the consensus change fix for the timejacking attack, we need to + # ensure that the cache is pretty fresh. Specifically, we need the median + # time past of the chain tip of the cache to be no more than 90 minutes + # behind the current local time, or else mined blocks will be rejected by + # all nodes, halting the test. With Sapling active by default, this requires + # the chain tip itself to be no more than 75 minutes behind the current + # local time. + # + # We address this here, by regenerating the cache if it is more than 60 + # minutes old. This gives 15 minutes of slack initially that an RPC test has + # to complete in, if it is started right at the oldest cache time. Within an + # individual test, the first five calls to `generate` will each advance the + # median time past of the chain tip by 2.5 minutes (with Sapling active by + # default). Therefore, if the logic between the completion of any two + # adjacent calls to `generate` within a test takes longer than 2.5 minutes, + # the excess will subtract from the slack. + if os.path.isdir(os.path.join(cachedir, "node0")): + if os.stat(cachedir).st_mtime + (60 * 60) < time.time(): + print("initialize_chain(): Removing stale cache") + shutil.rmtree(cachedir) + + assert num_nodes <= MAX_NODES + create_cache = False + for i in range(MAX_NODES): + if not os.path.isdir(os.path.join(cachedir, 'node'+str(i))): + create_cache = True + break + + if create_cache: + + #find and delete old cache directories if any exist + for i in range(MAX_NODES): + if os.path.isdir(os.path.join(cachedir,"node"+str(i))): + shutil.rmtree(os.path.join(cachedir,"node"+str(i))) + + # Create cache directories, run bitcoinds: + for i in range(MAX_NODES): + datadir=initialize_datadir(cachedir, i) + args = [ os.getenv("ZCASHD", ZCASHD_BINARY), "-keypool=1", "-datadir="+datadir, "-discover=0" ] + args.extend([ + '-nuparams=5ba81b19:1', # Overwinter + '-nuparams=76b809bb:1', # Sapling + ]) + if i > 0: + args.append("-connect=127.0.0.1:"+str(p2p_port(0))) + bitcoind_processes[i] = subprocess.Popen(args) + if os.getenv("PYTHON_DEBUG", ""): + print("initialize_chain: bitcoind started, waiting for RPC to come up") + wait_for_bitcoind_start(bitcoind_processes[i], rpc_url(i), i) + if os.getenv("PYTHON_DEBUG", ""): + print("initialize_chain: RPC successfully started") + + rpcs = [] + for i in range(MAX_NODES): + try: + rpcs.append(get_rpc_proxy(rpc_url(i), i)) + except: + sys.stderr.write("Error connecting to "+rpc_url(i)+"\n") + sys.exit(1) + + # Create a 200-block-long chain; each of the 4 first nodes + # gets 25 mature blocks and 25 immature. + # Note: To preserve compatibility with older versions of + # initialize_chain, only 4 nodes will generate coins. + # + # Blocks are created with timestamps 2.5 minutes apart (matching the + # chain defaulting above to Sapling active), starting 200 * 2.5 minutes + # before the current time. + block_time = int(time.time()) - (200 * PRE_BLOSSOM_BLOCK_TARGET_SPACING) + for i in range(2): + for peer in range(4): + for j in range(25): + set_node_times(rpcs, block_time) + rpcs[peer].generate(1) + block_time += PRE_BLOSSOM_BLOCK_TARGET_SPACING + # Must sync before next peer starts generating blocks + sync_blocks(rpcs) + # Check that local time isn't going backwards + assert_greater_than(time.time() + 1, block_time) + + # Shut them down, and clean up cache directories: + stop_nodes(rpcs) + wait_bitcoinds() + for i in range(MAX_NODES): + os.remove(log_filename(cachedir, i, "debug.log")) + os.remove(log_filename(cachedir, i, "db.log")) + os.remove(log_filename(cachedir, i, "peers.dat")) + os.remove(log_filename(cachedir, i, "fee_estimates.dat")) + + for i in range(num_nodes): + from_dir = os.path.join(cachedir, "node"+str(i)) + to_dir = os.path.join(test_dir, "node"+str(i)) + shutil.copytree(from_dir, to_dir) + initialize_datadir(test_dir, i) # Overwrite port/rpcport in zcash.conf + +def initialize_chain_clean(test_dir, num_nodes): + """ + Create an empty blockchain and num_nodes wallets. + Useful if a test case wants complete control over initialization. + """ + for i in range(num_nodes): + initialize_datadir(test_dir, i) + + +def _rpchost_to_args(rpchost): + '''Convert optional IP:port spec to rpcconnect/rpcport args''' + if rpchost is None: + return [] + + match = re.match('(\[[0-9a-fA-f:]+\]|[^:]+)(?::([0-9]+))?$', rpchost) + if not match: + raise ValueError('Invalid RPC host spec ' + rpchost) + + rpcconnect = match.group(1) + rpcport = match.group(2) + + if rpcconnect.startswith('['): # remove IPv6 [...] wrapping + rpcconnect = rpcconnect[1:-1] + + rv = ['-rpcconnect=' + rpcconnect] + if rpcport: + rv += ['-rpcport=' + rpcport] + return rv + +def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): + """ + Start a bitcoind and return RPC connection to it + """ + datadir = os.path.join(dirname, "node"+str(i)) + if binary is None: + binary = os.getenv("ZCASHD", ZCASHD_BINARY) + args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] + args.extend([ + '-nuparams=5ba81b19:1', # Overwinter + '-nuparams=76b809bb:1', # Sapling + ]) + if extra_args is not None: args.extend(extra_args) + bitcoind_processes[i] = subprocess.Popen(args, stderr=stderr) + if os.getenv("PYTHON_DEBUG", ""): + print("start_node: bitcoind started, waiting for RPC to come up") + url = rpc_url(i, rpchost) + wait_for_bitcoind_start(bitcoind_processes[i], url, i) + if os.getenv("PYTHON_DEBUG", ""): + print("start_node: RPC successfully started") + proxy = get_rpc_proxy(url, i, timeout=timewait) + + if COVERAGE_DIR: + coverage.write_all_rpc_commands(COVERAGE_DIR, proxy) + + return proxy + +def assert_start_raises_init_error(i, dirname, extra_args=None, expected_msg=None): + with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: + try: + node = start_node(i, dirname, extra_args, stderr=log_stderr) + stop_node(node, i) + except Exception as e: + assert 'bitcoind exited' in str(e) #node must have shutdown + if expected_msg is not None: + log_stderr.seek(0) + stderr = log_stderr.read().decode('utf-8') + if expected_msg not in stderr: + raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) + else: + if expected_msg is None: + assert_msg = "bitcoind should have exited with an error" + else: + assert_msg = "bitcoind should have exited with expected error " + expected_msg + raise AssertionError(assert_msg) + +def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): + """ + Start multiple bitcoinds, return RPC connections to them + """ + if extra_args is None: extra_args = [ None for _ in range(num_nodes) ] + if binary is None: binary = [ None for _ in range(num_nodes) ] + rpcs = [] + try: + for i in range(num_nodes): + rpcs.append(start_node(i, dirname, extra_args[i], rpchost, binary=binary[i])) + except: # If one node failed to start, stop the others + stop_nodes(rpcs) + raise + return rpcs + +def log_filename(dirname, n_node, logname): + return os.path.join(dirname, "node"+str(n_node), "regtest", logname) + +def check_node(i): + bitcoind_processes[i].poll() + return bitcoind_processes[i].returncode + +def stop_node(node, i): + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) + bitcoind_processes[i].wait() + del bitcoind_processes[i] + +def stop_nodes(nodes): + for node in nodes: + try: + node.stop() + except http.client.CannotSendRequest as e: + print("WARN: Unable to stop node: " + repr(e)) + del nodes[:] # Emptying array closes connections as a side effect + +def set_node_times(nodes, t): + for node in nodes: + node.setmocktime(t) + +def wait_bitcoinds(): + # Wait for all bitcoinds to cleanly exit + for bitcoind in list(bitcoind_processes.values()): + bitcoind.wait() + bitcoind_processes.clear() + +def connect_nodes(from_connection, node_num): + ip_port = "127.0.0.1:"+str(p2p_port(node_num)) + from_connection.addnode(ip_port, "onetry") + # poll until version handshake complete to avoid race conditions + # with transaction relaying + while any(peer['version'] == 0 for peer in from_connection.getpeerinfo()): + time.sleep(0.1) + +def connect_nodes_bi(nodes, a, b): + connect_nodes(nodes[a], b) + connect_nodes(nodes[b], a) + +def find_output(node, txid, amount): + """ + Return index to output of txid with value amount + Raises exception if there is none. + """ + txdata = node.getrawtransaction(txid, 1) + for i in range(len(txdata["vout"])): + if txdata["vout"][i]["value"] == amount: + return i + raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount))) + + +def gather_inputs(from_node, amount_needed, confirmations_required=1): + """ + Return a random set of unspent txouts that are enough to pay amount_needed + """ + assert(confirmations_required >=0) + utxo = from_node.listunspent(confirmations_required) + random.shuffle(utxo) + inputs = [] + total_in = Decimal("0.00000000") + while total_in < amount_needed and len(utxo) > 0: + t = utxo.pop() + total_in += t["amount"] + inputs.append({ "txid" : t["txid"], "vout" : t["vout"], "address" : t["address"] } ) + if total_in < amount_needed: + raise RuntimeError("Insufficient funds: need %d, have %d"%(amount_needed, total_in)) + return (total_in, inputs) + +def make_change(from_node, amount_in, amount_out, fee): + """ + Create change output(s), return them + """ + outputs = {} + amount = amount_out+fee + change = amount_in - amount + if change > amount*2: + # Create an extra change output to break up big inputs + change_address = from_node.getnewaddress() + # Split change in two, being careful of rounding: + outputs[change_address] = Decimal(change/2).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN) + change = amount_in - amount - outputs[change_address] + if change > 0: + outputs[from_node.getnewaddress()] = change + return outputs + +def send_zeropri_transaction(from_node, to_node, amount, fee): + """ + Create&broadcast a zero-priority transaction. + Returns (txid, hex-encoded-txdata) + Ensures transaction is zero-priority by first creating a send-to-self, + then using its output + """ + + # Create a send-to-self with confirmed inputs: + self_address = from_node.getnewaddress() + (total_in, inputs) = gather_inputs(from_node, amount+fee*2) + outputs = make_change(from_node, total_in, amount+fee, fee) + outputs[self_address] = float(amount+fee) + + self_rawtx = from_node.createrawtransaction(inputs, outputs) + self_signresult = from_node.signrawtransaction(self_rawtx) + self_txid = from_node.sendrawtransaction(self_signresult["hex"], True) + + vout = find_output(from_node, self_txid, amount+fee) + # Now immediately spend the output to create a 1-input, 1-output + # zero-priority transaction: + inputs = [ { "txid" : self_txid, "vout" : vout } ] + outputs = { to_node.getnewaddress() : float(amount) } + + rawtx = from_node.createrawtransaction(inputs, outputs) + signresult = from_node.signrawtransaction(rawtx) + txid = from_node.sendrawtransaction(signresult["hex"], True) + + return (txid, signresult["hex"]) + +def random_zeropri_transaction(nodes, amount, min_fee, fee_increment, fee_variants): + """ + Create a random zero-priority transaction. + Returns (txid, hex-encoded-transaction-data, fee) + """ + from_node = random.choice(nodes) + to_node = random.choice(nodes) + fee = min_fee + fee_increment*random.randint(0,fee_variants) + (txid, txhex) = send_zeropri_transaction(from_node, to_node, amount, fee) + return (txid, txhex, fee) + +def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): + """ + Create a random transaction. + Returns (txid, hex-encoded-transaction-data, fee) + """ + from_node = random.choice(nodes) + to_node = random.choice(nodes) + fee = min_fee + fee_increment*random.randint(0,fee_variants) + + (total_in, inputs) = gather_inputs(from_node, amount+fee) + outputs = make_change(from_node, total_in, amount, fee) + outputs[to_node.getnewaddress()] = float(amount) + + rawtx = from_node.createrawtransaction(inputs, outputs) + signresult = from_node.signrawtransaction(rawtx) + txid = from_node.sendrawtransaction(signresult["hex"], True) + + return (txid, signresult["hex"], fee) + +def assert_equal(expected, actual, message=""): + if expected != actual: + if message: + message = "; %s" % message + raise AssertionError("(left == right)%s\n left: <%s>\n right: <%s>" % (message, str(expected), str(actual))) + +def assert_true(condition, message = ""): + if not condition: + raise AssertionError(message) + +def assert_false(condition, message = ""): + assert_true(not condition, message) + +def assert_greater_than(thing1, thing2): + if thing1 <= thing2: + raise AssertionError("%s <= %s"%(str(thing1),str(thing2))) + +def assert_raises(exc, fun, *args, **kwds): + assert_raises_message(exc, None, fun, *args, **kwds) + +def assert_raises_message(ExceptionType, errstr, func, *args, **kwargs): + """ + Asserts that func throws and that the exception contains 'errstr' + in its message. + """ + try: + func(*args, **kwargs) + except ExceptionType as e: + if errstr is not None and errstr not in str(e): + raise AssertionError("Invalid exception string: Couldn't find %r in %r" % ( + errstr, str(e))) + except Exception as e: + raise AssertionError("Unexpected exception raised: " + type(e).__name__) + else: + raise AssertionError("No exception raised") + +def fail(message=""): + raise AssertionError(message) + + +# Returns an async operation result +def wait_and_assert_operationid_status_result(node, myopid, in_status='success', in_errormsg=None, timeout=300): + print('waiting for async operation {}'.format(myopid)) + result = None + for _ in range(1, timeout): + results = node.z_getoperationresult([myopid]) + if len(results) > 0: + result = results[0] + break + time.sleep(1) + + assert_true(result is not None, "timeout occurred") + status = result['status'] + + debug = os.getenv("PYTHON_DEBUG", "") + if debug: + print('...returned status: {}'.format(status)) + + errormsg = None + if status == "failed": + errormsg = result['error']['message'] + if debug: + print('...returned error: {}'.format(errormsg)) + assert_equal(in_errormsg, errormsg) + + assert_equal(in_status, status, "Operation returned mismatched status. Error Message: {}".format(errormsg)) + + return result + + +# Returns txid if operation was a success or None +def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None, timeout=300): + result = wait_and_assert_operationid_status_result(node, myopid, in_status, in_errormsg, timeout) + if result['status'] == "success": + return result['result']['txid'] + else: + return None + +# Find a coinbase address on the node, filtering by the number of UTXOs it has. +# If no filter is provided, returns the coinbase address on the node containing +# the greatest number of spendable UTXOs. +# The default cached chain has one address per coinbase output. +def get_coinbase_address(node, expected_utxos=None): + addrs = [utxo['address'] for utxo in node.listunspent() if utxo['generated']] + assert(len(set(addrs)) > 0) + + if expected_utxos is None: + addrs = [(addrs.count(a), a) for a in set(addrs)] + return sorted(addrs, reverse=True)[0][1] + + addrs = [a for a in set(addrs) if addrs.count(a) == expected_utxos] + assert(len(addrs) > 0) + return addrs[0] + +def check_node_log(self, node_number, line_to_check, stop_node = True): + print("Checking node " + str(node_number) + " logs") + if stop_node: + self.nodes[node_number].stop() + bitcoind_processes[node_number].wait() + logpath = self.options.tmpdir + "/node" + str(node_number) + "/regtest/debug.log" + with open(logpath, "r", encoding="utf8") as myfile: + logdata = myfile.readlines() + for (n, logline) in enumerate(logdata): + if line_to_check in logline: + return n + raise AssertionError(repr(line_to_check) + " not found") + +def nustr(branch_id): + return '%08x' % branch_id + +def nuparams(branch_id, height): + return '-nuparams=%s:%d' % (nustr(branch_id), height) diff --git a/depend/zcash/qa/rpc-tests/test_framework/zip244.py b/depend/zcash/qa/rpc-tests/test_framework/zip244.py new file mode 100644 index 000000000..d8e1b7126 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/test_framework/zip244.py @@ -0,0 +1,294 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# zip244.py +# +# Functionality to create txids, auth digests, and signature digests. +# +# This file is modified from zcash/zcash-test-vectors. +# + +import struct + +from hashlib import blake2b + +from .mininode import ser_string, ser_uint256 +from .script import ( + SIGHASH_ANYONECANPAY, + SIGHASH_NONE, + SIGHASH_SINGLE, + getHashOutputs, + getHashPrevouts, + getHashSequence, +) + + +# Transparent + +def transparent_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxIdTranspaHash') + + if len(tx.vin) + len(tx.vout) > 0: + digest.update(getHashPrevouts(tx, b'ZTxIdPrevoutHash')) + digest.update(getHashSequence(tx, b'ZTxIdSequencHash')) + digest.update(getHashOutputs(tx, b'ZTxIdOutputsHash')) + + return digest.digest() + +def transparent_scripts_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxAuthTransHash') + for x in tx.vin: + digest.update(ser_string(x.scriptSig)) + return digest.digest() + +# Sapling + +def sapling_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSaplingHash') + + if len(saplingBundle.spends) + len(saplingBundle.outputs) > 0: + digest.update(sapling_spends_digest(saplingBundle)) + digest.update(sapling_outputs_digest(saplingBundle)) + digest.update(struct.pack(' 0: + for desc in saplingBundle.spends: + digest.update(desc.zkproof.serialize()) + for desc in saplingBundle.spends: + digest.update(desc.spendAuthSig.serialize()) + for desc in saplingBundle.outputs: + digest.update(desc.zkproof.serialize()) + digest.update(saplingBundle.bindingSig.serialize()) + + return digest.digest() + +# - Spends + +def sapling_spends_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendsHash') + + if len(saplingBundle.spends) > 0: + digest.update(sapling_spends_compact_digest(saplingBundle)) + digest.update(sapling_spends_noncompact_digest(saplingBundle)) + + return digest.digest() + +def sapling_spends_compact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendCHash') + for desc in saplingBundle.spends: + digest.update(ser_uint256(desc.nullifier)) + return digest.digest() + +def sapling_spends_noncompact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSSpendNHash') + for desc in saplingBundle.spends: + digest.update(ser_uint256(desc.cv)) + digest.update(ser_uint256(desc.anchor)) + digest.update(ser_uint256(desc.rk)) + return digest.digest() + +# - Outputs + +def sapling_outputs_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutputHash') + + if len(saplingBundle.outputs) > 0: + digest.update(sapling_outputs_compact_digest(saplingBundle)) + digest.update(sapling_outputs_memos_digest(saplingBundle)) + digest.update(sapling_outputs_noncompact_digest(saplingBundle)) + + return digest.digest() + +def sapling_outputs_compact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutC__Hash') + for desc in saplingBundle.outputs: + digest.update(ser_uint256(desc.cmu)) + digest.update(ser_uint256(desc.ephemeralKey)) + digest.update(desc.encCiphertext[:52]) + return digest.digest() + +def sapling_outputs_memos_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutM__Hash') + for desc in saplingBundle.outputs: + digest.update(desc.encCiphertext[52:564]) + return digest.digest() + +def sapling_outputs_noncompact_digest(saplingBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdSOutN__Hash') + for desc in saplingBundle.outputs: + digest.update(ser_uint256(desc.cv)) + digest.update(desc.encCiphertext[564:]) + digest.update(desc.outCiphertext) + return digest.digest() + +# Orchard + +def orchard_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrchardHash') + + if len(orchardBundle.actions) > 0: + digest.update(orchard_actions_compact_digest(orchardBundle)) + digest.update(orchard_actions_memos_digest(orchardBundle)) + digest.update(orchard_actions_noncompact_digest(orchardBundle)) + digest.update(struct.pack('B', orchardBundle.flags())) + digest.update(struct.pack(' 0: + digest.update(bytes(orchardBundle.proofs)) + for desc in orchardBundle.actions: + digest.update(desc.spendAuthSig.serialize()) + digest.update(orchardBundle.bindingSig.serialize()) + + return digest.digest() + +# - Actions + +def orchard_actions_compact_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActCHash') + for desc in orchardBundle.actions: + digest.update(ser_uint256(desc.nullifier)) + digest.update(ser_uint256(desc.cmx)) + digest.update(ser_uint256(desc.ephemeralKey)) + digest.update(desc.encCiphertext[:52]) + return digest.digest() + +def orchard_actions_memos_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActMHash') + for desc in orchardBundle.actions: + digest.update(desc.encCiphertext[52:564]) + return digest.digest() + +def orchard_actions_noncompact_digest(orchardBundle): + digest = blake2b(digest_size=32, person=b'ZTxIdOrcActNHash') + for desc in orchardBundle.actions: + digest.update(ser_uint256(desc.cv)) + digest.update(ser_uint256(desc.rk)) + digest.update(desc.encCiphertext[564:]) + digest.update(desc.outCiphertext) + return digest.digest() + +# Transaction + +def header_digest(tx): + digest = blake2b(digest_size=32, person=b'ZTxIdHeadersHash') + + digest.update(struct.pack(' 0: + with mininode_lock: + ready = True if waiting_for is None else waiting_for(self) is not None + if ready and self.last_pong.nonce == self.ping_counter: + self.ping_counter += 1 + return + time.sleep(sleep_time) + timeout -= sleep_time + fail("Should have received pong") + + +def create_transaction(node, coinbase, to_address, amount, expiry_height): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{"txid": from_txid, "vout": 0}] + outputs = {to_address: amount} + rawtx = node.createrawtransaction(inputs, outputs) + tx = CTransaction() + + # Set the expiry height + f = io.BytesIO(unhexlify(rawtx)) + tx.deserialize(f) + tx.nExpiryHeight = expiry_height + rawtx = tx.serialize().hex() + + signresult = node.signrawtransaction(rawtx) + f = io.BytesIO(unhexlify(signresult['hex'])) + tx.deserialize(f) + tx.rehash() + return tx diff --git a/depend/zcash/qa/rpc-tests/txn_doublespend.py b/depend/zcash/qa/rpc-tests/txn_doublespend.py new file mode 100755 index 000000000..b4879d441 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/txn_doublespend.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test proper accounting with malleable transactions +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes, \ + sync_blocks, gather_inputs + + +class TxnMallTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = False + + def add_options(self, parser): + parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true", + help="Test double-spend of 1-confirmed transaction") + + def setup_network(self): + # Start with split network: + return super(TxnMallTest, self).setup_network(True) + + def run_test(self): + mining_reward = 10 + starting_balance = mining_reward * 25 + + 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! + + # Coins are sent to node1_address + node1_address = self.nodes[1].getnewaddress("") + + # First: use raw transaction API to send (starting_balance - (mining_reward - 2)) BTC to node1_address, + # but don't broadcast: + (total_in, inputs) = gather_inputs(self.nodes[0], (starting_balance - (mining_reward - 2))) + change_address = self.nodes[0].getnewaddress("") + outputs = {} + outputs[change_address] = (mining_reward - 2) + outputs[node1_address] = (starting_balance - (mining_reward - 2)) + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + doublespend = self.nodes[0].signrawtransaction(rawtx) + assert_equal(doublespend["complete"], True) + + # Create two transaction from node[0] to node[1]; the + # second must spend change from the first because the first + # spends all mature inputs: + txid1 = self.nodes[0].sendtoaddress(node1_address, (starting_balance - (mining_reward - 2))) + txid2 = self.nodes[0].sendtoaddress(node1_address, 5) + + # Have node0 mine a block: + if (self.options.mine_block): + self.nodes[0].generate(1) + sync_blocks(self.nodes[0:2]) + + tx1 = self.nodes[0].gettransaction(txid1) + tx2 = self.nodes[0].gettransaction(txid2) + + # Node0's balance should be starting balance, plus mining_reward for another + # matured block, minus (starting_balance - (mining_reward - 2)), minus 5, and minus transaction fees: + expected = starting_balance + if self.options.mine_block: expected += mining_reward + expected += tx1["amount"] + tx1["fee"] + expected += tx2["amount"] + tx2["fee"] + assert_equal(self.nodes[0].getbalance(), expected) + + if self.options.mine_block: + assert_equal(tx1["confirmations"], 1) + assert_equal(tx2["confirmations"], 1) + # Node1's total balance should be its starting balance plus both transaction amounts: + assert_equal(self.nodes[1].getbalance("*"), starting_balance - (tx1["amount"]+tx2["amount"])) + else: + assert_equal(tx1["confirmations"], 0) + assert_equal(tx2["confirmations"], 0) + + # Now give doublespend to miner: + self.nodes[2].sendrawtransaction(doublespend["hex"]) + # ... mine a block... + self.nodes[2].generate(1) + + # Reconnect the split network, and sync chain: + connect_nodes(self.nodes[1], 2) + self.nodes[2].generate(1) # Mine another block to make sure we sync + sync_blocks(self.nodes) + + # Re-fetch transaction info: + tx1 = self.nodes[0].gettransaction(txid1) + tx2 = self.nodes[0].gettransaction(txid2) + + # Both transactions should be conflicted + assert_equal(tx1["confirmations"], -1) + assert_equal(tx2["confirmations"], -1) + + # Node0's total balance should be starting balance, plus (mining_reward * 2) for + # two more matured blocks, minus (starting_balance - (mining_reward - 2)) for the double-spend: + expected = starting_balance + (mining_reward * 2) - (starting_balance - (mining_reward - 2)) + assert_equal(self.nodes[0].getbalance(), expected) + assert_equal(self.nodes[0].getbalance("*"), expected) + + # Node1's total balance should be its starting balance plus the amount of the mutated send: + assert_equal(self.nodes[1].getbalance("*"), starting_balance + (starting_balance - (mining_reward - 2))) + +if __name__ == '__main__': + TxnMallTest().main() diff --git a/depend/zcash/qa/rpc-tests/upgrade_golden.py b/depend/zcash/qa/rpc-tests/upgrade_golden.py new file mode 100755 index 000000000..b115b22a0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/upgrade_golden.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + initialize_chain_clean, start_nodes, start_node, + bitcoind_processes) +from test_framework.util import ( + nuparams, + OVERWINTER_BRANCH_ID, SAPLING_BRANCH_ID, BLOSSOM_BRANCH_ID, HEARTWOOD_BRANCH_ID, CANOPY_BRANCH_ID) + +import shutil +import logging +import tarfile +import os +import os.path + +HAS_SAPLING = [nuparams(OVERWINTER_BRANCH_ID, 10), nuparams(SAPLING_BRANCH_ID, 20)] +HAS_BLOSSOM = HAS_SAPLING + [nuparams(BLOSSOM_BRANCH_ID, 30)] +HAS_HEARTWOOD = HAS_BLOSSOM + [nuparams(HEARTWOOD_BRANCH_ID, 40)] +HAS_CANOPY = HAS_HEARTWOOD + [nuparams(CANOPY_BRANCH_ID, 50)] + +class Upgrade(): + def __init__(self, h, p, a): + self.gen_height = h + self.tgz_path = p + self.extra_args = a + +class UpgradeGoldenTest(BitcoinTestFramework): + def setup_chain(self): + self.upgrades = [ Upgrade(35, os.path.dirname(os.path.realpath(__file__))+"/golden/blossom.tar.gz", HAS_BLOSSOM) + , Upgrade(45, os.path.dirname(os.path.realpath(__file__))+"/golden/heartwood.tar.gz", HAS_HEARTWOOD) + , Upgrade(55, os.path.dirname(os.path.realpath(__file__))+"/golden/canopy.tar.gz", HAS_CANOPY) + ] + + logging.info("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, len(self.upgrades) + 1) + + # This mirrors how the network was setup in the bash test + def setup_network(self, split=False): + logging.info("Initializing the network in "+self.options.tmpdir) + + # Node 0 will always be running with the most recent network upgrade version. + # The remaining nodes start with the network upgrade versions in order that they + # are specified in the upgrades list. + upgrade_args = [self.upgrades[-1].extra_args] + [u.extra_args for u in self.upgrades] + self.nodes = start_nodes(len(self.upgrades) + 1, self.options.tmpdir, extra_args=upgrade_args) + + def capture_blocks(self, to_height, tgz_path): + # Generate past the upgrade activation height. + self.nodes[0].generate(to_height) + self.nodes[0].stop() + bitcoind_processes[0].wait() + + node_path = self.options.tmpdir + "/node0/regtest" + os.remove(node_path + "/peers.dat") + with tarfile.open(tgz_path, "w:gz") as tgz: + tgz.add(node_path, arcname="") + + logging.info("Captured node state to "+tgz_path) + + def run_test(self): + last_upgrade = self.upgrades[-1] + if not os.path.isfile(last_upgrade.tgz_path): + self.capture_blocks(last_upgrade.gen_height, last_upgrade.tgz_path) + # restart the node after capturing the state + self.nodes[0] = start_node(0, self.options.tmpdir, extra_args=last_upgrade.extra_args) + + i = 1 + for upgrade in self.upgrades: + if os.path.isfile(upgrade.tgz_path): + # shut down the node so we can replace its data dir(s) + self.nodes[i].stop() + bitcoind_processes[i].wait() + + regtest_path = self.options.tmpdir+"/node"+ str(i)+"/regtest" + shutil.rmtree(regtest_path) + with tarfile.open(upgrade.tgz_path, "r:gz") as tgz: + tgz.extractall(path = regtest_path) + + # Upgrade each node to the latest network version. If any fails to + # start, this will fail the test. + try: + self.nodes[i] = start_node(i, self.options.tmpdir, extra_args=last_upgrade.extra_args) + except: + logging.error("An error occurred attempting to start node "+str(i)) + raise + + + +if __name__ == '__main__': + UpgradeGoldenTest().main() + diff --git a/depend/zcash/qa/rpc-tests/wallet.py b/depend/zcash/qa/rpc-tests/wallet.py new file mode 100755 index 000000000..9cea66632 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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, start_nodes, start_node, \ + connect_nodes_bi, sync_blocks, sync_mempools + +from decimal import Decimal + +class WalletTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 + + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir) + 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) + self.sync_all() + + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 40) + assert_equal(walletinfo['balance'], 0) + + blockchaininfo = self.nodes[0].getblockchaininfo() + assert_equal(blockchaininfo['estimatedheight'], 4) + + 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(), 0) + assert_equal(self.nodes[0].getbalance("*"), 40) + assert_equal(self.nodes[1].getbalance("*"), 10) + assert_equal(self.nodes[2].getbalance("*"), 0) + + # Send 21 ZEC from 0 to 2 using sendtoaddress call. + # Second transaction will be child of first, and will require a fee + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 0) + + blockchaininfo = self.nodes[0].getblockchaininfo() + assert_equal(blockchaininfo['estimatedheight'], 105) + + # Have node0 mine a block, thus it will collect its own fee. + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Have node1 generate 100 blocks (so node0 can recover the fee) + self.nodes[1].generate(100) + self.sync_all() + + # node0 should end up with 50 ZEC in block rewards plus fees, but + # minus the 21 ZEC plus fees sent to node2 + assert_equal(self.nodes[0].getbalance(), 50-21) + assert_equal(self.nodes[2].getbalance(), 21) + assert_equal(self.nodes[0].getbalance("*"), 50-21) + assert_equal(self.nodes[2].getbalance("*"), 21) + + # Node0 should have three unspent outputs. + # Create a couple of transactions to send them to node2, submit them through + # node1, and make sure both node0 and node2 pick them up properly: + node0utxos = self.nodes[0].listunspent(1) + assert_equal(len(node0utxos), 3) + + # Check 'generated' field of listunspent + # Node 0: has one coinbase utxo and two regular utxos + assert_equal(sum(int(uxto["generated"] is True) for uxto in node0utxos), 1) + # Node 1: has 101 coinbase utxos and no regular utxos + node1utxos = self.nodes[1].listunspent(1) + assert_equal(len(node1utxos), 101) + assert_equal(sum(int(uxto["generated"] is True) for uxto in node1utxos), 101) + # Node 2: has no coinbase utxos and two regular utxos + node2utxos = self.nodes[2].listunspent(1) + assert_equal(len(node2utxos), 2) + assert_equal(sum(int(uxto["generated"] is True) for uxto in node2utxos), 0) + + # Catch an attempt to send a transaction with an absurdly high fee. + # Send 1.0 ZEC from an utxo of value 10.0 ZEC but don't specify a change output, so then + # the change of 9.0 ZEC becomes the fee, which is greater than estimated fee of 0.0021 ZEC. + inputs = [] + outputs = {} + for utxo in node2utxos: + if utxo["amount"] == Decimal("10.0"): + break + assert_equal(utxo["amount"], Decimal("10.0")) + inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) + outputs[self.nodes[2].getnewaddress("")] = Decimal("1.0") + raw_tx = self.nodes[2].createrawtransaction(inputs, outputs) + signed_tx = self.nodes[2].signrawtransaction(raw_tx) + try: + self.nodes[2].sendrawtransaction(signed_tx["hex"]) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal(errorString, "256: absurdly-high-fee") + + # create both transactions + txns_to_send = [] + for utxo in node0utxos: + inputs = [] + outputs = {} + inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) + outputs[self.nodes[2].getnewaddress("")] = utxo["amount"] + raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) + txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx)) + + # Have node 1 (miner) send the transactions + self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True) + self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True) + self.nodes[1].sendrawtransaction(txns_to_send[2]["hex"], True) + + # Have node1 mine a block to confirm transactions: + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 0) + assert_equal(self.nodes[2].getbalance(), 50) + assert_equal(self.nodes[0].getbalance("*"), 0) + assert_equal(self.nodes[2].getbalance("*"), 50) + + # Send 10 ZEC normally + address = self.nodes[0].getnewaddress("") + self.nodes[2].settxfee(Decimal('0.001')) # not the default + self.nodes[2].sendtoaddress(address, 10, "", "", False) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('39.99900000')) + assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000')) + assert_equal(self.nodes[2].getbalance("*"), Decimal('39.99900000')) + assert_equal(self.nodes[0].getbalance("*"), Decimal('10.00000000')) + + # Send 10 ZEC with subtract fee from amount + self.nodes[2].sendtoaddress(address, 10, "", "", True) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('29.99900000')) + assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000')) + assert_equal(self.nodes[2].getbalance("*"), Decimal('29.99900000')) + assert_equal(self.nodes[0].getbalance("*"), Decimal('19.99900000')) + + # Sendmany 10 ZEC + self.nodes[2].sendmany("", {address: 10}, 0, "", []) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('19.99800000')) + assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000')) + assert_equal(self.nodes[2].getbalance("*"), Decimal('19.99800000')) + assert_equal(self.nodes[0].getbalance("*"), Decimal('29.99900000')) + + # Sendmany 10 ZEC with subtract fee from amount + self.nodes[2].sendmany("", {address: 10}, 0, "", [address]) + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('9.99800000')) + assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000')) + assert_equal(self.nodes[2].getbalance("*"), Decimal('9.99800000')) + assert_equal(self.nodes[0].getbalance("*"), Decimal('39.99800000')) + + # Test ResendWalletTransactions: + # Create a couple of transactions, then start up a fourth + # node (nodes[3]) and ask nodes[0] to rebroadcast. + # EXPECT: nodes[3] should have those transactions in its mempool. + txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) + txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) + sync_mempools(self.nodes) + + self.nodes.append(start_node(3, self.options.tmpdir)) + connect_nodes_bi(self.nodes, 0, 3) + sync_blocks(self.nodes) + + relayed = self.nodes[0].resendwallettransactions() + assert_equal(set(relayed), set([txid1, txid2])) + sync_mempools(self.nodes) + + assert(txid1 in self.nodes[3].getrawmempool()) + + # check integer balances from getbalance + assert_equal(self.nodes[2].getbalance("*", 1, False, True), 999800000) + + # send from node 0 to node 2 taddr + mytaddr = self.nodes[2].getnewaddress() + mytxid = self.nodes[0].sendtoaddress(mytaddr, 10.0) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + mybalance = self.nodes[2].z_getbalance(mytaddr) + assert_equal(mybalance, Decimal('10.0')) + + # check integer balances from z_getbalance + assert_equal(self.nodes[2].z_getbalance(mytaddr, 1, True), 1000000000) + + mytxdetails = self.nodes[2].gettransaction(mytxid) + myvjoinsplits = mytxdetails["vjoinsplit"] + assert_equal(0, len(myvjoinsplits)) + assert("joinSplitPubKey" not in mytxdetails) + assert("joinSplitSig" not in mytxdetails) + +if __name__ == '__main__': + WalletTest ().main () diff --git a/depend/zcash/qa/rpc-tests/wallet_1941.py b/depend/zcash/qa/rpc-tests/wallet_1941.py new file mode 100755 index 000000000..8aff2c5cd --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_1941.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# This is a regression test for #1941. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + initialize_datadir, start_nodes, start_node, connect_nodes_bi, \ + bitcoind_processes, wait_and_assert_operationid_status, \ + get_coinbase_address, DEFAULT_FEE + +from decimal import Decimal + +starttime = 1388534400 + +class Wallet1941RegressionTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 1) + + # Start nodes with -regtestshieldcoinbase to set fCoinbaseMustBeShielded to true. + def setup_network(self, split=False): + self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase','-debug=zrpc']] ) + self.is_network_split=False + + def add_second_node(self): + initialize_datadir(self.options.tmpdir, 1) + self.nodes.append(start_node(1, self.options.tmpdir, extra_args=['-regtestshieldcoinbase','-debug=zrpc'])) + self.nodes[1].setmocktime(starttime + 9000) + connect_nodes_bi(self.nodes,0,1) + self.sync_all() + + def restart_second_node(self, extra_args=[]): + self.nodes[1].stop() + bitcoind_processes[1].wait() + self.nodes[1] = start_node(1, self.options.tmpdir, extra_args=['-regtestshieldcoinbase','-debug=zrpc'] + extra_args) + self.nodes[1].setmocktime(starttime + 9000) + connect_nodes_bi(self.nodes, 0, 1) + self.sync_all() + + def run_test (self): + print("Mining blocks...") + + self.nodes[0].setmocktime(starttime) + self.nodes[0].generate(101) + self.sync_all() + + mytaddr = get_coinbase_address(self.nodes[0]) + myzaddr = self.nodes[0].z_getnewaddress() + + # Send 10 coins to our zaddr. + recipients = [] + recipients.append({"address":myzaddr, "amount":Decimal('10.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[0].generate(1) + + # Ensure the block times of the latest blocks exceed the variability + self.nodes[0].setmocktime(starttime + 3000) + self.nodes[0].generate(1) + self.nodes[0].setmocktime(starttime + 6000) + 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) + assert_equal(Decimal(resp), Decimal('10.0') - DEFAULT_FEE) + + # Export the key for the zaddr from node 0. + key = self.nodes[0].z_exportkey(myzaddr) + + # Start the new wallet + self.add_second_node() + self.nodes[1].getnewaddress() + self.nodes[1].z_getnewaddress() + self.nodes[1].generate(101) + self.sync_all() + + # Import the key on node 1, only scanning the last few blocks. + # (uses 'true' to test boolean fallback) + self.nodes[1].z_importkey(key, 'true', self.nodes[1].getblockchaininfo()['blocks'] - 100) + + # Confirm that the balance on node 1 is zero, as we have not + # rescanned over the older transactions + resp = self.nodes[1].z_getbalance(myzaddr) + assert_equal(Decimal(resp), 0) + + # Re-import the key on node 1, scanning from before the transaction. + self.nodes[1].z_importkey(key, 'yes', self.nodes[1].getblockchaininfo()['blocks'] - 110) + + # Confirm that the balance on node 1 is valid now (node 1 must + # have rescanned) + resp = self.nodes[1].z_getbalance(myzaddr) + assert_equal(Decimal(resp), Decimal('10.0') - DEFAULT_FEE) + + +if __name__ == '__main__': + Wallet1941RegressionTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_accounts.py b/depend/zcash/qa/rpc-tests/wallet_accounts.py new file mode 100755 index 000000000..68ee79bb5 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_accounts.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.authproxy import JSONRPCException +from test_framework.mininode import COIN +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + assert_raises_message, + assert_true, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet accounts behaviour +class WalletAccountsTest(BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 210), + ]] * self.num_nodes) + + def check_receiver_types(self, ua, expected): + actual = self.nodes[0].z_listunifiedreceivers(ua) + assert_equal(set(expected), set(actual)) + + def check_z_listaccounts(self, node, acct_id, addr_id, ua): + accounts = self.nodes[node].z_listaccounts() + assert_equal(accounts[acct_id]['addresses'][addr_id]['ua'], ua['address']) + assert_equal(accounts[acct_id]['addresses'][addr_id]['diversifier_index'], ua['diversifier_index']) + + # Check we only have balances in the expected pools. + # Remember that empty pools are omitted from the output. + def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf): + rpc = getattr(self.nodes[node], rpcmethod) + actual = rpc(account, minconf) + assert_equal(set(expected), set(actual['pools'])) + total_balance = 0 + for pool in expected: + assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat']) + total_balance += expected[pool] + assert_equal(actual['minimum_confirmations'], minconf) + return total_balance + + def check_balance(self, node, account, address, expected, minconf=1): + acct_balance = self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf) + z_getbalance = self.nodes[node].z_getbalance(address, minconf) + assert_equal(acct_balance, z_getbalance) + fvk = self.nodes[node].z_exportviewingkey(address) + self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf) + + def run_test(self): + # With a new wallet, the first account will be 0. + account0 = self.nodes[0].z_getnewaccount() + assert_equal(account0['account'], 0) + + # Verify that just creating the account does not generate any visible addresses + addresses = self.nodes[0].z_listaddresses() + assert_equal([], addresses) + accounts = self.nodes[0].z_listaccounts() + assert_equal(len(accounts), 1) + assert_equal(accounts[0]['account'], 0) + + # The next account will be 1. + account1 = self.nodes[0].z_getnewaccount() + assert_equal(account1['account'], 1) + accounts = self.nodes[0].z_listaccounts() + assert_equal(len(accounts), 2) + assert_equal(accounts[1]['account'], 1) + + # Generate the first address for account 0. + addr0 = self.nodes[0].z_getaddressforaccount(0) + assert_equal(addr0['account'], 0) + assert_equal(set(addr0['receiver_types']), set(['p2pkh', 'sapling', 'orchard'])) + ua0 = addr0['address'] + self.check_z_listaccounts(0, 0, 0, addr0) + + # We pick mnemonic phrases to ensure that we can always generate the default + # address in account 0; this is however not necessarily at diversifier index 0. + # We should be able to generate it directly and get the exact same data. + j = addr0['diversifier_index'] + assert_equal(self.nodes[0].z_getaddressforaccount(0, [], j), addr0) + if j > 0: + # We should get an error if we generate the address at diversifier index 0. + assert_raises_message( + JSONRPCException, + 'no address at diversifier index 0', + self.nodes[0].z_getaddressforaccount, 0, [], 0) + + # The second address for account 0 is different to the first address. + addr0_2 = self.nodes[0].z_getaddressforaccount(0) + assert_equal(addr0_2['account'], 0) + assert_equal(set(addr0_2['receiver_types']), set(['p2pkh', 'sapling', 'orchard'])) + ua0_2 = addr0_2['address'] + assert(ua0 != ua0_2) + self.check_z_listaccounts(0, 0, 1, addr0_2) + + # We can generate a fully-shielded address. + addr0_3 = self.nodes[0].z_getaddressforaccount(0, ['sapling', 'orchard']) + assert_equal(addr0_3['account'], 0) + assert_equal(set(addr0_3['receiver_types']), set(['sapling', 'orchard'])) + ua0_3 = addr0_3['address'] + self.check_z_listaccounts(0, 0, 2, addr0_3) + + # We can generate an address without a Sapling receiver. + addr0_4 = self.nodes[0].z_getaddressforaccount(0, ['p2pkh', 'orchard']) + assert_equal(addr0_4['account'], 0) + assert_equal(set(addr0_4['receiver_types']), set(['p2pkh', 'orchard'])) + ua0_4 = addr0_4['address'] + self.check_z_listaccounts(0, 0, 3, addr0_4) + + # The first address for account 1 is different to account 0. + addr1 = self.nodes[0].z_getaddressforaccount(1) + assert_equal(addr1['account'], 1) + assert_equal(set(addr1['receiver_types']), set(['p2pkh', 'sapling', 'orchard'])) + ua1 = addr1['address'] + assert(ua0 != ua1) + self.check_z_listaccounts(0, 1, 0, addr1) + + # The UA contains the expected receiver kinds. + self.check_receiver_types(ua0, ['p2pkh', 'sapling', 'orchard']) + self.check_receiver_types(ua0_2, ['p2pkh', 'sapling', 'orchard']) + self.check_receiver_types(ua0_3, [ 'sapling', 'orchard']) + self.check_receiver_types(ua0_4, ['p2pkh', 'orchard']) + self.check_receiver_types(ua1, ['p2pkh', 'sapling', 'orchard']) + + # The balances of the accounts are all zero. + self.check_balance(0, 0, ua0, {}) + self.check_balance(0, 1, ua1, {}) + + # Send coinbase funds to the UA. + print('Sending coinbase funds to account') + recipients = [{'address': ua0, 'amount': Decimal('10')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + txid = wait_and_assert_operationid_status(self.nodes[0], opid) + + # The wallet should detect the new note as belonging to the UA. + tx_details = self.nodes[0].z_viewtransaction(txid) + assert_equal(len(tx_details['outputs']), 1) + assert_equal(tx_details['outputs'][0]['type'], 'sapling') + assert_equal(tx_details['outputs'][0]['address'], ua0) + + # The new balance should not be visible with the default minconf, but should be + # visible with minconf=0. + self.sync_all() + self.check_balance(0, 0, ua0, {}) + self.check_balance(0, 0, ua0, {'sapling': 10}, 0) + + self.nodes[2].generate(1) + self.sync_all() + + # The default minconf should now detect the balance. + self.check_balance(0, 0, ua0, {'sapling': 10}) + + # Send Sapling funds from the UA. + print('Sending account funds to Sapling address') + node1sapling = self.nodes[1].z_getnewaddress('sapling') + + recipients = [{'address': node1sapling, 'amount': Decimal('1')}] + opid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0) + txid = wait_and_assert_operationid_status(self.nodes[0], opid) + + # The wallet should detect the spent note as belonging to the UA. + tx_details = self.nodes[0].z_viewtransaction(txid) + assert_equal(len(tx_details['spends']), 1) + assert_equal(tx_details['spends'][0]['type'], 'sapling') + assert_equal(tx_details['spends'][0]['address'], ua0) + + # The balances of the account should reflect whether zero-conf transactions are + # being considered. We will show either 0 (because the spent 10-ZEC note is never + # shown, as that transaction has been created and broadcast, and _might_ get mined + # up until the transaction expires), or 9 (if we include the unmined transaction). + self.sync_all() + self.check_balance(0, 0, ua0, {}) + self.check_balance(0, 0, ua0, {'sapling': 9}, 0) + + # Activate NU5 + print('Activating NU5') + self.nodes[2].generate(9) + self.sync_all() + assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 210) + + # Send more coinbase funds to the UA. + print('Sending coinbase funds to account') + recipients = [{'address': ua0, 'amount': Decimal('10')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + txid = wait_and_assert_operationid_status(self.nodes[0], opid) + + # The wallet should detect the new note as belonging to the UA. + tx_details = self.nodes[0].z_viewtransaction(txid) + assert_equal(len(tx_details['outputs']), 1) + assert_equal(tx_details['outputs'][0]['type'], 'orchard') + assert_equal(tx_details['outputs'][0]['address'], ua0) + + # The new balance should not be visible with the default minconf, but should be + # visible with minconf=0. + self.sync_all() + self.check_balance(0, 0, ua0, {'sapling': 9}) + self.check_balance(0, 0, ua0, {'sapling': 9, 'orchard': 10}, 0) + + # The total balance with the default minconf should be just the Sapling balance + assert_equal('9.00', self.nodes[0].z_gettotalbalance()['private']) + assert_equal('19.00', self.nodes[0].z_gettotalbalance(0)['private']) + + self.nodes[2].generate(1) + self.sync_all() + + # Send Orchard funds from the UA. + print('Sending account funds to Orchard-only UA') + node1account = self.nodes[1].z_getnewaccount()['account'] + node1orchard = self.nodes[1].z_getaddressforaccount(node1account, ['orchard']) + self.check_z_listaccounts(1, 0, 0, node1orchard) + node1orchard = node1orchard['address'] + + recipients = [{'address': node1orchard, 'amount': Decimal('1')}] + opid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0) + txid = wait_and_assert_operationid_status(self.nodes[0], opid) + + # The wallet should detect the spent note as belonging to the UA. + tx_details = self.nodes[0].z_viewtransaction(txid) + assert_equal(len(tx_details['spends']), 1) + assert_equal(tx_details['spends'][0]['type'], 'orchard') + assert_equal(tx_details['spends'][0]['address'], ua0) + + assert_equal(len(tx_details['outputs']), 2) + outputs = sorted(tx_details['outputs'], key=lambda x: x['valueZat']) + assert_equal(outputs[0]['type'], 'orchard') + assert_equal(outputs[0]['address'], node1orchard) + assert_equal(outputs[0]['valueZat'], 100000000) + # outputs[1] is change + assert_equal(outputs[1]['type'], 'orchard') + assert_true('address' not in outputs[1]) # + + # The balances of the account should reflect whether zero-conf transactions are + # being considered. The Sapling balance should remain at 9, while the Orchard + # balance will show either 0 (because the spent 10-ZEC note is never shown, as + # that transaction has been created and broadcast, and _might_ get mined up until + # the transaction expires), or 9 (if we include the unmined transaction). + self.sync_all() + self.check_balance(0, 0, ua0, {'sapling': 9}) + self.check_balance(0, 0, ua0, {'sapling': 9, 'orchard': 9}, 0) + + +if __name__ == '__main__': + WalletAccountsTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_addresses.py b/depend/zcash/qa/rpc-tests/wallet_addresses.py new file mode 100755 index 000000000..20ce16814 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_addresses.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes_bi, + start_nodes, + stop_nodes, + wait_bitcoinds, + NU5_BRANCH_ID, +) +from test_framework.mininode import nuparams + +# Test wallet address behaviour across network upgrades +class WalletAddressesTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + # need 2 nodes to import addresses + self.num_nodes = 2 + self.setup_clean_chain = True + + def setup_network(self): + self.nodes = start_nodes( + self.num_nodes, self.options.tmpdir, + extra_args=[[nuparams(NU5_BRANCH_ID, 2),]] * self.num_nodes) + connect_nodes_bi(self.nodes, 0, 1) + self.is_network_split = False + self.sync_all() + + def list_addresses(self, node, expected_sources): + addrs = self.nodes[node].listaddresses() + sources = [s['source'] for s in addrs] + # Sources should be unique. + assert_equal(len(set(sources)), len(sources)) + assert_equal(set(sources), set(expected_sources)) + + # Extract a list of all addresses from the output. + all_addrs = [ + source.get('transparent', {}).get('addresses', []) + + source.get('transparent', {}).get('changeAddresses', []) + + source.get('sprout', {}).get('addresses', []) + + [s['addresses'] for s in source.get('sapling', [])] + + [[a['address'] for a in s['addresses']] for s in source.get('unified', [])] + for source in addrs] + all_addrs = [a for s in all_addrs for a in s] + all_addrs = [a if type(a) == list else [a] for a in all_addrs] + all_addrs = [a for s in all_addrs for a in s] + + assert_equal(len(set(all_addrs)), len(all_addrs), "Duplicates in listaddresses output: %s" % addrs) + return addrs + + def run_test(self): + def get_source(listed_addresses, source): + return next(src for src in listed_addresses if src['source'] == source) + + print("Testing height 1 (Sapling)") + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].getblockcount(), 1) + listed_addresses = self.list_addresses(0, ['mnemonic_seed']) + # There should be a single address from the coinbase, which was derived + # from the mnemonic seed. + assert 'transparent' in get_source(listed_addresses, 'mnemonic_seed') + + # If we import a t-address, we should see imported_watchonly as a source. + taddr_import = self.nodes[1].getnewaddress() + self.nodes[0].importaddress(taddr_import) + listed_addresses = self.list_addresses(0, ['imported_watchonly', 'mnemonic_seed']) + imported_watchonly_src = get_source(listed_addresses, 'imported_watchonly') + assert_equal(imported_watchonly_src['transparent']['addresses'][0], taddr_import) + + account = self.nodes[0].z_getnewaccount()['account'] + sprout_1 = self.nodes[0].z_getnewaddress('sprout') + sapling_1 = self.nodes[0].z_getnewaddress('sapling') + unified_1 = self.nodes[0].z_getaddressforaccount(account)['address'] + types_and_addresses = [ + ('sprout', sprout_1), + ('sapling', sapling_1), + ('unified', unified_1), + ] + + for addr_type, addr in types_and_addresses: + res = self.nodes[0].z_validateaddress(addr) + assert res['isvalid'] + # assert res['ismine'] # this isn't present for unified addresses + assert_equal(res['type'], addr_type) + + # We should see the following sources: + # - imported_watchonly (for the previously-imported t-addr) + # - legacy_random (for the new Sprout address) + # - mnemonic_seed (for the previous t-addrs and the new Sapling and Unified addrs) + listed_addresses = self.list_addresses(0, ['imported_watchonly', 'legacy_random', 'mnemonic_seed']) + legacy_random_src = get_source(listed_addresses, 'legacy_random') + mnemonic_seed_src = get_source(listed_addresses, 'mnemonic_seed') + + # Check Sprout addrs + assert_equal(legacy_random_src['sprout']['addresses'], [sprout_1]) + + # Check Sapling addrs + assert_equal( + set([(obj['zip32KeyPath'], x) for obj in mnemonic_seed_src['sapling'] for x in obj['addresses']]), + set([("m/32'/1'/2147483647'/0'", sapling_1)]), + ) + + # Check Unified addrs + unified_obj = mnemonic_seed_src['unified'] + assert_equal(unified_obj[0]['account'], 0) + assert_equal(unified_obj[0]['addresses'][0]['address'], unified_1) + assert 'diversifier_index' in unified_obj[0]['addresses'][0] + assert_equal(unified_obj[0]['addresses'][0]['receiver_types'], ['p2pkh', 'sapling', 'orchard']) + + # import the key for sapling_1 into node 1 + sapling_1_key = self.nodes[0].z_exportkey(sapling_1) + self.nodes[1].z_importkey(sapling_1_key) + + # verify that we see the imported source + listed_addresses = self.list_addresses(1, ['imported', 'mnemonic_seed']) + imported_src = get_source(listed_addresses, 'imported') + assert_equal(imported_src['sapling'][0]['addresses'], [sapling_1]) + + # stop the nodes & restart to ensure that the imported address + # still shows up in listaddresses output + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + listed_addresses = self.list_addresses(1, ['imported', 'mnemonic_seed']) + imported_src = get_source(listed_addresses, 'imported') + assert_equal(imported_src['sapling'][0]['addresses'], [sapling_1]) + + print("Testing height 2 (NU5)") + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[0].getblockcount(), 2) + # Sprout address generation is no longer allowed + sapling_2 = self.nodes[0].z_getnewaddress('sapling') + unified_2 = self.nodes[0].z_getaddressforaccount(account)['address'] + types_and_addresses = [ + ('sapling', sapling_2), + ('unified', unified_2), + ] + + for addr_type, addr in types_and_addresses: + res = self.nodes[0].z_validateaddress(addr) + assert res['isvalid'] + # assert res['ismine'] # this isn't present for unified addresses + assert_equal(res['type'], addr_type) + + # We should see the same sources (address generation does not change across the NU5 boundary). + listed_addresses = self.list_addresses(0, ['imported_watchonly', 'legacy_random', 'mnemonic_seed']) + legacy_random_src = get_source(listed_addresses, 'legacy_random') + mnemonic_seed_src = get_source(listed_addresses, 'mnemonic_seed') + + # Check Sprout addrs + assert_equal(legacy_random_src['sprout']['addresses'], [sprout_1]) + + # Check Sapling addrs + assert_equal( + set([(obj['zip32KeyPath'], x) for obj in mnemonic_seed_src['sapling'] for x in obj['addresses']]), + set([ + ("m/32'/1'/2147483647'/0'", sapling_1), + ("m/32'/1'/2147483647'/1'", sapling_2), + ]), + ) + + # Check Unified addrs + unified_obj = mnemonic_seed_src['unified'] + assert_equal(unified_obj[0]['account'], 0) + assert_equal( + set([addr['address'] for addr in unified_obj[0]['addresses']]), + set([unified_1, unified_2]), + ) + assert 'diversifier_index' in unified_obj[0]['addresses'][0] + assert 'diversifier_index' in unified_obj[0]['addresses'][1] + assert_equal(unified_obj[0]['addresses'][0]['receiver_types'], ['p2pkh', 'sapling', 'orchard']) + assert_equal(unified_obj[0]['addresses'][1]['receiver_types'], ['p2pkh', 'sapling', 'orchard']) + + print("Generate mature coinbase, spend to create and detect change") + self.nodes[0].generate(100) + self.sync_all() + self.nodes[0].sendmany('', {taddr_import: 1}) + listed_addresses = self.list_addresses(0, ['imported_watchonly', 'legacy_random', 'mnemonic_seed']) + mnemonic_seed_src = get_source(listed_addresses, 'mnemonic_seed') + assert len(mnemonic_seed_src['transparent']['changeAddresses']) > 0 + + +if __name__ == '__main__': + WalletAddressesTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_anchorfork.py b/depend/zcash/qa/rpc-tests/wallet_anchorfork.py new file mode 100755 index 000000000..e259af27b --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_anchorfork.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, stop_nodes, connect_nodes_bi, \ + wait_and_assert_operationid_status, wait_bitcoinds, get_coinbase_address, \ + sync_blocks, sync_mempools, DEFAULT_FEE +from decimal import Decimal + +class WalletAnchorForkTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + # Start nodes with -regtestshieldcoinbase to set fCoinbaseMustBeShielded to true. + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase', '-debug=zrpc']] * 3 ) + 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) + self.sync_all() + + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 40) + assert_equal(walletinfo['balance'], 0) + + self.sync_all() + self.nodes[1].generate(102) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 40) + assert_equal(self.nodes[1].getbalance(), 20) + assert_equal(self.nodes[2].getbalance(), 0) + + # At this point in time, commitment tree is the empty root + + # Node 0 creates a joinsplit transaction + mytaddr0 = get_coinbase_address(self.nodes[0]) + myzaddr0 = self.nodes[0].z_getnewaddress() + recipients = [] + recipients.append({"address":myzaddr0, "amount": Decimal('10.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(mytaddr0, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Sync up mempools and mine the transaction. All nodes have the same anchor. + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Stop nodes. + stop_nodes(self.nodes) + wait_bitcoinds() + + # Relaunch nodes and partition network into two: + # A: node 0 + # B: node 1, 2 + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase', '-debug=zrpc']] * 3 ) + connect_nodes_bi(self.nodes,1,2) + + # Partition B, node 1 mines an empty block + self.nodes[1].generate(1) + + # Partition A, node 0 creates a joinsplit transaction + recipients = [] + recipients.append({"address":myzaddr0, "amount": Decimal('10.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(mytaddr0, recipients) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + rawhex = self.nodes[0].getrawtransaction(txid) + + # Partition A, node 0 mines a block with the transaction + self.nodes[0].generate(1) + # Same as self.sync_all() but only for node 0 + sync_blocks(self.nodes[:1]) + sync_mempools(self.nodes[:1]) + + # Partition B, node 1 mines the same joinsplit transaction + txid2 = self.nodes[1].sendrawtransaction(rawhex) + assert_equal(txid, txid2) + self.nodes[1].generate(1) + # Same as self.sync_all() but only for nodes 1 and 2 + sync_blocks(self.nodes[1:]) + sync_mempools(self.nodes[1:]) + + # Check that Partition B is one block ahead and that they have different tips + assert_equal(self.nodes[0].getblockcount() + 1, self.nodes[1].getblockcount()) + assert( self.nodes[0].getbestblockhash() != self.nodes[1].getbestblockhash()) + + # Shut down all nodes so any in-memory state is saved to disk + stop_nodes(self.nodes) + wait_bitcoinds() + + # Relaunch nodes and reconnect the entire network + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase', '-debug=zrpc']] * 3 ) + connect_nodes_bi(self.nodes,0, 1) + connect_nodes_bi(self.nodes,1, 2) + connect_nodes_bi(self.nodes,0, 2) + + # Mine a new block and let it propagate + self.nodes[1].generate(1) + + # Due to a bug in v1.0.0-1.0.3, node 0 will die with a tree root assertion, so sync_all() will throw an exception. + self.sync_all() + + # v1.0.4 will reach here safely + assert_equal( self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash()) + assert_equal( self.nodes[1].getbestblockhash(), self.nodes[2].getbestblockhash()) + +if __name__ == '__main__': + WalletAnchorForkTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_broadcast.py b/depend/zcash/qa/rpc-tests/wallet_broadcast.py new file mode 100755 index 000000000..f625c8aac --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_broadcast.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes_bi, start_nodes, stop_nodes, sync_blocks, wait_bitcoinds +from decimal import Decimal + +# Test wallet address behaviour across network upgrades +class WalletBroadcastTest(BitcoinTestFramework): + def run_test(self): + #do some -walletbroadcast tests + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"]] * 3) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.sync_all() + + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) + txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) + self.sync_all() + self.nodes[1].generate(1) #mine a block, tx should not be in there + self.sync_all() + assert_equal(self.nodes[2].getbalance(), Decimal('250.00000000')) #default should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance("*"), Decimal('250.00000000')) #default should not be changed because tx was not broadcasted + + #now broadcast from another node, mine a block, sync, and check the balance + self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) + assert_equal(self.nodes[2].getbalance(), Decimal('252.00000000')) #should not be + assert_equal(self.nodes[2].getbalance("*"), Decimal('252.00000000')) #should not be + + #create another tx + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) + + #restart the nodes with -walletbroadcast=1 + stop_nodes(self.nodes) + wait_bitcoinds() + self.nodes = start_nodes(3, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + sync_blocks(self.nodes) + + self.nodes[0].generate(1) + sync_blocks(self.nodes) + + # tx should be added to balance because after restarting the nodes tx should be broadcast + assert_equal(self.nodes[2].getbalance(), Decimal('254.00000000')) + assert_equal(self.nodes[2].getbalance("*"), Decimal('254.00000000')) + +if __name__ == '__main__': + WalletBroadcastTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_changeaddresses.py b/depend/zcash/qa/rpc-tests/wallet_changeaddresses.py new file mode 100755 index 000000000..409e2b94e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_changeaddresses.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# Copyright (c) 2019 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + connect_nodes_bi, + get_coinbase_address, + initialize_chain_clean, + start_node, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet change address behaviour +class WalletChangeAddressesTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + args = [ + '-nuparams=5ba81b19:1', # Overwinter + '-nuparams=76b809bb:1', # Sapling + '-txindex' # Avoid JSONRPC error: No information available about transaction + ] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes_bi(self.nodes,0,1) + self.is_network_split=False + self.sync_all() + + def run_test(self): + self.nodes[0].generate(110) + + # Obtain some transparent funds + midAddr = self.nodes[0].z_getnewaddress('sapling') + myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), midAddr, 0)['opid'] + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + taddrSource = self.nodes[0].getnewaddress() + for _ in range(6): + recipients = [{"address": taddrSource, "amount": Decimal('2')}] + myopid = self.nodes[0].z_sendmany(midAddr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + def check_change_taddr_reuse(target): + recipients = [{"address": target, "amount": Decimal('1')}] + + # Send funds to recipient address twice + myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0) + txid1 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0) + txid2 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + + # Verify that the two transactions used different change addresses + tx1 = self.nodes[0].getrawtransaction(txid1, 1) + tx2 = self.nodes[0].getrawtransaction(txid2, 1) + for i in range(len(tx1['vout'])): + tx1OutAddrs = tx1['vout'][i]['scriptPubKey']['addresses'] + tx2OutAddrs = tx2['vout'][i]['scriptPubKey']['addresses'] + if tx1OutAddrs != [target]: + print('Source address: %s' % taddrSource) + print('TX1 change address: %s' % tx1OutAddrs[0]) + print('TX2 change address: %s' % tx2OutAddrs[0]) + assert(tx1OutAddrs != tx2OutAddrs) + + taddr = self.nodes[0].getnewaddress() + saplingAddr = self.nodes[0].z_getnewaddress('sapling') + + print() + print('Checking z_sendmany(taddr->Sapling)') + check_change_taddr_reuse(saplingAddr) + print() + print('Checking z_sendmany(taddr->taddr)') + check_change_taddr_reuse(taddr) + +if __name__ == '__main__': + WalletChangeAddressesTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_changeindicator.py b/depend/zcash/qa/rpc-tests/wallet_changeindicator.py new file mode 100755 index 000000000..b091b2396 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_changeindicator.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, assert_false, wait_and_assert_operationid_status + +from decimal import Decimal + +class WalletChangeIndicatorTest (BitcoinTestFramework): + # Helper Methods + def generate_and_sync(self): + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Tests + def run_test(self): + taddr = self.nodes[1].getnewaddress() + zaddr1 = self.nodes[1].z_getnewaddress() + zaddr2 = self.nodes[1].z_getnewaddress() + + self.nodes[0].sendtoaddress(taddr, Decimal('1.0')) + self.generate_and_sync() + + # Send 1 ZEC to a zaddr + wait_and_assert_operationid_status(self.nodes[1], self.nodes[1].z_sendmany(taddr, [{'address': zaddr1, 'amount': 1.0, 'memo': 'c0ffee01'}], 1, 0)) + self.generate_and_sync() + + # Check that we have received 1 note which is not change + receivedbyaddress = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + listunspent = self.nodes[1].z_listunspent() + assert_equal(1, len(receivedbyaddress), "Should have received 1 note") + assert_false(receivedbyaddress[0]['change'], "Note should not be change") + assert_equal(1, len(listunspent), "Should have 1 unspent note") + assert_false(listunspent[0]['change'], "Unspent note should not be change") + + # Generate some change + wait_and_assert_operationid_status(self.nodes[1], self.nodes[1].z_sendmany(zaddr1, [{'address': zaddr2, 'amount': 0.6, 'memo': 'c0ffee02'}], 1, 0)) + self.generate_and_sync() + + # Check zaddr1 received + sortedreceived1 = sorted(self.nodes[1].z_listreceivedbyaddress(zaddr1, 0), key = lambda received: received['amount']) + assert_equal(2, len(sortedreceived1), "zaddr1 Should have received 2 notes") + assert_equal(Decimal('0.4'), sortedreceived1[0]['amount']) + assert_true(sortedreceived1[0]['change'], "Note valued at 0.4 should be change") + assert_equal(Decimal('1.0'), sortedreceived1[1]['amount']) + assert_false(sortedreceived1[1]['change'], "Note valued at 1.0 should not be change") + # Check zaddr2 received + sortedreceived2 = sorted(self.nodes[1].z_listreceivedbyaddress(zaddr2, 0), key = lambda received: received['amount']) + assert_equal(1, len(sortedreceived2), "zaddr2 Should have received 1 notes") + assert_equal(Decimal('0.6'), sortedreceived2[0]['amount']) + assert_false(sortedreceived2[0]['change'], "Note valued at 0.6 should not be change") + # Check unspent + sortedunspent = sorted(self.nodes[1].z_listunspent(), key = lambda received: received['amount']) + assert_equal(2, len(sortedunspent), "Should have 2 unspent notes") + assert_equal(Decimal('0.4'), sortedunspent[0]['amount']) + assert_true(sortedunspent[0]['change'], "Unspent note valued at 0.4 should be change") + assert_equal(Decimal('0.6'), sortedunspent[1]['amount']) + assert_false(sortedunspent[1]['change'], "Unspent note valued at 0.6 should not be change") + + # Give node 0 a viewing key + viewing_key = self.nodes[1].z_exportviewingkey(zaddr1) + self.nodes[0].z_importviewingkey(viewing_key) + received_node0 = self.nodes[0].z_listreceivedbyaddress(zaddr1, 0) + assert_equal(2, len(received_node0)) + unspent_node0 = self.nodes[0].z_listunspent(1, 9999999, True) + # Sapling viewing keys correctly detect spends, so we only see the unspent note + assert_equal(1, len(unspent_node0)) + # node 0 only has a viewing key so does not see the change field + assert_false('change' in received_node0[0]) + assert_false('change' in received_node0[1]) + assert_false('change' in unspent_node0[0]) + +if __name__ == '__main__': + WalletChangeIndicatorTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_db_flush.py b/depend/zcash/qa/rpc-tests/wallet_db_flush.py new file mode 100755 index 000000000..56fd83e9e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_db_flush.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . +# +# This test reproduces https://github.com/zcash/zcash/issues/4301 +# It takes an hour to run! + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + bitcoind_processes, + initialize_chain_clean, + start_node, +) +import time + +class WalletDBFlush (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 1) + + def start_node_with(self, index, extra_args=[]): + args = [ + "-nuparams=2bb40e60:1", # Blossom + "-nuparams=f5b9230b:2", # Heartwood + "-nurejectoldversions=false", + ] + return start_node(index, self.options.tmpdir, args + extra_args) + + def setup_network(self, split=False): + self.nodes = [] + self.nodes.append(self.start_node_with(0)) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print("PLEASE NOTE: This test takes an hour to run!") + + # This test requires shielded funds in the local wallet so + # there is witness data, and the easiest way to get shielded + # funds is to mine (since Heartwood, mining reward can go to + # a zaddr), so first create a Sapling address to mine to. + zaddr = self.nodes[0].z_getnewaddress('sapling') + self.nodes[0].generate(2) + + self.nodes[0].stop() + bitcoind_processes[0].wait() + + print("Start mining to address ", zaddr) + self.nodes[0] = self.start_node_with(0, [ + "-mineraddress=%s" % zaddr, + ]) + self.nodes[0].generate(1) + self.sync_all() + self.nodes[0].stop() + bitcoind_processes[0].wait() + + # If you replace main.cpp:3129 DATABASE_WRITE_INTERVAL with + # 60 (seconds), then sleeptime here can be 80, and this test + # will fail (pre-PR) much faster. + sleeptime = 3620 # just over one hour (DATABASE_WRITE_INTERVAL) + + print("Restart, sleep {}, mine (pre-PR will flush bad wallet state)".format(sleeptime)) + self.nodes[0] = self.start_node_with(0, [ + "-mineraddress=%s" % zaddr, + ]) + assert_equal(self.nodes[0].z_getbalance(zaddr, 0), 5) + time.sleep(sleeptime) + self.nodes[0].generate(1) + self.sync_all() + self.nodes[0].stop() + bitcoind_processes[0].wait() + + print("Restart, generate, expect assert in CopyPreviousWitnesses") + self.nodes[0] = self.start_node_with(0, [ + "-mineraddress=%s" % zaddr, + ]) + self.nodes[0].generate(1) + self.sync_all() + self.nodes[0].stop() + +if __name__ == '__main__': + WalletDBFlush().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_deprecation.py b/depend/zcash/qa/rpc-tests/wallet_deprecation.py new file mode 100755 index 000000000..ee2c7842f --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_deprecation.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + start_nodes, + stop_nodes, + wait_bitcoinds, +) +from test_framework.authproxy import JSONRPCException + +# Test wallet address behaviour across network upgrades +class WalletDeprecationTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 1 + + def setup_network(self): + self.setup_network_internal([]) + + def setup_network_internal(self, allowed_deprecated = []): + dep_args = ["-allowdeprecated=" + v for v in allowed_deprecated] + + self.nodes = start_nodes( + self.num_nodes, self.options.tmpdir, + extra_args=[dep_args] * self.num_nodes) + + def run_test(self): + # z_getnewaddress is deprecated, but enabled by default so it should succeed + self.nodes[0].z_getnewaddress() + + # zcrawkeygen is deprecated, and not enabled by default so it should fail + errorString = '' + try: + self.nodes[0].zcrawkeygen() + except JSONRPCException as e: + errorString = e.error['message'] + assert "DEPRECATED" in errorString + + # restart with a specific selection of deprecated methods enabled + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network_internal(["getnewaddress","zcrawkeygen"]) + + # z_getnewaddress is enabled by default, so it should succeed + self.nodes[0].z_getnewaddress() + + # getnewaddress and zcrawkeygen are enabled so they should succeed. + self.nodes[0].getnewaddress() + self.nodes[0].zcrawkeygen() + + # restart with no deprecated methods enabled + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network_internal(["none"]) + + errorString = '' + try: + self.nodes[0].z_getnewaddress() + except JSONRPCException as e: + errorString = e.error['message'] + assert "DEPRECATED" in errorString + + errorString = '' + try: + self.nodes[0].zcrawkeygen() + except JSONRPCException as e: + errorString = e.error['message'] + assert "DEPRECATED" in errorString + +if __name__ == '__main__': + WalletDeprecationTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_doublespend.py b/depend/zcash/qa/rpc-tests/wallet_doublespend.py new file mode 100755 index 000000000..4654b58ed --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_doublespend.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import shutil +import os.path + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + stop_nodes, + wait_bitcoinds, + wait_and_assert_operationid_status, +) + +# Test wallet behaviour with the Orchard protocol +class WalletDoubleSpendTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 201), + ]] * self.num_nodes) + + def run_test_for_recipient_type(self, recipient_type): + # Get a couple of new accounts + acct0a = self.nodes[0].z_getnewaccount()['account'] + ua0a = self.nodes[0].z_getaddressforaccount(acct0a, [recipient_type])['address'] + + acct0b = self.nodes[0].z_getnewaccount()['account'] + ua0b = self.nodes[0].z_getaddressforaccount(acct0b, [recipient_type])['address'] + + # Get a new UA for account 1 + acct1 = self.nodes[1].z_getnewaccount()['account'] + addrRes1 = self.nodes[1].z_getaddressforaccount(acct1, [recipient_type]) + ua1 = addrRes1['address'] + + # Create a note matching recipient_type on node 1 + recipients = [{"address": ua1, "amount": 10}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Check the value sent to ua1 was received + assert_equal( + {'pools': {recipient_type: {'valueZat': 1000000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Shut down the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + + # Copy node 1's wallet to node 2 + tmpdir = self.options.tmpdir + shutil.copyfile( + os.path.join(tmpdir, "node1", "regtest", "wallet.dat"), + os.path.join(tmpdir, "node2", "regtest", "wallet.dat")) + + # Restart with the network split + self.setup_network(True) + + # Verify the balance on node 1 + assert_equal( + {'pools': {recipient_type: {'valueZat': 1000000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Verify the balance on node 2, on the other side of the split + assert_equal( + {'pools': {recipient_type: {'valueZat': 1000000000}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct1)) + + # Spend the note from node 1 + recipients = [{"address": ua0a, "amount": 1}] + myopid = self.nodes[1].z_sendmany(ua1, recipients, 1, 0) + txa_id = wait_and_assert_operationid_status(self.nodes[1], myopid) + + # Spend the note from node 2 + recipients = [{"address": ua0b, "amount": 2}] + myopid = self.nodes[2].z_sendmany(ua1, recipients, 1, 0) + txb_id = wait_and_assert_operationid_status(self.nodes[2], myopid) + + # Mine the conflicting notes in the split + self.sync_all() + self.nodes[0].generate(2) + self.nodes[3].generate(10) + self.sync_all() + + # the remaining balance is visible on both sides of the split + assert_equal( + {'pools': {recipient_type: {'valueZat': 900000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + assert_equal( + {'pools': {recipient_type: {'valueZat': 800000000}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct1)) + + # before re-joining the network, there is no recognition of the conflict + txa = self.nodes[1].gettransaction(txa_id) + txb = self.nodes[2].gettransaction(txb_id) + assert_equal(2, txa['confirmations']); + assert_equal(10, txb['confirmations']); + assert_equal([], txa['walletconflicts']); + assert_equal([], txb['walletconflicts']); + + # acct0a will have received the transaction; it can't see node 2's send + assert_equal( + {'pools': {recipient_type: {'valueZat': 100000000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0a)) + + self.join_network() + + # after the network is re-joined, both transactions should be viewed as conflicted + txa = self.nodes[1].gettransaction(txa_id) + txb = self.nodes[1].gettransaction(txb_id) + assert_equal(-1, txa['confirmations']); + assert_equal(10, txb['confirmations']); + assert_equal([txb_id], txa['walletconflicts']); + assert_equal([txa_id], txb['walletconflicts']); + + # After the reorg, node 2 wins, so its balance is the consensus for + # both wallets + assert_equal( + {'pools': {recipient_type: {'valueZat': 800000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + assert_equal( + {'pools': {recipient_type: {'valueZat': 800000000}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct1)) + + # acct0b will have received the transaction + assert_equal( + {'pools': {recipient_type: {'valueZat': 200000000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0b)) + + # acct0a's note was un-mined + assert_equal( + {'pools': {}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0a)) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Activate NU5 + self.nodes[0].generate(1) + self.sync_all() + + self.run_test_for_recipient_type('sapling') + self.run_test_for_recipient_type('orchard') + +if __name__ == '__main__': + WalletDoubleSpendTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_import_export.py b/depend/zcash/qa/rpc-tests/wallet_import_export.py new file mode 100755 index 000000000..b5d091ac3 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_import_export.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, start_nodes + +class WalletImportExportTest (BitcoinTestFramework): + def setup_network(self, split=False): + num_nodes = 3 + extra_args = [([ + "-exportdir={}/export{}".format(self.options.tmpdir, i), + ] + (["-walletrequirebackup"] if i == 0 else [])) for i in range(num_nodes)] + self.nodes = start_nodes(num_nodes, self.options.tmpdir, extra_args) + + def run_test(self): + sapling_address2 = self.nodes[2].z_getnewaddress('sapling') + privkey2 = self.nodes[2].z_exportkey(sapling_address2) + self.nodes[0].z_importkey(privkey2) + + # test walletconfirmbackup + try: + self.nodes[0].getnewaddress() + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Error: Please acknowledge that you have backed up" in errorString, True) + try: + self.nodes[0].z_getnewaddress('sapling') + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Error: Please acknowledge that you have backed up" in errorString, True) + dump_path0 = self.nodes[0].z_exportwallet('walletdumpmnem') + (mnemonic, _, _, _) = parse_wallet_file(dump_path0) + self.nodes[0].walletconfirmbackup(mnemonic) + + # Now that we've confirmed backup, we can generate addresses + sprout_address0 = self.nodes[0].z_getnewaddress('sprout') + sapling_address0 = self.nodes[0].z_getnewaddress('sapling') + + # node 0 should have the keys + dump_path0 = self.nodes[0].z_exportwallet('walletdump') + (_, t_keys0, sprout_keys0, sapling_keys0) = parse_wallet_file(dump_path0) + + sapling_line_lengths = [len(sapling_key0.split(' #')[0].split()) for sapling_key0 in sapling_keys0.splitlines()] + assert_equal(2, len(sapling_line_lengths), "Should have 2 sapling keys") + assert_true(2 in sapling_line_lengths, "Should have a key with 2 parameters") + assert_true(4 in sapling_line_lengths, "Should have a key with 4 parameters") + + assert_true(sprout_address0 in sprout_keys0) + assert_true(sapling_address0 in sapling_keys0) + assert_true(sapling_address2 in sapling_keys0) + + # node 1 should not have the keys + dump_path1 = self.nodes[1].z_exportwallet('walletdumpbefore') + (_, t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path1) + + assert_true(sprout_address0 not in sprout_keys1) + assert_true(sapling_address0 not in sapling_keys1) + + # import wallet to node 1 + self.nodes[1].z_importwallet(dump_path0) + + # node 1 should now have the keys + dump_path1 = self.nodes[1].z_exportwallet('walletdumpafter') + (_, t_keys1, sprout_keys1, sapling_keys1) = parse_wallet_file(dump_path1) + + assert_true(sprout_address0 in sprout_keys1) + assert_true(sapling_address0 in sapling_keys1) + assert_true(sapling_address2 in sapling_keys1) + + # make sure we have preserved the metadata + for sapling_key0 in sapling_keys0.splitlines(): + assert_true(sapling_key0 in sapling_keys1) + +# Helper functions +def parse_wallet_file(dump_path): + file_lines = open(dump_path, "r", encoding="utf8").readlines() + # We expect information about the HDSeed and fingerpring in the header + assert_true("recovery_phrase" in file_lines[5], "Expected emergency recovery phrase") + assert_true("language" in file_lines[6], "Expected mnemonic seed language") + assert_true("fingerprint" in file_lines[7], "Expected mnemonic seed fingerprint") + mnemonic = file_lines[5].split("=")[1].replace("\"", "").strip() + (t_keys, i) = parse_wallet_file_lines(file_lines, 0) + (sprout_keys, i) = parse_wallet_file_lines(file_lines, i) + (sapling_keys, i) = parse_wallet_file_lines(file_lines, i) + + return (mnemonic, t_keys, sprout_keys, sapling_keys) + +def parse_wallet_file_lines(file_lines, i): + keys = [] + # skip blank lines and comments + while i < len(file_lines) and (file_lines[i] == '\n' or file_lines[i].startswith("#")): + i += 1 + # add keys until we hit another blank line or comment + while i < len(file_lines) and not (file_lines[i] == '\n' or file_lines[i].startswith("#")): + keys.append(file_lines[i]) + i += 1 + return ("".join(keys), i) + +if __name__ == '__main__': + WalletImportExportTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_isfromme.py b/depend/zcash/qa/rpc-tests/wallet_isfromme.py new file mode 100755 index 000000000..aefef0677 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_isfromme.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# Copyright (c) 2021 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + BLOSSOM_BRANCH_ID, + CANOPY_BRANCH_ID, + HEARTWOOD_BRANCH_ID, + OVERWINTER_BRANCH_ID, + SAPLING_BRANCH_ID, + assert_equal, + get_coinbase_address, + initialize_chain_clean, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +class WalletIsFromMe(BitcoinTestFramework): + def setup_chain(self): + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self, split=False): + self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[[ + nuparams(OVERWINTER_BRANCH_ID, 1), + nuparams(SAPLING_BRANCH_ID, 1), + nuparams(BLOSSOM_BRANCH_ID, 1), + nuparams(HEARTWOOD_BRANCH_ID, 1), + nuparams(CANOPY_BRANCH_ID, 1), + ]]) + self.is_network_split=False + + def run_test (self): + node = self.nodes[0] + + node.generate(101) + assert_equal(node.getbalance('', 0), Decimal('6.25')) + + coinbase_addr = get_coinbase_address(node) + + # Send all available funds to a z-address. + zaddr = node.z_getnewaddress() + wait_and_assert_operationid_status( + node, + node.z_sendmany( + coinbase_addr, + [ + {'address': zaddr, 'amount': Decimal('6.25')}, + ], + 0, + 0, + ), + ) + self.sync_all() + assert_equal(node.getbalance('', 0), 0) + + # Mine the transaction; we get another coinbase output. + self.nodes[0].generate(1) + self.sync_all() + assert_equal(node.getbalance('', 0), Decimal('6.25')) + + # Now send the funds back to a new t-address. + taddr = node.getnewaddress() + wait_and_assert_operationid_status( + node, + node.z_sendmany( + zaddr, + [ + {'address': taddr, 'amount': Decimal('6.25')}, + ], + 1, + 0, + ), + ) + self.sync_all() + + # At this point we have created the conditions for the bug in + # https://github.com/zcash/zcash/issues/5325. + + # listunspent should show the coinbase output, and optionally the + # newly-received unshielding output. + assert_equal(len(node.listunspent()), 1) + assert_equal(len(node.listunspent(0)), 2) + + # "getbalance '' 0" should count both outputs. The bug failed here. + assert_equal(node.getbalance('', 0), Decimal('12.5')) + +if __name__ == '__main__': + WalletIsFromMe().main () diff --git a/depend/zcash/qa/rpc-tests/wallet_listnotes.py b/depend/zcash/qa/rpc-tests/wallet_listnotes.py new file mode 100755 index 000000000..9e50376d6 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_listnotes.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + assert_true, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, + DEFAULT_FEE +) + +from decimal import Decimal + +# Test wallet z_listunspent behaviour across network upgrades +class WalletListNotes(BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 215), + ]] * 4) + + def run_test(self): + # Current height = 200 -> Sapling + assert_equal(200, self.nodes[0].getblockcount()) + sproutzaddr = self.nodes[0].z_getnewaddress('sprout') + + # 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 + self.nodes[0].generate(1) + self.sync_all() + assert_equal(201, self.nodes[0].getblockcount()) + + # Shield one coinbase output + receive_amount_1 = Decimal('10.0') - DEFAULT_FEE + result = self.nodes[0].z_shieldcoinbase('*', sproutzaddr, DEFAULT_FEE, 1) + txid_1 = wait_and_assert_operationid_status(self.nodes[0], result['opid']) + 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('sprout', unspent_cb[0]['pool']) + assert_equal(True, unspent_cb[0]['spendable']) + assert_equal(sproutzaddr, unspent_cb[0]['address']) + assert_equal(receive_amount_1, 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 + assert_equal(202, self.nodes[0].getblockcount()) + + # Send 1.0 minus default fee from sproutzaddr to a new Sapling zaddr + saplingzaddr = self.nodes[0].z_getnewaddress('sapling') + receive_amount_2 = Decimal('1.0') + change_amount_2 = receive_amount_1 - receive_amount_2 - DEFAULT_FEE + assert_equal('sapling', self.nodes[0].z_validateaddress(saplingzaddr)['type']) + recipients = [{"address": saplingzaddr, "amount":receive_amount_2}] + myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients, 1, DEFAULT_FEE) + 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('sapling', unspent_tx[0]['pool']) + assert_equal(True, unspent_tx[0]['spendable']) + assert_equal(saplingzaddr, unspent_tx[0]['address']) + assert_equal(receive_amount_2, unspent_tx[0]['amount']) + + assert_equal(True, unspent_tx[1]['change']) + assert_equal(txid_2, unspent_tx[1]['txid']) + assert_equal('sprout', unspent_tx[1]['pool']) + assert_equal(True, unspent_tx[1]['spendable']) + assert_equal(sproutzaddr, unspent_tx[1]['address']) + assert_equal(change_amount_2, unspent_tx[1]['amount']) + + unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [saplingzaddr]) + 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]) + + self.nodes[0].generate(1) + self.sync_all() + + # Send 2.0 minus default fee to a new sapling zaddr + saplingzaddr2 = self.nodes[0].z_getnewaddress('sapling') + receive_amount_3 = Decimal('2.0') + change_amount_3 = change_amount_2 - receive_amount_3 - DEFAULT_FEE + recipients = [{"address": saplingzaddr2, "amount":receive_amount_3}] + myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients, 1, DEFAULT_FEE) + txid_3 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + unspent_tx = self.nodes[0].z_listunspent(0) + assert_equal(3, len(unspent_tx)) + + # low-to-high in amount + 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('sapling', unspent_tx[0]['pool']) + assert_equal(True, unspent_tx[0]['spendable']) + assert_equal(saplingzaddr, unspent_tx[0]['address']) + assert_equal(receive_amount_2, unspent_tx[0]['amount']) + + assert_equal(False, unspent_tx[1]['change']) + assert_equal(txid_3, unspent_tx[1]['txid']) + assert_equal('sapling', unspent_tx[1]['pool']) + assert_equal(True, unspent_tx[1]['spendable']) + assert_equal(saplingzaddr2, unspent_tx[1]['address']) + assert_equal(receive_amount_3, unspent_tx[1]['amount']) + + assert_equal(True, unspent_tx[2]['change']) + assert_equal(txid_3, unspent_tx[2]['txid']) + assert_equal('sprout', unspent_tx[2]['pool']) + assert_equal(True, unspent_tx[2]['spendable']) + assert_equal(sproutzaddr, unspent_tx[2]['address']) + assert_equal(change_amount_3, unspent_tx[2]['amount']) + + unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [saplingzaddr]) + assert_equal(1, len(unspent_tx_filter)) + assert_equal(unspent_tx[0], unspent_tx_filter[0]) + + # test that pre- and post-sapling can be filtered in a single call + unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, + [sproutzaddr, saplingzaddr]) + assert_equal(2, len(unspent_tx_filter)) + unspent_tx_filter = sorted(unspent_tx_filter, key=lambda k: k['amount']) + assert_equal(unspent_tx[0], unspent_tx_filter[0]) + assert_equal(unspent_tx[2], unspent_tx_filter[1]) + + # so far, this node has no watchonly addresses, so results are the same + unspent_tx_watchonly = self.nodes[0].z_listunspent(0, 9999, True) + unspent_tx_watchonly = sorted(unspent_tx_watchonly, key=lambda k: k['amount']) + assert_equal(unspent_tx, unspent_tx_watchonly) + + # TODO: use z_exportviewingkey, z_importviewingkey to test includeWatchonly + # but this requires Sapling support for those RPCs + + # Set current height to 215 -> NU5 + self.nodes[0].generate(12) + self.sync_all() + assert_equal(215, self.nodes[0].getblockcount()) + + # Create an Orchard note. + account0 = self.nodes[0].z_getnewaccount()['account'] + ua0 = self.nodes[0].z_getaddressforaccount(account0)['address'] + receive_amount_4 = Decimal('10.0') + recipients = [{"address": ua0, "amount": receive_amount_4}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + txid_4 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + + unspent_tx = self.nodes[0].z_listunspent(0) + assert_equal(4, len(unspent_tx)) + # low-to-high in amount + 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('sapling', unspent_tx[0]['pool']) + assert_equal(True, unspent_tx[0]['spendable']) + assert_true('account' not in unspent_tx[0]) + assert_equal(saplingzaddr, unspent_tx[0]['address']) + assert_equal(receive_amount_2, unspent_tx[0]['amount']) + + assert_equal(False, unspent_tx[1]['change']) + assert_equal(txid_3, unspent_tx[1]['txid']) + assert_equal('sapling', unspent_tx[1]['pool']) + assert_equal(True, unspent_tx[1]['spendable']) + assert_true('account' not in unspent_tx[1]) + assert_equal(saplingzaddr2, unspent_tx[1]['address']) + assert_equal(receive_amount_3, unspent_tx[1]['amount']) + + assert_equal(True, unspent_tx[2]['change']) + assert_equal(txid_3, unspent_tx[2]['txid']) + assert_equal('sprout', unspent_tx[2]['pool']) + assert_equal(True, unspent_tx[2]['spendable']) + assert_true('account' not in unspent_tx[2]) + assert_equal(sproutzaddr, unspent_tx[2]['address']) + assert_equal(change_amount_3, unspent_tx[2]['amount']) + + assert_equal(False, unspent_tx[3]['change']) + assert_equal(txid_4, unspent_tx[3]['txid']) + assert_equal('orchard', unspent_tx[3]['pool']) + assert_equal(True, unspent_tx[3]['spendable']) + assert_equal(account0, unspent_tx[3]['account']) + assert_equal(ua0, unspent_tx[3]['address']) + assert_equal(receive_amount_4, unspent_tx[3]['amount']) + +if __name__ == '__main__': + WalletListNotes().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_listreceived.py b/depend/zcash/qa/rpc-tests/wallet_listreceived.py new file mode 100755 index 000000000..4df19ff50 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_listreceived.py @@ -0,0 +1,553 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.authproxy import JSONRPCException +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_true, + assert_false, + assert_raises_message, + connect_nodes_bi, + get_coinbase_address, + nuparams, + DEFAULT_FEE, + DEFAULT_FEE_ZATS, + NU5_BRANCH_ID, +) +from test_framework.util import wait_and_assert_operationid_status, start_nodes +from decimal import Decimal + +my_memo_str = 'c0ffee' # stay awake +my_memo = '633066666565' +my_memo = my_memo + '0'*(1024-len(my_memo)) + +no_memo = 'f6' + ('0'*1022) # see section 5.5 of the protocol spec + +class ListReceivedTest (BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 3 + self.setup_clean_chain = True + + def setup_network(self): + self.nodes = start_nodes( + self.num_nodes, self.options.tmpdir, + extra_args=[[ + nuparams(NU5_BRANCH_ID, 225), + ]] * self.num_nodes + ) + 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 generate_and_sync(self, new_height): + current_height = self.nodes[0].getblockcount() + assert(new_height > current_height) + self.sync_all() + self.nodes[0].generate(new_height - current_height) + self.sync_all() + assert_equal(new_height, self.nodes[0].getblockcount()) + + def test_received_sprout(self, height): + self.generate_and_sync(height+2) + + zaddr1 = self.nodes[1].z_getnewaddress('sprout') + + # Send 10 ZEC each zaddr1 and zaddrExt via z_shieldcoinbase + result = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), zaddr1, 0, 1) + txid_shielding1 = wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + zaddrExt = self.nodes[2].z_getnewaddress('sprout') + result = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), zaddrExt, 0, 1) + txid_shieldingExt = wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + self.sync_all() + + # Decrypted transaction details should not be visible on node 0 + pt = self.nodes[0].z_viewtransaction(txid_shielding1) + assert_equal(pt['txid'], txid_shielding1) + assert_equal(len(pt['spends']), 0) + assert_equal(len(pt['outputs']), 0) + + # Decrypted transaction details should be correct on node 1 + pt = self.nodes[1].z_viewtransaction(txid_shielding1) + assert_equal(pt['txid'], txid_shielding1) + assert_equal(len(pt['spends']), 0) + assert_equal(len(pt['outputs']), 1) + assert_equal(pt['outputs'][0]['type'], 'sprout') + assert_equal(pt['outputs'][0]['js'], 0) + assert_equal(pt['outputs'][0]['address'], zaddr1) + assert_equal(pt['outputs'][0]['value'], Decimal('10')) + assert_equal(pt['outputs'][0]['valueZat'], 1000000000) + assert_equal(pt['outputs'][0]['memo'], no_memo) + jsOutputPrev = pt['outputs'][0]['jsOutput'] + + # Second transaction should not be known to node 1 + assert_raises_message( + JSONRPCException, + "Invalid or non-wallet transaction id", + self.nodes[1].z_viewtransaction, + txid_shieldingExt) + + # Second transaction should be visible on node0 + pt = self.nodes[2].z_viewtransaction(txid_shieldingExt) + assert_equal(pt['txid'], txid_shieldingExt) + assert_equal(len(pt['spends']), 0) + assert_equal(len(pt['outputs']), 1) + assert_equal(pt['outputs'][0]['type'], 'sprout') + assert_equal(pt['outputs'][0]['js'], 0) + assert_equal(pt['outputs'][0]['address'], zaddrExt) + assert_equal(pt['outputs'][0]['value'], Decimal('10')) + assert_equal(pt['outputs'][0]['valueZat'], 1000000000) + assert_equal(pt['outputs'][0]['memo'], no_memo) + + r = self.nodes[1].z_listreceivedbyaddress(zaddr1) + assert_equal(0, len(r), "Should have received no confirmed note") + c = self.nodes[1].z_getnotescount() + assert_equal(0, c['sprout'], "Count of confirmed notes should be 0") + + # No confirmation required, one note should be present + r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + assert_equal(1, len(r), "Should have received one (unconfirmed) note") + assert_equal(txid_shielding1, r[0]['txid']) + assert_equal(10, r[0]['amount']) + assert_equal(1000000000, r[0]['amountZat']) + assert_false(r[0]['change'], "Note should not be change") + assert_equal(no_memo, r[0]['memo']) + assert_equal(0, r[0]['confirmations']) + assert_equal(-1, r[0]['blockindex']) + assert_equal(0, r[0]['blockheight']) + + c = self.nodes[1].z_getnotescount(0) + assert_equal(1, c['sprout'], "Count of unconfirmed notes should be 1") + + # Confirm transaction (10 ZEC shielded) + self.generate_and_sync(height+3) + + # Require one confirmation, note should be present + r0 = self.nodes[1].z_listreceivedbyaddress(zaddr1) + assert_equal(1, len(r0), "Should have received one (unconfirmed) note") + assert_equal(txid_shielding1, r0[0]['txid']) + assert_equal(10, r0[0]['amount']) + assert_equal(1000000000, r0[0]['amountZat']) + assert_false(r0[0]['change'], "Note should not be change") + assert_equal(no_memo, r0[0]['memo']) + assert_equal(1, r0[0]['confirmations']) + assert_equal(height + 3, r0[0]['blockheight']) + + taddr = self.nodes[1].getnewaddress() + # Generate some change by sending part of zaddr1 back to taddr + opid = self.nodes[1].z_sendmany(zaddr1, [{'address': taddr, 'amount': 0.6}], 1) + txid = wait_and_assert_operationid_status(self.nodes[1], opid) + + self.generate_and_sync(height+4) + + # Decrypted transaction details should be correct + pt = self.nodes[1].z_viewtransaction(txid) + assert_equal(pt['txid'], txid) + assert_equal(len(pt['spends']), 1) + # TODO: enable once z_viewtransaction displays transparent elements + # assert_equal(len(pt['outputs']), 2) + assert_equal(len(pt['outputs']), 1) + + assert_equal(pt['spends'][0]['type'], 'sprout') + assert_equal(pt['spends'][0]['txidPrev'], txid_shielding1) + assert_equal(pt['spends'][0]['js'], 0) + assert_equal(pt['spends'][0]['jsPrev'], 0) + assert_equal(pt['spends'][0]['jsOutputPrev'], jsOutputPrev) + assert_equal(pt['spends'][0]['address'], zaddr1) + assert_equal(pt['spends'][0]['value'], Decimal('10.0')) + assert_equal(pt['spends'][0]['valueZat'], 1000000000) + + # We expect a transparent output and a Sprout output, but the RPC does + # not define any particular ordering of these within the returned JSON. + outputs = [{ + 'type': output['type'], + 'address': output['address'], + 'value': output['value'], + 'valueZat': output['valueZat'], + } for output in pt['outputs']] + for (i, output) in enumerate(pt['outputs']): + if 'memo' in output: + outputs[i]['memo'] = output['memo'] + + # TODO: enable once z_viewtransaction displays transparent elements + # assert({ + # 'type': 'transparent', + # 'address': taddr, + # 'value': Decimal('0.6'), + # 'valueZat': 60000000, + # } in outputs) + assert({ + 'type': 'sprout', + 'address': zaddr1, + 'value': Decimal('9.4') - DEFAULT_FEE, + 'valueZat': 940000000 - DEFAULT_FEE_ZATS, + 'memo': no_memo, + } in outputs) + + # zaddr1 should have a note with change + r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + assert_equal(2, len(r), "zaddr1 Should have received 2 notes") + r = sorted(r, key = lambda received: received['amount']) + assert_equal(txid, r[0]['txid']) + assert_equal(Decimal('9.4')-DEFAULT_FEE, r[0]['amount']) + assert_equal(940000000-DEFAULT_FEE_ZATS, r[0]['amountZat']) + assert_true(r[0]['change'], "Note valued at (9.4-"+str(DEFAULT_FEE)+") should be change") + assert_equal(no_memo, r[0]['memo']) + + # The old note still exists (it's immutable), even though it is spent + assert_equal(Decimal('10.0'), r[1]['amount']) + assert_equal(1000000000, r[1]['amountZat']) + assert_false(r[1]['change'], "Note valued at 10.0 should not be change") + assert_equal(no_memo, r[1]['memo']) + + def test_received_sapling(self, height): + self.generate_and_sync(height+1) + taddr = self.nodes[1].getnewaddress() + zaddr1 = self.nodes[1].z_getnewaddress('sapling') + zaddrExt = self.nodes[2].z_getnewaddress('sapling') + + txid_taddr = self.nodes[0].sendtoaddress(taddr, 4.0) + self.generate_and_sync(height+2) + + # Send 1 ZEC to zaddr1 + opid = self.nodes[1].z_sendmany(taddr, [ + {'address': zaddr1, 'amount': 1, 'memo': my_memo}, + {'address': zaddrExt, 'amount': 2}, + ], 1) + txid = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + + # Decrypted transaction details should be correct + pt = self.nodes[1].z_viewtransaction(txid) + + assert_equal(pt['txid'], txid) + assert_equal(len(pt['spends']), 0) + assert_equal(len(pt['outputs']), 2) + + # Outputs are not returned in a defined order but the amounts are deterministic + outputs = sorted(pt['outputs'], key=lambda x: x['valueZat']) + assert_equal(outputs[0]['type'], 'sapling') + assert_equal(outputs[0]['address'], zaddr1) + assert_equal(outputs[0]['value'], Decimal('1')) + assert_equal(outputs[0]['valueZat'], 100000000) + assert_equal(outputs[0]['output'], 0) + assert_equal(outputs[0]['outgoing'], False) + assert_equal(outputs[0]['memo'], my_memo) + assert_equal(outputs[0]['memoStr'], my_memo_str) + + assert_equal(outputs[1]['type'], 'sapling') + assert_equal(outputs[1]['address'], zaddrExt) + assert_equal(outputs[1]['value'], Decimal('2')) + assert_equal(outputs[1]['valueZat'], 200000000) + assert_equal(outputs[1]['output'], 1) + assert_equal(outputs[1]['outgoing'], True) + assert_equal(outputs[1]['memo'], no_memo) + assert 'memoStr' not in outputs[1] + + r = self.nodes[1].z_listreceivedbyaddress(zaddr1) + assert_equal(0, len(r), "Should have received no confirmed note") + c = self.nodes[1].z_getnotescount() + assert_equal(0, c['sapling'], "Count of confirmed notes should be 0") + + # No confirmation required, one note should be present + r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + assert_equal(1, len(r), "Should have received one (unconfirmed) note") + assert_equal(txid, r[0]['txid']) + assert_equal(1, r[0]['amount']) + assert_equal(100000000, r[0]['amountZat']) + assert_false(r[0]['change'], "Note should not be change") + assert_equal(my_memo, r[0]['memo']) + assert_equal(0, r[0]['confirmations']) + assert_equal(-1, r[0]['blockindex']) + assert_equal(0, r[0]['blockheight']) + + c = self.nodes[1].z_getnotescount(0) + assert_equal(1, c['sapling'], "Count of unconfirmed notes should be 1") + + # Confirm transaction (1 ZEC from taddr to zaddr1) + self.generate_and_sync(height+3) + + # adjust confirmations + r[0]['confirmations'] = 1 + # adjust blockindex + r[0]['blockindex'] = 1 + # adjust height + r[0]['blockheight'] = height + 3 + + # Require one confirmation, note should be present + assert_equal(r, self.nodes[1].z_listreceivedbyaddress(zaddr1)) + + # Generate some change by sending part of zaddr1 to zaddr2 + txidPrev = txid + zaddr2 = self.nodes[1].z_getnewaddress('sapling') + opid = self.nodes[1].z_sendmany(zaddr1, [{'address': zaddr2, 'amount': 0.6}], 1) + txid = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + self.generate_and_sync(height+4) + + # Decrypted transaction details should be correct + pt = self.nodes[1].z_viewtransaction(txid) + assert_equal(pt['txid'], txid) + assert_equal(len(pt['spends']), 1) + assert_equal(len(pt['outputs']), 2) + + assert_equal(pt['spends'][0]['type'], 'sapling') + assert_equal(pt['spends'][0]['txidPrev'], txidPrev) + assert_equal(pt['spends'][0]['spend'], 0) + assert_equal(pt['spends'][0]['outputPrev'], 0) + assert_equal(pt['spends'][0]['address'], zaddr1) + assert_equal(pt['spends'][0]['value'], Decimal('1.0')) + assert_equal(pt['spends'][0]['valueZat'], 100000000) + + # Outputs are not returned in a defined order but the amounts are deterministic + outputs = sorted(pt['outputs'], key=lambda x: x['valueZat']) + assert_equal(outputs[0]['type'], 'sapling') + assert_equal(outputs[0]['address'], zaddr1) + assert_equal(outputs[0]['value'], Decimal('0.4') - DEFAULT_FEE) + assert_equal(outputs[0]['valueZat'], 40000000 - DEFAULT_FEE_ZATS) + assert_equal(outputs[0]['output'], 1) + assert_equal(outputs[0]['outgoing'], False) + assert_equal(outputs[0]['memo'], no_memo) + assert 'memoStr' not in outputs[0] + + assert_equal(outputs[1]['type'], 'sapling') + assert_equal(outputs[1]['address'], zaddr2) + assert_equal(outputs[1]['value'], Decimal('0.6')) + assert_equal(outputs[1]['valueZat'], 60000000) + assert_equal(outputs[1]['output'], 0) + assert_equal(outputs[1]['outgoing'], False) + assert_equal(outputs[1]['memo'], no_memo) + assert 'memoStr' not in outputs[1] + + # zaddr1 should have a note with change + r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + assert_equal(2, len(r), "zaddr1 Should have received 2 notes") + r = sorted(r, key = lambda received: received['amount']) + assert_equal(txid, r[0]['txid']) + assert_equal(Decimal('0.4')-DEFAULT_FEE, r[0]['amount']) + assert_equal(40000000-DEFAULT_FEE_ZATS, r[0]['amountZat']) + assert_equal(r[0]['change'], True, "Note valued at (0.4-"+str(DEFAULT_FEE)+") should be change") + assert_equal(no_memo, r[0]['memo']) + + # The old note still exists (it's immutable), even though it is spent + assert_equal(Decimal('1.0'), r[1]['amount']) + assert_equal(100000000, r[1]['amountZat']) + assert_equal(r[1]['change'], False, "Note valued at 1.0 should not be change") + assert_equal(my_memo, r[1]['memo']) + + # zaddr2 should not have change + r = self.nodes[1].z_listreceivedbyaddress(zaddr2, 0) + assert_equal(len(r), 1, "zaddr2 Should have received 1 notes") + r = sorted(r, key = lambda received: received['amount']) + assert_equal(r[0]['txid'], txid) + assert_equal(r[0]['amount'], Decimal('0.6')) + assert_equal(r[0]['amountZat'], 60000000) + assert_equal(r[0]['change'], False, "Note valued at 0.6 should not be change") + assert_equal(r[0]['memo'], no_memo) + assert 0 <= r[0]['outindex'] < 2 + + c = self.nodes[1].z_getnotescount(0) + assert_equal(c['sapling'], 3, "Count of unconfirmed notes should be 3(2 in zaddr1 + 1 in zaddr2)") + + # As part of UA support, a transparent address is now accepted + r = self.nodes[1].z_listreceivedbyaddress(taddr, 0) + assert_equal(len(r), 1) + assert_equal(r[0]['pool'], 'transparent') + assert_equal(r[0]['txid'], txid_taddr) + assert_equal(r[0]['amount'], Decimal('4')) + assert_equal(r[0]['amountZat'], 400000000) + assert_equal(r[0]['confirmations'], 3) + assert 0 <= r[0]['outindex'] < 2 + + # Test unified address + node = self.nodes[1] + + # Create a unified address on one node, try z_listreceivedbyaddress on another node + account = self.nodes[0].z_getnewaccount()['account'] + r = self.nodes[0].z_getaddressforaccount(account) + unified_addr = r['address'] + # this address isn't in node1's wallet + assert_raises_message( + JSONRPCException, + "From address does not belong to this node", + node.z_listreceivedbyaddress, unified_addr, 0) + + # create a UA on node1 + r = node.z_getnewaccount() + account = r['account'] + r = node.z_getaddressforaccount(account) + unified_addr = r['address'] + receivers = node.z_listunifiedreceivers(unified_addr) + assert_equal(len(receivers), 3) + assert 'p2pkh' in receivers + assert 'sapling' in receivers + assert 'orchard' in receivers + assert_raises_message( + JSONRPCException, + "The provided address is a bare receiver from a Unified Address in this wallet.", + node.z_listreceivedbyaddress, receivers['p2pkh'], 0) + assert_raises_message( + JSONRPCException, + "The provided address is a bare receiver from a Unified Address in this wallet.", + node.z_listreceivedbyaddress, receivers['sapling'], 0) + + # Wallet contains no notes + r = node.z_listreceivedbyaddress(unified_addr, 0) + assert_equal(len(r), 0, "unified_addr should have received zero notes") + + # Create a note in this UA on node1 + opid = node.z_sendmany(zaddr1, [{'address': unified_addr, 'amount': 0.1}], 1) + txid_sapling = wait_and_assert_operationid_status(node, opid) + self.generate_and_sync(height+5) + + # Create a UTXO that unified_address's transparent component references, on node1 + outputs = {receivers['p2pkh']: 0.2} + txid_taddr = node.sendmany("", outputs) + + r = node.z_listreceivedbyaddress(unified_addr, 0) + assert_equal(len(r), 2, "unified_addr should have received 2 payments") + # The return list order isn't defined, so sort by pool name + r = sorted(r, key=lambda x: x['pool']) + assert_equal(r[0]['pool'], 'sapling') + assert_equal(r[0]['txid'], txid_sapling) + assert_equal(r[0]['amount'], Decimal('0.1')) + assert_equal(r[0]['amountZat'], 10000000) + assert_equal(r[0]['memo'], no_memo) + assert 0 <= r[0]['outindex'] < 2 + assert_equal(r[0]['confirmations'], 1) + assert_equal(r[0]['change'], False) + assert_equal(r[0]['blockheight'], height+5) + assert_equal(r[0]['blockindex'], 1) + assert 'blocktime' in r[0] + + assert_equal(r[1]['pool'], 'transparent') + assert_equal(r[1]['txid'], txid_taddr) + assert_equal(r[1]['amount'], Decimal('0.2')) + assert_equal(r[1]['amountZat'], 20000000) + assert 0 <= r[1]['outindex'] < 2 + assert_equal(r[1]['confirmations'], 0) + assert_equal(r[1]['change'], False) + assert 'memo' not in r[1] + assert_equal(r[1]['blockheight'], 0) # not yet mined + assert_equal(r[1]['blockindex'], -1) # not yet mined + assert 'blocktime' in r[1] + + def test_received_orchard(self, height): + self.generate_and_sync(height+1) + taddr = self.nodes[1].getnewaddress() + acct1 = self.nodes[1].z_getnewaccount()['account'] + acct2 = self.nodes[1].z_getnewaccount()['account'] + + addrResO = self.nodes[1].z_getaddressforaccount(acct1, ['orchard']) + assert_equal(addrResO['receiver_types'], ['orchard']) + uao = addrResO['address'] + + addrResSO = self.nodes[1].z_getaddressforaccount(acct2, ['sapling', 'orchard']) + assert_equal(addrResSO['receiver_types'], ['sapling', 'orchard']) + uaso = addrResSO['address'] + + self.nodes[0].sendtoaddress(taddr, 4.0) + self.generate_and_sync(height+2) + + acct_node0 = self.nodes[0].z_getnewaccount()['account'] + ua_node0 = self.nodes[0].z_getaddressforaccount(acct_node0, ['sapling', 'orchard'])['address'] + + opid = self.nodes[1].z_sendmany(taddr, [ + {'address': uao, 'amount': 1, 'memo': my_memo}, + {'address': uaso, 'amount': 2}, + ], 1, 0, 'AllowRevealedSenders') + txid0 = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + + # Decrypted transaction details should be correct, even though + # the transaction is still just in the mempool + pt = self.nodes[1].z_viewtransaction(txid0) + + assert_equal(pt['txid'], txid0) + assert_equal(len(pt['spends']), 0) + assert_equal(len(pt['outputs']), 2) + + # Outputs are not returned in a defined order but the amounts are deterministic + outputs = sorted(pt['outputs'], key=lambda x: x['valueZat']) + assert_equal(outputs[0]['type'], 'orchard') + assert_equal(outputs[0]['address'], uao) + assert_equal(outputs[0]['value'], Decimal('1')) + assert_equal(outputs[0]['valueZat'], 100000000) + assert_equal(outputs[0]['outgoing'], False) + assert_equal(outputs[0]['memo'], my_memo) + assert_equal(outputs[0]['memoStr'], my_memo_str) + actionToSpend = outputs[0]['action'] + + assert_equal(outputs[1]['type'], 'orchard') + assert_equal(outputs[1]['address'], uaso) + assert_equal(outputs[1]['value'], Decimal('2')) + assert_equal(outputs[1]['valueZat'], 200000000) + assert_equal(outputs[1]['outgoing'], False) + assert_equal(outputs[1]['memo'], no_memo) + assert 'memoStr' not in outputs[1] + + self.generate_and_sync(height+3) + + opid = self.nodes[1].z_sendmany(uao, [ + {'address': uaso, 'amount': Decimal('0.3')}, + {'address': ua_node0, 'amount': Decimal('0.2')} + ], 1) + txid1 = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + + pt = self.nodes[1].z_viewtransaction(txid1) + + assert_equal(pt['txid'], txid1) + assert_equal(len(pt['spends']), 1) # one spend we can see + assert_equal(len(pt['outputs']), 3) # one output + one change output we can see + + spends = pt['spends'] + assert_equal(spends[0]['type'], 'orchard') + assert_equal(spends[0]['txidPrev'], txid0) + assert_equal(spends[0]['actionPrev'], actionToSpend) + assert_equal(spends[0]['address'], uao) + assert_equal(spends[0]['value'], Decimal('1.0')) + assert_equal(spends[0]['valueZat'], 100000000) + + outputs = sorted(pt['outputs'], key=lambda x: x['valueZat']) + assert_equal(outputs[0]['type'], 'orchard') + assert_equal(outputs[0]['address'], ua_node0) + assert_equal(outputs[0]['value'], Decimal('0.2')) + assert_equal(outputs[0]['valueZat'], 20000000) + assert_equal(outputs[0]['outgoing'], True) + assert_equal(outputs[0]['walletInternal'], False) + assert_equal(outputs[0]['memo'], no_memo) + + assert_equal(outputs[1]['type'], 'orchard') + assert_equal(outputs[1]['address'], uaso) + assert_equal(outputs[1]['value'], Decimal('0.3')) + assert_equal(outputs[1]['valueZat'], 30000000) + assert_equal(outputs[1]['outgoing'], False) + assert_equal(outputs[1]['walletInternal'], False) + assert_equal(outputs[1]['memo'], no_memo) + + # Verify that we observe the change output + assert_equal(outputs[2]['type'], 'orchard') + assert_equal(outputs[2]['value'], Decimal('0.49999')) + assert_equal(outputs[2]['valueZat'], 49999000) + assert_equal(outputs[2]['outgoing'], False) + assert_equal(outputs[2]['walletInternal'], True) + assert_equal(outputs[2]['memo'], no_memo) + # The change address should have been erased + assert_true('address' not in outputs[2]) + + def run_test(self): + self.test_received_sprout(200) + self.test_received_sapling(214) + self.test_received_orchard(230) + + +if __name__ == '__main__': + ListReceivedTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_nullifiers.py b/depend/zcash/qa/rpc-tests/wallet_nullifiers.py new file mode 100755 index 000000000..e9dc49b1e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_nullifiers.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, bitcoind_processes, \ + connect_nodes_bi, start_node, start_nodes, wait_and_assert_operationid_status, \ + get_coinbase_address, DEFAULT_FEE + +from decimal import Decimal + +class WalletNullifiersTest (BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[['-experimentalfeatures', '-developerencryptwallet']] * self.num_nodes) + + def run_test (self): + # add zaddr to node 0 + myzaddr0 = self.nodes[0].z_getnewaddress() + + # send node 0 taddr to zaddr to get out of coinbase + # Tests using the default cached chain have one address per coinbase output + mytaddr = get_coinbase_address(self.nodes[0]) + recipients = [] + recipients.append({"address": myzaddr0, "amount": Decimal('10.0') - DEFAULT_FEE}) # utxo amount less fee + + wait_and_assert_operationid_status(self.nodes[0], self.nodes[0].z_sendmany(mytaddr, recipients), timeout=120) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # add zaddr to node 2 + myzaddr = self.nodes[2].z_getnewaddress() + + # import node 2 zaddr into node 1 + myzkey = self.nodes[2].z_exportkey(myzaddr) + self.nodes[1].z_importkey(myzkey) + + # encrypt node 1 wallet and wait to terminate + self.nodes[1].encryptwallet("test") + bitcoind_processes[1].wait() + + # restart node 1 + self.nodes[1] = start_node(1, self.options.tmpdir) + connect_nodes_bi(self.nodes, 0, 1) + connect_nodes_bi(self.nodes, 1, 2) + self.sync_all() + + # send node 0 zaddr to note 2 zaddr + recipients = [] + recipients.append({"address":myzaddr, "amount":7.0}) + + wait_and_assert_operationid_status(self.nodes[0], self.nodes[0].z_sendmany(myzaddr0, recipients, 1), timeout=120) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # check zaddr balance + zsendmanynotevalue = Decimal('7.0') + assert_equal(self.nodes[2].z_getbalance(myzaddr), zsendmanynotevalue) + assert_equal(self.nodes[1].z_getbalance(myzaddr), zsendmanynotevalue) + + # add zaddr to node 3 + myzaddr3 = self.nodes[3].z_getnewaddress() + + # send node 2 zaddr to note 3 zaddr + recipients = [] + recipients.append({"address":myzaddr3, "amount":2.0}) + + wait_and_assert_operationid_status(self.nodes[2], self.nodes[2].z_sendmany(myzaddr, recipients, 1), timeout=120) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # check zaddr balance + zsendmany2notevalue = Decimal('2.0') + zsendmanyfee = DEFAULT_FEE + zaddrremaining = zsendmanynotevalue - zsendmany2notevalue - zsendmanyfee + assert_equal(self.nodes[3].z_getbalance(myzaddr3), zsendmany2notevalue) + assert_equal(self.nodes[2].z_getbalance(myzaddr), zaddrremaining) + + # Parallel encrypted wallet can cache nullifiers for Sapling received notes + assert_equal(self.nodes[1].z_getbalance(myzaddr), zaddrremaining) + + # send node 2 zaddr on node 1 to taddr + self.nodes[1].walletpassphrase("test", 600) + mytaddr1 = self.nodes[1].getnewaddress() + recipients = [] + recipients.append({"address":mytaddr1, "amount":1.0}) + + wait_and_assert_operationid_status(self.nodes[1], self.nodes[1].z_sendmany(myzaddr, recipients, 1), timeout=120) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # check zaddr balance + zsendmany3notevalue = Decimal('1.0') + zaddrremaining2 = zaddrremaining - zsendmany3notevalue - zsendmanyfee + assert_equal(self.nodes[1].z_getbalance(myzaddr), zaddrremaining2) + assert_equal(self.nodes[2].z_getbalance(myzaddr), zaddrremaining2) + + # Test viewing keys + + node3mined = Decimal('250.0') + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance().items()}, { + 'transparent': node3mined, + 'private': zsendmany2notevalue, + 'total': node3mined + zsendmany2notevalue, + }) + + # Add node 1 address and node 2 viewing key to node 3 + myzvkey = self.nodes[2].z_exportviewingkey(myzaddr) + self.nodes[3].importaddress(mytaddr1) + importvk_result = self.nodes[3].z_importviewingkey(myzvkey, 'whenkeyisnew', 1) + + # Check results of z_importviewingkey + assert_equal(importvk_result["type"], "sapling") + assert_equal(importvk_result["address"], myzaddr) + + # Check the address has been imported + assert_equal(myzaddr in self.nodes[3].z_listaddresses(), False) + assert_equal(myzaddr in self.nodes[3].z_listaddresses(True), True) + + # Node 3 should see the same received notes as node 2; however, there are 2 things: + # - Some of the notes were change for node 2 but not for node 3. + # - Each node wallet store transaction time as received. As + # `wait_and_assert_operationid_status` is called node 2 and 3 are off by a few seconds. + # Aside from that the received notes should be the same. So, + # group by txid and then check that all properties aside from + # change are equal. + node2Received = dict([r['txid'], r] for r in self.nodes[2].z_listreceivedbyaddress(myzaddr)) + node3Received = dict([r['txid'], r] for r in self.nodes[3].z_listreceivedbyaddress(myzaddr)) + assert_equal(len(node2Received), len(node2Received)) + for txid in node2Received: + received2 = node2Received[txid] + received3 = node3Received[txid] + # the change field will be omitted for received3, but all other fields should be shared + assert_true(len(received2) >= len(received3)) + for key in received2: + # check all the properties except for change and blocktime + if key != 'change' and key != 'blocktime': + assert_equal(received2[key], received3[key]) + + # Node 3's balances should be unchanged without explicitly requesting + # to include watch-only balances + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance().items()}, { + 'transparent': node3mined, + 'private': zsendmany2notevalue, + 'total': node3mined + zsendmany2notevalue, + }) + + # Wallet can cache nullifiers for Sapling notes received by addresses it only has a + # viewing key for. + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance(1, True).items()}, { + 'transparent': node3mined + Decimal('1.0'), + 'private': zsendmany2notevalue + zaddrremaining2, + 'total': node3mined + Decimal('1.0') + zsendmany2notevalue + zaddrremaining2, + }) + + # Check individual balances reflect the above + assert_equal(self.nodes[3].z_getbalance(mytaddr1), Decimal('1.0')) + assert_equal(self.nodes[3].z_getbalance(myzaddr), zaddrremaining2) + +if __name__ == '__main__': + WalletNullifiersTest().main () diff --git a/depend/zcash/qa/rpc-tests/wallet_orchard.py b/depend/zcash/qa/rpc-tests/wallet_orchard.py new file mode 100755 index 000000000..218c5e57b --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_orchard.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet behaviour with the Orchard protocol +class WalletOrchardTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 210), + ]] * self.num_nodes) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Get a new orchard-only unified address + acct1 = self.nodes[1].z_getnewaccount()['account'] + addrRes1 = self.nodes[1].z_getaddressforaccount(acct1, ['orchard']) + assert_equal(acct1, addrRes1['account']) + assert_equal(addrRes1['receiver_types'], ['orchard']) + ua1 = addrRes1['address'] + + # Verify that we have only an Orchard component + receiver_types = self.nodes[0].z_listunifiedreceivers(ua1) + assert_equal(set(['orchard']), set(receiver_types)) + + # Verify balance + assert_equal({'pools': {}, 'minimum_confirmations': 1}, self.nodes[1].z_getbalanceforaccount(acct1)) + + # Send some sapling funds to node 2 for later spending after we split the network + acct2 = self.nodes[2].z_getnewaccount()['account'] + addrRes2 = self.nodes[2].z_getaddressforaccount(acct2, ['sapling', 'orchard']) + assert_equal(acct2, addrRes2['account']) + ua2 = addrRes2['address'] + saplingAddr2 = self.nodes[2].z_listunifiedreceivers(ua2)['sapling'] + + recipients = [{"address": saplingAddr2, "amount": Decimal('10')}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Mine the tx & activate NU5 + self.sync_all() + self.nodes[0].generate(10) + self.sync_all() + + # Check the value sent to saplingAddr2 was received in node 2's account + assert_equal( + {'pools': {'sapling': {'valueZat': Decimal('1000000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + # Node 0 shields some funds + # t-coinbase -> Orchard + recipients = [{"address": ua1, "amount": Decimal('10')}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('1000000000')}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Split the network + self.split_network() + + # Send another tx to ua1 + recipients = [{"address": ua1, "amount": Decimal('10')}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Mine the tx & generate a majority chain on the 0/1 side of the split + self.sync_all() + self.nodes[0].generate(10) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('2000000000')}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # On the other side of the split, send some funds to node 3 + acct3 = self.nodes[3].z_getnewaccount()['account'] + addrRes3 = self.nodes[3].z_getaddressforaccount(acct3, ['sapling', 'orchard']) + assert_equal(acct3, addrRes3['account']) + ua3 = addrRes3['address'] + + recipients = [{"address": ua3, "amount": Decimal('1')}] + myopid = self.nodes[2].z_sendmany(ua2, recipients, 1, 0, 'AllowRevealedAmounts') + rollback_tx = wait_and_assert_operationid_status(self.nodes[2], myopid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # The remaining change from ua2's Sapling note has been sent to the + # account's internal Orchard change address. + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('900000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('100000000')}}, 'minimum_confirmations': 1}, + self.nodes[3].z_getbalanceforaccount(acct3)) + + # Check that the mempools are empty + for i in range(self.num_nodes): + assert_equal(set([]), set(self.nodes[i].getrawmempool())) + + # Reconnect the nodes; nodes 2 and 3 will re-org to node 0's chain. + print("Re-joining the network so that nodes 2 and 3 reorg") + self.join_network() + + # split 0/1's chain should have won, so their wallet balance should be consistent + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('2000000000')}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # split 2/3's chain should have been rolled back, so their txn should have been + # un-mined and returned to the mempool + assert_equal(set([rollback_tx]), set(self.nodes[2].getrawmempool())) + + # acct2's sole Orchard note is spent by a transaction in the mempool, so our + # confirmed balance is currently 0 + assert_equal( + {'pools': {}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + # acct2's incoming change (unconfirmed, still in the mempool) is 9 zec + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('900000000')}}, 'minimum_confirmations': 0}, + self.nodes[2].z_getbalanceforaccount(acct2, 0)) + + # The transaction was un-mined, so acct3 should have no confirmed balance + assert_equal( + {'pools': {}, 'minimum_confirmations': 1}, + self.nodes[3].z_getbalanceforaccount(acct3)) + + # acct3's unconfirmed balance is 1 zec + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('100000000')}}, 'minimum_confirmations': 0}, + self.nodes[3].z_getbalanceforaccount(acct3, 0)) + + # Manually resend the transaction in node 2's mempool + self.nodes[2].resendwallettransactions() + + # Sync the network + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # The un-mined transaction should now have been re-mined + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('900000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('100000000')}}, 'minimum_confirmations': 1}, + self.nodes[3].z_getbalanceforaccount(acct3)) + + # Split the network again + self.split_network() + + # Spend some of acct3's funds on the 2/3 side of the split + recipients = [{"address": ua2, "amount": Decimal('0.5')}] + myopid = self.nodes[3].z_sendmany(ua3, recipients, 1, 0) + rollback_tx = wait_and_assert_operationid_status(self.nodes[3], myopid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('950000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + # Generate a majority chain on the 0/1 side of the split, then + # re-join the network. + self.nodes[1].generate(10) + self.join_network() + + # split 2/3's chain should have been rolled back, so their txn should have been + # un-mined and returned to the mempool + assert_equal(set([rollback_tx]), set(self.nodes[3].getrawmempool())) + + # acct2's balance is back to not contain the Orchard->Orchard value + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('900000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + + # acct3's sole Orchard note is spent by a transaction in the mempool, so our + # confirmed balance is currently 0 + assert_equal( + {'pools': {}, 'minimum_confirmations': 1}, + self.nodes[3].z_getbalanceforaccount(acct3)) + + # Manually resend the transaction in node 3's mempool + self.nodes[2].resendwallettransactions() + + # Sync the network + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # The un-mined transaction should now have been re-mined + assert_equal( + {'pools': {'orchard': {'valueZat': Decimal('950000000')}}, 'minimum_confirmations': 1}, + self.nodes[2].z_getbalanceforaccount(acct2)) + +if __name__ == '__main__': + WalletOrchardTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_orchard_change.py b/depend/zcash/qa/rpc-tests/wallet_orchard_change.py new file mode 100755 index 000000000..bded74614 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_orchard_change.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + stop_nodes, + wait_and_assert_operationid_status, + wait_bitcoinds, +) + +# Test wallet behaviour with the Orchard protocol +class WalletOrchardChangeTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 205), + '-regtestwalletsetbestchaineveryblock', + ]] * self.num_nodes) + + def check_has_output(self, node, tx, expected): + tx_outputs = self.nodes[0].z_viewtransaction(tx)['outputs'] + tx_outputs = [{x: y for (x, y) in output.items() if x in expected} for output in tx_outputs] + found = False + for output in tx_outputs: + if output == expected: + found = True + break + assert found, 'Node %s is missing output %s in tx %s (actual: %s)' % (node, expected, tx, tx_outputs) + + def run_test(self): + # Sanity-check the test harness. + assert_equal(self.nodes[0].getblockcount(), 200) + + # Create an account with funds in the Sapling receiver. + acct0 = self.nodes[0].z_getnewaccount()['account'] + ua0 = self.nodes[0].z_getaddressforaccount(acct0, ['sapling', 'orchard'])['address'] + + recipients = [{"address": ua0, "amount": 10}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Mine the tx & activate NU5. + self.sync_all() + self.nodes[0].generate(5) + self.sync_all() + + assert_equal( + {'pools': {'sapling': {'valueZat': 10_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0), + ) + + # We want to generate an Orchard change note on node 0. We do this by + # sending funds to an Orchard-only UA on node 1. + acct1 = self.nodes[1].z_getnewaccount()['account'] + ua1 = self.nodes[1].z_getaddressforaccount(acct1, ['orchard'])['address'] + + recipients = [{"address": ua1, "amount": 1}] + myopid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0, 'AllowRevealedAmounts') + source_tx = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # The nodes have the expected split of funds. + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0), + ) + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1), + ) + + # The Orchard note for node 0 is a change note. + self.check_has_output(0, source_tx, { + 'pool': 'orchard', + 'outgoing': False, + 'walletInternal': True, + 'value': 9, + 'valueZat': 9_0000_0000, + }) + + # Shut down the nodes, and restart so that we can check wallet load + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # The nodes have unaltered balances. + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0), + ) + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1), + ) + + # Send another Orchard transaction from node 0 to node 1. + myopid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 8_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0), + ) + +if __name__ == '__main__': + WalletOrchardChangeTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_orchard_init.py b/depend/zcash/qa/rpc-tests/wallet_orchard_init.py new file mode 100755 index 000000000..b5db9f4e1 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_orchard_init.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import os +import os.path + +from decimal import Decimal + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + stop_nodes, + wait_bitcoinds, + wait_and_assert_operationid_status, +) + +# Test wallet behaviour with the Orchard protocol +class OrchardWalletInitTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 205), + '-regtestwalletsetbestchaineveryblock' + ]] * self.num_nodes) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Get a new Orchard account on node 0 + acct0 = self.nodes[0].z_getnewaccount()['account'] + ua0 = self.nodes[0].z_getaddressforaccount(acct0, ['orchard'])['address'] + + # Activate NU5 + self.nodes[0].generate(5) + self.sync_all() + + # Get a recipient address + acct1 = self.nodes[1].z_getnewaccount()['account'] + ua1 = self.nodes[1].z_getaddressforaccount(acct1, ['orchard'])['address'] + + # Send a transaction to node 1 so that it has an Orchard note to spend. + recipients = [{"address": ua1, "amount": 10}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Check the value sent to ua1 was received + assert_equal( + {'pools': {'orchard': {'valueZat': 10_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Create an Orchard spend, so that the note commitment tree root gets altered. + recipients = [{"address": ua0, "amount": 1}] + myopid = self.nodes[1].z_sendmany(ua1, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify the balance on both nodes + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0)) + + # Split the network. We'll advance the state of nodes 0/1 so that after + # we re-join the network, we need to roll back more than one block after + # the wallet is restored, into a chain state that the wallet never observed. + self.split_network() + + self.sync_all() + self.nodes[0].generate(2) + self.sync_all() + + # Shut down the network and delete node 0's wallet + stop_nodes(self.nodes) + wait_bitcoinds() + + tmpdir = self.options.tmpdir + os.remove(os.path.join(tmpdir, "node0", "regtest", "wallet.dat")) + + # Restart the network, still split; the split here is note necessary to reproduce + # the error but it is sufficient, and we will later use the split to check the + # corresponding rewind. + self.setup_network(True) + + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Get a new account with an Orchard UA on node 0 + acct0new = self.nodes[0].z_getnewaccount()['account'] + ua0new = self.nodes[0].z_getaddressforaccount(acct0, ['orchard'])['address'] + + # Send a transaction to the Orchard account. When we mine this transaction, + # the bug causes the state of note commitment tree in the wallet to not match + # the state of the global note commitment tree. + recipients = [{"address": ua0new, "amount": 1}] + myopid = self.nodes[1].z_sendmany(ua1, recipients, 1, 0) + rollback_tx = wait_and_assert_operationid_status(self.nodes[1], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0new)) + + # Node 2 has no progress since the network was first split, so this should roll + # everything back to the original fork point. + self.nodes[2].generate(10) + + # Re-join the network + self.join_network() + + assert_equal(set([rollback_tx]), set(self.nodes[1].getrawmempool())) + + # Resend un-mined transactions and sync the network + self.nodes[1].resendwallettransactions() + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0new)) + + # Spend from the note that was just received + recipients = [{"address": ua1, "amount": Decimal('0.3')}] + myopid = self.nodes[0].z_sendmany(ua0new, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 8_3000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + +if __name__ == '__main__': + OrchardWalletInitTest().main() + diff --git a/depend/zcash/qa/rpc-tests/wallet_orchard_persistence.py b/depend/zcash/qa/rpc-tests/wallet_orchard_persistence.py new file mode 100755 index 000000000..f27a94442 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_orchard_persistence.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + stop_nodes, + wait_bitcoinds, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet behaviour with the Orchard protocol +class WalletOrchardPersistenceTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 201), + ]] * self.num_nodes) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # activate NU5 + self.nodes[0].generate(1) + self.sync_all() + + # Send some Orchard funds to node 2 for later spending after we split the network + acct0 = self.nodes[0].z_getnewaccount()['account'] + ua0 = self.nodes[0].z_getaddressforaccount(acct0, ['sapling', 'orchard'])['address'] + + recipients = [{"address": ua0, "amount": 10}] + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Mine the tx + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 10_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0)) + + # Send to a new orchard-only unified address + acct1 = self.nodes[1].z_getnewaccount()['account'] + ua1 = self.nodes[1].z_getaddressforaccount(acct1, ['orchard'])['address'] + + recipients = [{"address": ua1, "amount": 1}] + myopid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0)) + assert_equal( + {'pools': {'orchard': {'valueZat': 1_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(acct1)) + + # Send another Orchard transaction from node 0 back to itself, so that the + # note commitment tree gets advanced. + recipients = [{"address": ua0, "amount": 1}] + myopid = self.nodes[0].z_sendmany(ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Shut down the nodes, and restart so that we can check wallet load + stop_nodes(self.nodes); + wait_bitcoinds() + self.setup_network() + + assert_equal( + {'pools': {'orchard': {'valueZat': 9_0000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0)) + + recipients = [{"address": ua0, "amount": Decimal('0.5')}] + myopid = self.nodes[1].z_sendmany(ua1, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'orchard': {'valueZat': 9_5000_0000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(acct0)) + +if __name__ == '__main__': + WalletOrchardPersistenceTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_overwintertx.py b/depend/zcash/qa/rpc-tests/wallet_overwintertx.py new file mode 100755 index 000000000..5ccdd57b4 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_overwintertx.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + assert_greater_than, + connect_nodes_bi, + get_coinbase_address, + start_nodes, + wait_and_assert_operationid_status, + DEFAULT_FEE +) +from test_framework.authproxy import JSONRPCException + +from decimal import Decimal + +class WalletOverwinterTxTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + self.setup_clean_chain = True + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[ + "-nuparams=2bb40e60:200", + "-debug=zrpcunsafe", + "-txindex", + ]] * self.num_nodes) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + def run_test (self): + self.nodes[0].generate(100) + self.sync_all() + self.nodes[1].generate(95) + self.sync_all() + # Node 0 has reward from blocks 1 to 95 which are spendable. + + taddr0 = get_coinbase_address(self.nodes[0]) + taddr1 = self.nodes[1].getnewaddress() + taddr2 = self.nodes[2].getnewaddress() + zaddr2 = self.nodes[2].z_getnewaddress('sprout') + taddr3 = self.nodes[3].getnewaddress() + zaddr3 = self.nodes[3].z_getnewaddress('sprout') + + # + # Currently at block 195. The next block to be mined 196 is a Sapling block + # + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '76b809bb') + assert_equal(bci['consensus']['nextblock'], '76b809bb') + assert_equal(bci['upgrades']['2bb40e60']['status'], 'pending') + + # Node 0 sends transparent funds to Node 2 + tsendamount = Decimal('1.0') + txid_transparent = self.nodes[0].sendtoaddress(taddr2, tsendamount) + self.sync_all() + + # Node 2 sends the zero-confirmation transparent funds to Node 1 using z_sendmany + recipients = [] + recipients.append({"address":taddr1, "amount": Decimal('0.5')}) + myopid = self.nodes[2].z_sendmany(taddr2, recipients, 0) + txid_zsendmany = wait_and_assert_operationid_status(self.nodes[2], myopid) + + # Node 0 shields to Node 2, a coinbase utxo of value 10.0 less default fee + zsendamount = Decimal('10.0') - DEFAULT_FEE + result = self.nodes[0].z_shieldcoinbase(taddr0, zaddr2, DEFAULT_FEE, 1) + txid_shielded = wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + # Skip over the three blocks prior to activation; no transactions can be mined + # in them due to the nearly-expiring restrictions. + self.sync_all() + self.nodes[0].generate(4) + self.sync_all() + + # Verify balance + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('0.5')) + assert_equal(self.nodes[2].getbalance(), Decimal('0.5') - DEFAULT_FEE) + assert_equal(self.nodes[2].z_getbalance(zaddr2), zsendamount) + + # Verify transaction version is 4 (intended for Sapling+) + result = self.nodes[0].getrawtransaction(txid_transparent, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + result = self.nodes[0].getrawtransaction(txid_zsendmany, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + result = self.nodes[0].getrawtransaction(txid_shielded, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + + # + # Currently at block 199. The next block to be mined 200 is a Blossom block + # + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '76b809bb') + assert_equal(bci['consensus']['nextblock'], '2bb40e60') + assert_equal(bci['upgrades']['2bb40e60']['status'], 'pending') + + # Test using expiryheight parameter of createrawtransaction when Blossom is active in the next block + errorString = "" + try: + self.nodes[0].createrawtransaction([], {}, 0, 499999999) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("", errorString) + try: + self.nodes[0].createrawtransaction([], {}, 0, -1) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True) + try: + self.nodes[0].createrawtransaction([], {}, 0, 500000000) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True) + try: + self.nodes[0].createrawtransaction([], {}, 0, 200) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Invalid parameter, expiryheight should be at least 203 to avoid transaction expiring soon" in errorString, True) + + # Node 0 sends transparent funds to Node 3 + tsendamount = Decimal('1.0') + txid_transparent = self.nodes[0].sendtoaddress(taddr3, tsendamount) + self.sync_all() + + # Node 3 sends the zero-confirmation transparent funds to Node 1 using z_sendmany + recipients = [] + recipients.append({"address":taddr1, "amount": Decimal('0.5')}) + myopid = self.nodes[3].z_sendmany(taddr3, recipients, 0) + txid_zsendmany = wait_and_assert_operationid_status(self.nodes[3], myopid) + + # Node 0 shields to Node 3, a coinbase utxo of value 10.0 less default fee + zsendamount = Decimal('10.0') - DEFAULT_FEE + result = self.nodes[0].z_shieldcoinbase(taddr0, zaddr3, DEFAULT_FEE, 1) + txid_shielded = wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + # Mine the first Blossom block + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + bci = self.nodes[0].getblockchaininfo() + + # size_on_disk should be > 0 + assert_greater_than(bci['size_on_disk'], 0) + + assert_equal(bci['consensus']['chaintip'], '2bb40e60') + assert_equal(bci['consensus']['nextblock'], '2bb40e60') + assert_equal(bci['upgrades']['2bb40e60']['status'], 'active') + + # Verify balance + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('1.0')) + assert_equal(self.nodes[3].getbalance(), Decimal('0.5') - DEFAULT_FEE) + assert_equal(self.nodes[3].z_getbalance(zaddr3), zsendamount) + + # Verify transaction version is 4 (intended for Sapling+) + result = self.nodes[0].getrawtransaction(txid_transparent, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "892f2085") + result = self.nodes[0].getrawtransaction(txid_zsendmany, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "892f2085") + result = self.nodes[0].getrawtransaction(txid_shielded, 1) + assert_equal(result["version"], 4) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "892f2085") + +if __name__ == '__main__': + WalletOverwinterTxTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_parsing_amounts.py b/depend/zcash/qa/rpc-tests/wallet_parsing_amounts.py new file mode 100755 index 000000000..fd1718f9b --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_parsing_amounts.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes_bi, start_nodes +from test_framework.authproxy import JSONRPCException +from decimal import Decimal + +# Test wallet address behaviour across network upgrades +class WalletAmountParsingTest(BitcoinTestFramework): + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir) + 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): + #send a tx with value in a string (PR#6380 +) + txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2") + txObj = self.nodes[0].gettransaction(txId) + assert_equal(txObj['amount'], Decimal('-2.00000000')) + assert_equal(txObj['amountZat'], -200000000) + + txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001") + txObj = self.nodes[0].gettransaction(txId) + assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amountZat'], -10000) + + #check if JSON parser can handle scientific notation in strings + txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4") + txObj = self.nodes[0].gettransaction(txId) + assert_equal(txObj['amount'], Decimal('-0.00010000')) + assert_equal(txObj['amountZat'], -10000) + + #this should fail + errorString = "" + try: + txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") + except JSONRPCException as e: + errorString = e.error['message'] + + assert_equal("Invalid amount" in errorString, True) + + errorString = "" + try: + self.nodes[0].generate("2") #use a string to as block amount parameter must fail because it's not interpreted as amount + except JSONRPCException as e: + errorString = e.error['message'] + + assert_equal("not an integer" in errorString, True) + + myzaddr = self.nodes[0].z_getnewaddress() + recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ] + errorString = '' + + # Make sure that amount=0 transactions can use the default fee + # without triggering "absurd fee" errors + try: + myopid = self.nodes[0].z_sendmany(myzaddr, recipients) + assert(myopid) + except JSONRPCException as e: + errorString = e.error['message'] + print(errorString) + assert(False) + + # This fee is larger than the default fee and since amount=0 + # it should trigger error + fee = Decimal('0.1') + recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ] + minconf = 1 + errorString = '' + + try: + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee) + except JSONRPCException as e: + errorString = e.error['message'] + assert('Small transaction amount' in errorString) + + # This fee is less than default and greater than amount, but still valid + fee = Decimal('0.0000001') + recipients = [ {"address": myzaddr, "amount": Decimal('0.00000001') } ] + minconf = 1 + errorString = '' + + try: + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee) + assert(myopid) + except JSONRPCException as e: + errorString = e.error['message'] + print(errorString) + assert(False) + + # Make sure amount=0, fee=0 transaction are valid to add to mempool + # though miners decide whether to add to a block + fee = Decimal('0.0') + minconf = 1 + recipients = [ {"address": myzaddr, "amount": Decimal('0.0') } ] + errorString = '' + + try: + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, fee) + assert(myopid) + except JSONRPCException as e: + errorString = e.error['message'] + print(errorString) + assert(False) + +if __name__ == '__main__': + WalletAmountParsingTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_persistence.py b/depend/zcash/qa/rpc-tests/wallet_persistence.py new file mode 100755 index 000000000..7c8c34838 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_persistence.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, assert_true, + get_coinbase_address, + start_nodes, stop_nodes, + initialize_chain_clean, connect_nodes_bi, wait_bitcoinds, + wait_and_assert_operationid_status +) +from decimal import Decimal + +class WalletPersistenceTest (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): + self.nodes = start_nodes(4, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,2,3) + self.is_network_split=False + self.sync_all() + + def run_test(self): + # Sanity-check the test harness + self.nodes[0].generate(200) + assert_equal(self.nodes[0].getblockcount(), 200) + self.sync_all() + + # Verify Sapling address is persisted in wallet + sapling_addr = self.nodes[0].z_getnewaddress('sapling') + + # Make sure the node has the address + addresses = self.nodes[0].z_listaddresses() + assert_true(sapling_addr in addresses, "Should contain address before restart") + + # Restart the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Make sure we still have the address after restarting + addresses = self.nodes[0].z_listaddresses() + assert_true(sapling_addr in addresses, "Should contain address after restart") + + # Node 0 shields funds to Sapling address + taddr0 = get_coinbase_address(self.nodes[0]) + recipients = [] + recipients.append({"address": sapling_addr, "amount": Decimal('20')}) + myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify shielded balance + assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('20')) + + # Verify size of shielded pools + pools = self.nodes[0].getblockchaininfo()['valuePools'] + assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout + assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling + + # Restart the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Verify size of shielded pools + pools = self.nodes[0].getblockchaininfo()['valuePools'] + assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout + assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling + + # Node 0 sends some shielded funds to Node 1 + dest_addr = self.nodes[1].z_getnewaddress('sapling') + recipients = [] + recipients.append({"address": dest_addr, "amount": Decimal('15')}) + myopid = self.nodes[0].z_sendmany(sapling_addr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify balances + assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5')) + assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15')) + + # Restart the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Verify balances + assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5')) + assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15')) + + # Verify importing a spending key will update and persist the nullifiers and witnesses correctly + sk0 = self.nodes[0].z_exportkey(sapling_addr) + self.nodes[2].z_importkey(sk0, "yes") + assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5')) + + # Verify importing a viewing key will update and persist the nullifiers and witnesses correctly + extfvk0 = self.nodes[0].z_exportviewingkey(sapling_addr) + self.nodes[3].z_importviewingkey(extfvk0, "yes") + assert_equal(self.nodes[3].z_getbalance(sapling_addr), Decimal('5')) + assert_equal(self.nodes[3].z_gettotalbalance()['private'], '0.00') + assert_equal(self.nodes[3].z_gettotalbalance(1, True)['private'], '5.00') + + # Restart the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # Verify nullifiers persisted correctly by checking balance + # Prior to PR #3590, there will be an error as spent notes are considered unspent: + # Assertion failed: expected: <25.00000000> but was: <5> + assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5')) + assert_equal(self.nodes[3].z_getbalance(sapling_addr), Decimal('5')) + assert_equal(self.nodes[3].z_gettotalbalance()['private'], '0.00') + assert_equal(self.nodes[3].z_gettotalbalance(1, True)['private'], '5.00') + + # Verity witnesses persisted correctly by sending shielded funds + recipients = [] + recipients.append({"address": dest_addr, "amount": Decimal('1')}) + myopid = self.nodes[2].z_sendmany(sapling_addr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[2], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify balances + assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('4')) + assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('16')) + +if __name__ == '__main__': + WalletPersistenceTest().main() \ No newline at end of file diff --git a/depend/zcash/qa/rpc-tests/wallet_sapling.py b/depend/zcash/qa/rpc-tests/wallet_sapling.py new file mode 100755 index 000000000..28c86cae0 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_sapling.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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, + get_coinbase_address, + wait_and_assert_operationid_status, + DEFAULT_FEE +) + +from decimal import Decimal + +# Test wallet behaviour with Sapling addresses +class WalletSaplingTest(BitcoinTestFramework): + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + taddr1 = self.nodes[1].getnewaddress() + saplingAddr0 = self.nodes[0].z_getnewaddress('sapling') + saplingAddr1 = self.nodes[1].z_getnewaddress('sapling') + + # Verify addresses + assert(saplingAddr0 in self.nodes[0].z_listaddresses()) + assert(saplingAddr1 in self.nodes[1].z_listaddresses()) + assert_equal(self.nodes[0].z_validateaddress(saplingAddr0)['type'], 'sapling') + assert_equal(self.nodes[0].z_validateaddress(saplingAddr1)['type'], 'sapling') + + # Verify balance + assert_equal(self.nodes[0].z_getbalance(saplingAddr0), Decimal('0')) + assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('0')) + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('0')) + + # Node 0 shields some funds + # taddr -> Sapling + recipients = [] + recipients.append({"address": saplingAddr0, "amount": Decimal('10')}) + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + + # Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000) + mempool = self.nodes[0].getrawmempool(True) + assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16')) + + # Shield another coinbase UTXO + myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # Verify balance + assert_equal(self.nodes[0].z_getbalance(saplingAddr0), Decimal('20')) + assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('0')) + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('0')) + + # Node 0 sends some shielded funds to node 1 + # Sapling -> Sapling + # -> Sapling (change) + recipients = [] + recipients.append({"address": saplingAddr1, "amount": Decimal('15')}) + myopid = self.nodes[0].z_sendmany(saplingAddr0, recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + + # Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000) + mempool = self.nodes[0].getrawmempool(True) + assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16')) + + self.nodes[2].generate(1) + self.sync_all() + + # Verify balance + assert_equal(self.nodes[0].z_getbalance(saplingAddr0), Decimal('5')) + assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('15')) + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('0')) + + # Node 1 sends some shielded funds to node 0, as well as unshielding + # Sapling -> Sapling + # -> taddr + # -> Sapling (change) + recipients = [] + recipients.append({"address": saplingAddr0, "amount": Decimal('5')}) + recipients.append({"address": taddr1, "amount": Decimal('5')}) + myopid = self.nodes[1].z_sendmany(saplingAddr1, recipients, 1, 0) + mytxid = wait_and_assert_operationid_status(self.nodes[1], myopid) + + self.sync_all() + + # Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000) + mempool = self.nodes[1].getrawmempool(True) + assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16')) + + self.nodes[2].generate(1) + self.sync_all() + + # Verify balance + assert_equal(self.nodes[0].z_getbalance(saplingAddr0), Decimal('10')) + assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal('5')) + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('5')) + + # Verify existence of Sapling related JSON fields + resp = self.nodes[0].getrawtransaction(mytxid, 1) + assert_equal(resp['valueBalance'], Decimal('5')) + assert(len(resp['vShieldedSpend']) == 1) + assert(len(resp['vShieldedOutput']) == 2) + assert('bindingSig' in resp) + shieldedSpend = resp['vShieldedSpend'][0] + assert('cv' in shieldedSpend) + assert('anchor' in shieldedSpend) + assert('nullifier' in shieldedSpend) + assert('rk' in shieldedSpend) + assert('proof' in shieldedSpend) + assert('spendAuthSig' in shieldedSpend) + shieldedOutput = resp['vShieldedOutput'][0] + assert('cv' in shieldedOutput) + assert('cmu' in shieldedOutput) + assert('ephemeralKey' in shieldedOutput) + assert('encCiphertext' in shieldedOutput) + assert('outCiphertext' in shieldedOutput) + assert('proof' in shieldedOutput) + + # Verify importing a spending key will update the nullifiers and witnesses correctly + sk0 = self.nodes[0].z_exportkey(saplingAddr0) + saplingAddrInfo0 = self.nodes[2].z_importkey(sk0, "yes") + assert_equal(saplingAddrInfo0["type"], "sapling") + assert_equal(saplingAddrInfo0["address"], saplingAddr0) + assert_equal(self.nodes[2].z_getbalance(saplingAddrInfo0["address"]), Decimal('10')) + sk1 = self.nodes[1].z_exportkey(saplingAddr1) + saplingAddrInfo1 = self.nodes[2].z_importkey(sk1, "yes") + assert_equal(saplingAddrInfo1["type"], "sapling") + assert_equal(saplingAddrInfo1["address"], saplingAddr1) + assert_equal(self.nodes[2].z_getbalance(saplingAddrInfo1["address"]), Decimal('5')) + + # Verify importing a viewing key will update the nullifiers and witnesses correctly + extfvk0 = self.nodes[0].z_exportviewingkey(saplingAddr0) + saplingAddrInfo0 = self.nodes[3].z_importviewingkey(extfvk0, "yes") + assert_equal(saplingAddrInfo0["type"], "sapling") + assert_equal(saplingAddrInfo0["address"], saplingAddr0) + assert_equal(self.nodes[3].z_getbalance(saplingAddrInfo0["address"]), Decimal('10')) + extfvk1 = self.nodes[1].z_exportviewingkey(saplingAddr1) + saplingAddrInfo1 = self.nodes[3].z_importviewingkey(extfvk1, "yes") + assert_equal(saplingAddrInfo1["type"], "sapling") + assert_equal(saplingAddrInfo1["address"], saplingAddr1) + assert_equal(self.nodes[3].z_getbalance(saplingAddrInfo1["address"]), Decimal('5')) + + # Verify that z_gettotalbalance only includes watch-only addresses when requested + assert_equal(self.nodes[3].z_gettotalbalance()['private'], '0.00') + assert_equal(self.nodes[3].z_gettotalbalance(1, True)['private'], '15.00') + + # Make sure we get a useful error when trying to send to both sprout and sapling + node4_sproutaddr = self.nodes[3].z_getnewaddress('sprout') + node4_saplingaddr = self.nodes[3].z_getnewaddress('sapling') + try: + self.nodes[1].z_sendmany( + taddr1, + [{'address': node4_sproutaddr, 'amount': Decimal('2.5')}, + {'address': node4_saplingaddr, 'amount': Decimal('2.5') - DEFAULT_FEE}], + 1, DEFAULT_FEE + ) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Sending funds into the Sprout value pool is not supported by z_sendmany", e.error['message']) + +if __name__ == '__main__': + WalletSaplingTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_sendmany_any_taddr.py b/depend/zcash/qa/rpc-tests/wallet_sendmany_any_taddr.py new file mode 100755 index 000000000..79846ccb8 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_sendmany_any_taddr.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes_bi, + start_nodes, + sync_blocks, + wait_and_assert_operationid_status, +) + +TX_EXPIRY_DELTA = 10 +TX_EXPIRING_SOON_THRESHOLD = 3 + +# Test ANY_TADDR special string in z_sendmany +class WalletSendManyAnyTaddr(BitcoinTestFramework): + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, + [[ + "-txexpirydelta=%d" % TX_EXPIRY_DELTA, + ]] * self.num_nodes) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Create the addresses we will be using. + recipient = self.nodes[1].z_getnewaddress() + node2zaddr = self.nodes[2].z_getnewaddress() + node2taddr1 = self.nodes[2].getnewaddress() + node3zaddr = self.nodes[3].z_getnewaddress() + node3taddr1 = self.nodes[3].getnewaddress() + node3taddr2 = self.nodes[3].getnewaddress() + + # Prepare some non-coinbase UTXOs + wait_and_assert_operationid_status( + self.nodes[3], + self.nodes[3].z_shieldcoinbase("*", node3zaddr, 0)['opid'], + ) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + assert_equal(self.nodes[3].z_getbalance(node3zaddr), 250) + + wait_and_assert_operationid_status( + self.nodes[3], + self.nodes[3].z_sendmany( + node3zaddr, + [ + {'address': node3taddr1, 'amount': 60}, + {'address': node3taddr2, 'amount': 75}, + ], + 1 + ), + ) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Check the various balances. + assert_equal(self.nodes[1].z_getbalance(recipient), 0) + assert_equal(self.nodes[3].z_getbalance(node3taddr1), 60) + assert_equal(self.nodes[3].z_getbalance(node3taddr2), 75) + + # We should be able to spend multiple UTXOs at once + wait_and_assert_operationid_status( + self.nodes[3], + self.nodes[3].z_sendmany('ANY_TADDR', [{'address': recipient, 'amount': 100}], 1), + ) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # The recipient has their funds! + assert_equal(self.nodes[1].z_getbalance(recipient), 100) + + # Change is sent to a new t-address. + assert_equal(self.nodes[3].z_getbalance(node3taddr1), 0) + assert_equal(self.nodes[3].z_getbalance(node3taddr2), 0) + + # Send from a change t-address. + wait_and_assert_operationid_status( + self.nodes[3], + self.nodes[3].z_sendmany('ANY_TADDR', [{'address': recipient, 'amount': 20}], 1), + ) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # The recipient has their funds! + assert_equal(self.nodes[1].z_getbalance(recipient), 120) + + # Check that ANY_TADDR note selection doesn't attempt a double-spend + myopid = self.nodes[3].z_sendmany('ANY_TADDR', [{'address': recipient, 'amount': 20}], 1) + wait_and_assert_operationid_status(self.nodes[3], myopid, "failed", "Insufficient funds: have 14.99998, need 20.00001") + + # Create an expired transaction on node 3. + self.split_network() + expire_transparent = self.nodes[3].sendtoaddress(node2taddr1, 14) + assert(expire_transparent in self.nodes[3].getrawmempool()) + self.sync_all() + assert_equal('waiting', self.nodes[2].gettransaction(expire_transparent)['status']) + + self.nodes[0].generate(TX_EXPIRY_DELTA + TX_EXPIRING_SOON_THRESHOLD) + self.sync_all() + connect_nodes_bi(self.nodes, 1, 2) + sync_blocks(self.nodes[1:3]) + assert_equal('expired', self.nodes[2].gettransaction(expire_transparent)['status']) + + # Ensure that node 2 has no transparent funds. + self.nodes[2].generate(100) # To ensure node 2's pending coinbase is spendable + self.sync_all() + wait_and_assert_operationid_status( + self.nodes[2], + self.nodes[2].z_shieldcoinbase("*", node2zaddr, 0)['opid'], + ) + self.sync_all() + assert_equal(0, self.nodes[2].getbalance()) + + # Check that ANY_TADDR doesn't select an expired output. + wait_and_assert_operationid_status(self.nodes[2], self.nodes[2].z_sendmany('ANY_TADDR', [{'address': recipient, 'amount': 13}]), "failed", "Insufficient funds: have 0.00, need 13.00001") + +if __name__ == '__main__': + WalletSendManyAnyTaddr().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase.py b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase.py new file mode 100755 index 000000000..feb4b0aae --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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, sync_blocks, sync_mempools, \ + wait_and_assert_operationid_status, get_coinbase_address, DEFAULT_FEE, \ + NU5_BRANCH_ID, nuparams + +from decimal import Decimal + +class WalletShieldCoinbaseTest (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 = [ + '-regtestprotectcoinbase', + '-debug=zrpcunsafe', + nuparams(NU5_BRANCH_ID, self.nu5_activation), + ] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + self.nodes.append(start_node(2, self.options.tmpdir, args)) + 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(1) + self.nodes[0].generate(4) + self.sync_all() + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 50) + assert_equal(walletinfo['balance'], 0) + self.sync_all() + self.nodes[2].generate(1) + self.nodes[2].generate(1) + self.nodes[2].generate(1) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 50) + assert_equal(self.nodes[1].getbalance(), 10) + assert_equal(self.nodes[2].getbalance(), 30) + + # create one zaddr that is the target of all shielding + myzaddr = self.test_init_zaddr(self.nodes[0]) + + do_not_shield_taddr = get_coinbase_address(self.nodes[0], 1) + + # Prepare to send taddr->zaddr + mytaddr = get_coinbase_address(self.nodes[0], 4) + + # Shielding will fail when trying to spend from watch-only address + self.nodes[2].importaddress(mytaddr) + try: + self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Could not find any coinbase funds to shield" in errorString, True) + + # Shielding will fail because fee is negative + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, -1) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Shielding will fail because fee is larger than MAX_MONEY + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('21000000.00000001')) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Shielding will fail because fee is larger than sum of utxos + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, 999) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Insufficient coinbase funds" in errorString, True) + + # Shielding will fail because limit parameter must be at least 0 + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), -1) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Limit on maximum number of utxos cannot be negative" in errorString, True) + + # Shielding will fail because limit parameter is absurdly large + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), 99999999999999) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("JSON integer out of range" in errorString, True) + + # Shield coinbase utxos from node 0 of value 40, standard fee + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + self.test_check_balance_zaddr(self.nodes[0], Decimal('40.0') - DEFAULT_FEE) + assert_equal(self.nodes[1].getbalance(), 20) + assert_equal(self.nodes[2].getbalance(), 30) + + # Shield coinbase utxos from any node 2 taddr, and set fee to 0 + result = self.nodes[2].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 10) + self.test_check_balance_zaddr(self.nodes[0], Decimal('70.0') - DEFAULT_FEE) + assert_equal(self.nodes[1].getbalance(), 30) + assert_equal(self.nodes[2].getbalance(), 0) + + # Generate 800 coinbase utxos on node 0, and 20 coinbase utxos on node 2 + self.nodes[0].generate(800) + self.sync_all() + self.nodes[2].generate(20) + self.sync_all() + self.nodes[1].generate(100) + self.sync_all() + mytaddr = get_coinbase_address(self.nodes[0], 800) + + def verify_locking(first, second, limit): + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, limit) + assert_equal(result["shieldingUTXOs"], Decimal(first)) + assert_equal(result["remainingUTXOs"], Decimal(second)) + remainingValue = result["remainingValue"] + opid1 = result['opid'] + + # Verify that utxos are locked (not available for selection) by queuing up another shielding operation + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 0) + assert_equal(result["shieldingValue"], Decimal(remainingValue)) + assert_equal(result["shieldingUTXOs"], Decimal(second)) + assert_equal(result["remainingValue"], Decimal('0')) + assert_equal(result["remainingUTXOs"], Decimal('0')) + opid2 = result['opid'] + + # wait for both async operations to complete + wait_and_assert_operationid_status(self.nodes[0], opid1) + wait_and_assert_operationid_status(self.nodes[0], opid2) + + # Shield the 800 utxos over two transactions + verify_locking('500', '300', 500) + + # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected. + # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated + # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced. + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of utxos which node 0 can shield is set by default limit parameter of 50 + self.nodes[0].generate(200) + self.sync_all() + mytaddr = get_coinbase_address(self.nodes[0], 100) + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, DEFAULT_FEE) + assert_equal(result["shieldingUTXOs"], Decimal('50')) + assert_equal(result["remainingUTXOs"], Decimal('50')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + # Verify maximum number of utxos which node 0 can shield can be set by the limit parameter + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, DEFAULT_FEE, 33) + assert_equal(result["shieldingUTXOs"], Decimal('33')) + assert_equal(result["remainingUTXOs"], Decimal('17')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + +# Note, no "if __name__ == '__main__" and call the test here; it's called from +# pool-specific derived classes in wallet_shieldcoinbase_*.py \ No newline at end of file diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sapling.py b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sapling.py new file mode 100755 index 000000000..5e3cc2a39 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sapling.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +from wallet_shieldcoinbase import WalletShieldCoinbaseTest +from test_framework.util import assert_equal + +class WalletShieldCoinbaseSapling(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseSapling, self).__init__() + self.nu5_activation = 99999 + + def test_init_zaddr(self, node): + self.addr = node.z_getnewaddress('sapling') + return self.addr + + def test_check_balance_zaddr(self, node, expected): + balance = node.z_getbalance(self.addr) + assert_equal(balance, expected) + + +if __name__ == '__main__': + print("Test shielding to a sapling address") + WalletShieldCoinbaseSapling().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sprout.py b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sprout.py new file mode 100755 index 000000000..2e7fc7f7c --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_sprout.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +from wallet_shieldcoinbase import WalletShieldCoinbaseTest +from test_framework.util import assert_equal + +class WalletShieldCoinbaseSprout(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseSprout, self).__init__() + self.nu5_activation = 99999 + + def test_init_zaddr(self, node): + self.addr = node.z_getnewaddress('sprout') + return self.addr + + def test_check_balance_zaddr(self, node, expected): + balance = node.z_getbalance(self.addr) + assert_equal(balance, expected) + + +if __name__ == '__main__': + print("Test shielding to a sapling address") + WalletShieldCoinbaseSprout().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_nu5.py b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_nu5.py new file mode 100755 index 000000000..6d472462d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_nu5.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +from wallet_shieldcoinbase import WalletShieldCoinbaseTest +from test_framework.util import assert_equal +from test_framework.mininode import COIN + +class WalletShieldCoinbaseUANU5(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseUANU5, self).__init__() + self.account = None + # activate after initial setup, before the first z_shieldcoinbase RPC + self.nu5_activation = 109 + + def test_init_zaddr(self, node): + # this function may be called no more than once + assert(self.account is None) + self.account = node.z_getnewaccount()['account'] + self.addr = node.z_getaddressforaccount(self.account)['address'] + return self.addr + + def test_check_balance_zaddr(self, node, expected): + balances = node.z_getbalanceforaccount(self.account) + assert('transparent' not in balances['pools']) + assert('sprout' not in balances['pools']) + # Remove the following after Orchard support is added to z_shieldcoinbase + sapling_balance = balances['pools']['sapling']['valueZat'] + assert_equal(sapling_balance, expected * COIN) + # TODO: Uncomment after Orchard support is added to z_shieldcoinbase + #assert('sapling' not in balances['pools']) + #orchard_balance = balances['pools']['orchard']['valueZat'] + #assert_equal(orchard_balance, expected * COIN) + + # While we're at it, check that z_listunspent only shows outputs with + # the Unified Address (not the Orchard receiver), and of the expected + # type. + unspent = node.z_listunspent(1, 999999, False, [self.addr]) + assert_equal( + # TODO: Fix after Orchard support is added to z_shieldcoinbase + #[{'type': 'orchard', 'address': self.addr} for _ in unspent], + [{'type': 'sapling', 'address': self.addr} for _ in unspent], + [{'type': x['type'], 'address': x['address']} for x in unspent], + ) + + total_balance = node.z_getbalance(self.addr) * COIN + assert_equal(total_balance, sapling_balance) + +if __name__ == '__main__': + print("Test shielding to a unified address with NU5 activated") + WalletShieldCoinbaseUANU5().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_sapling.py b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_sapling.py new file mode 100755 index 000000000..3f1b88e4d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldcoinbase_ua_sapling.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +from wallet_shieldcoinbase import WalletShieldCoinbaseTest +from test_framework.util import assert_equal +from test_framework.mininode import COIN + +class WalletShieldCoinbaseUASapling(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseUASapling, self).__init__() + self.account = None + self.nu5_activation = 99999 + + def test_init_zaddr(self, node): + # this function may be called no more than once + assert(self.account is None) + self.account = node.z_getnewaccount()['account'] + self.addr = node.z_getaddressforaccount(self.account)['address'] + return self.addr + + def test_check_balance_zaddr(self, node, expected): + balances = node.z_getbalanceforaccount(self.account) + assert('transparent' not in balances['pools']) + assert('sprout' not in balances['pools']) + sapling_balance = balances['pools']['sapling']['valueZat'] + assert_equal(sapling_balance, expected * COIN) + assert('orchard' not in balances['pools']) + + # While we're at it, check that z_listunspent only shows outputs with + # the Unified Address (not the Sapling receiver), and of the expected + # type. + unspent = node.z_listunspent(1, 999999, False, [self.addr]) + assert_equal( + [{'type': 'sapling', 'address': self.addr} for _ in unspent], + [{'type': x['type'], 'address': x['address']} for x in unspent], + ) + + total_balance = node.z_getbalance(self.addr) * COIN + assert_equal(total_balance, sapling_balance) + +if __name__ == '__main__': + print("Test shielding to a unified address with sapling activated (but not NU5)") + WalletShieldCoinbaseUASapling().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_shieldingcoinbase.py b/depend/zcash/qa/rpc-tests/wallet_shieldingcoinbase.py new file mode 100755 index 000000000..c3261993a --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_shieldingcoinbase.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.mininode import COIN +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, \ + wait_and_assert_operationid_status_result, get_coinbase_address, \ + check_node_log, DEFAULT_FEE + +import sys +import timeit +from decimal import Decimal + +def check_value_pool(node, name, total): + value_pools = node.getblockchaininfo()['valuePools'] + found = False + for pool in value_pools: + if pool['id'] == name: + found = True + assert_equal(pool['monitored'], True) + assert_equal(pool['chainValue'], total) + assert_equal(pool['chainValueZat'], total * COIN) + assert(found) + +class WalletShieldingCoinbaseTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + # Start nodes with -regtestshieldcoinbase to set fCoinbaseMustBeShielded to true. + def setup_network(self, split=False): + self.nodes = start_nodes(4, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase', '-debug=zrpcunsafe']] * 4 ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + 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) + assert_equal(walletinfo['balance'], 0) + + 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(), 0) + assert_equal(self.nodes[3].getbalance(), 0) + + check_value_pool(self.nodes[0], 'sapling', 0) + check_value_pool(self.nodes[1], 'sapling', 0) + check_value_pool(self.nodes[2], 'sapling', 0) + check_value_pool(self.nodes[3], 'sapling', 0) + + # Send will fail because we are enforcing the consensus rule that + # coinbase utxos can only be sent to a zaddr. + errorString = "" + try: + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Coinbase funds can only be sent to a zaddr" in errorString, True) + + # Prepare to send taddr->zaddr + mytaddr = get_coinbase_address(self.nodes[0]) + myzaddr = self.nodes[0].z_getnewaddress('sapling') + + # Node 3 will test that watch only address utxos are not selected + self.nodes[3].importaddress(mytaddr) + recipients= [{"address":myzaddr, "amount": Decimal('1')}] + try: + myopid = self.nodes[3].z_sendmany(mytaddr, recipients) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Invalid from address, no payment source found for address.", errorString); + + # This send will fail because our consensus does not allow transparent change when + # shielding a coinbase utxo. + # TODO: After upgrading to unified address support, change will be sent to the most + # recent shielded spend authority corresponding to the account of the source address + # and this send will succeed, causing this test to fail. + recipients = [] + recipients.append({"address":myzaddr, "amount":Decimal('1.23456789')}) + + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + error_result = wait_and_assert_operationid_status_result( + self.nodes[0], + myopid, "failed", + "When shielding coinbase funds, the wallet does not allow any change. The proposed transaction would result in 8.76542211 in change.", + 10) + + # Test that the returned status object contains a params field with the operation's input parameters + assert_equal(error_result["method"], "z_sendmany") + params = error_result["params"] + assert_equal(params["fee"], DEFAULT_FEE) # default + assert_equal(params["minconf"], Decimal('10')) # default + assert_equal(params["fromaddress"], mytaddr) + assert_equal(params["amounts"][0]["address"], myzaddr) + assert_equal(params["amounts"][0]["amount"], Decimal('1.23456789')) + + # Add viewing key for myzaddr to Node 3 + myviewingkey = self.nodes[0].z_exportviewingkey(myzaddr) + self.nodes[3].z_importviewingkey(myviewingkey, "no") + + # This send will succeed. We send two coinbase utxos totalling 20.0 less a default fee, with no change. + shieldvalue = Decimal('20.0') - DEFAULT_FEE + recipients = [] + recipients.append({"address":myzaddr, "amount": shieldvalue}) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + + # Verify that z_listunspent can return a note that has zero confirmations + results = self.nodes[0].z_listunspent() + assert(len(results) == 0) + results = self.nodes[0].z_listunspent(0) # set minconf to zero + assert(len(results) == 1) + assert_equal(results[0]["type"], "sapling") + assert_equal(results[0]["address"], myzaddr) + assert_equal(results[0]["amount"], shieldvalue) + assert_equal(results[0]["confirmations"], 0) + + # Mine the tx + self.nodes[1].generate(1) + self.sync_all() + + # Verify that z_listunspent returns one note which has been confirmed + results = self.nodes[0].z_listunspent() + assert(len(results) == 1) + assert_equal(results[0]["type"], "sapling") + assert_equal(results[0]["address"], myzaddr) + assert_equal(results[0]["amount"], shieldvalue) + assert_equal(results[0]["confirmations"], 1) + assert_equal(results[0]["spendable"], True) + + # Verify that z_listunspent returns note for watchonly address on node 3. + results = self.nodes[3].z_listunspent(1, 999, True) + assert(len(results) == 1) + assert_equal(results[0]["type"], "sapling") + assert_equal(results[0]["address"], myzaddr) + assert_equal(results[0]["amount"], shieldvalue) + assert_equal(results[0]["confirmations"], 1) + assert_equal(results[0]["spendable"], False) + + # Verify that z_listunspent returns error when address spending key from node 0 is not available in wallet of node 1. + try: + results = self.nodes[1].z_listunspent(1, 999, False, [myzaddr]) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Invalid parameter, spending key for an address does not belong to the wallet.", errorString) + + # Verify that debug=zrpcunsafe logs params, and that full txid is associated with opid + initialized_line = check_node_log(self, 0, myopid + ": z_sendmany initialized", False) + finished_line = check_node_log(self, 0, myopid + ": z_sendmany finished", False) + assert(initialized_line < finished_line) + + # check balances (the z_sendmany consumes 3 coinbase utxos) + resp = self.nodes[0].z_gettotalbalance() + assert_equal(Decimal(resp["transparent"]), Decimal('20.0')) + assert_equal(Decimal(resp["private"]), Decimal('20.0') - DEFAULT_FEE) + assert_equal(Decimal(resp["total"]), Decimal('40.0') - DEFAULT_FEE) + + # The Sprout value pool should reflect the send + saplingvalue = shieldvalue + check_value_pool(self.nodes[0], 'sapling', saplingvalue) + + # A custom fee of 0 is okay. Here the node will send the note value back to itself. + recipients = [] + recipients.append({"address":myzaddr, "amount": Decimal('20.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1, Decimal('0.0')) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + resp = self.nodes[0].z_gettotalbalance() + assert_equal(Decimal(resp["transparent"]), Decimal('20.0')) + assert_equal(Decimal(resp["private"]), Decimal('20.0') - DEFAULT_FEE) + assert_equal(Decimal(resp["total"]), Decimal('40.0') - DEFAULT_FEE) + + # The Sapling value pool should be unchanged + check_value_pool(self.nodes[0], 'sapling', saplingvalue) + + # convert note to transparent funds + unshieldvalue = Decimal('10.0') + recipients = [] + recipients.append({"address":mytaddr, "amount": unshieldvalue}) + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) + assert(mytxid is not None) + self.sync_all() + + # check that priority of the tx sending from a zaddr is not 0 + mempool = self.nodes[0].getrawmempool(True) + assert(Decimal(mempool[mytxid]['startingpriority']) >= Decimal('1000000000000')) + + self.nodes[1].generate(1) + self.sync_all() + + # check balances + saplingvalue -= unshieldvalue + DEFAULT_FEE + resp = self.nodes[0].z_gettotalbalance() + assert_equal(Decimal(resp["transparent"]), Decimal('30.0')) + assert_equal(Decimal(resp["private"]), Decimal('10.0') - 2*DEFAULT_FEE) + assert_equal(Decimal(resp["total"]), Decimal('40.0') - 2*DEFAULT_FEE) + check_value_pool(self.nodes[0], 'sapling', saplingvalue) + + # z_sendmany will return an error if there is transparent change output considered dust. + # UTXO selection in z_sendmany sorts in ascending order, so smallest utxos are consumed first. + # At this point in time, unspent notes all have a value of 10.0. + recipients = [] + amount = Decimal('10.0') - DEFAULT_FEE - Decimal('0.00000001') # this leaves change at 1 zatoshi less than dust threshold + recipients.append({"address":self.nodes[0].getnewaddress(), "amount":amount }) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients, 1) + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient funds: have 10.00, need 0.00000053 more to avoid creating invalid change output 0.00000001 (dust threshold is 0.00000054)") + + # Send will fail because send amount is too big, even when including coinbase utxos + errorString = "" + try: + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 99999) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Insufficient funds" in errorString, True) + + # z_sendmany will fail because of insufficient funds + recipients = [] + recipients.append({"address":self.nodes[1].getnewaddress(), "amount":Decimal('10000.0')}) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients, 1) + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient funds: have 10.00, need 10000.00001; note that coinbase outputs will not be selected if you specify ANY_TADDR or if any transparent recipients are included.") + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1) + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient funds: have 9.99998, need 10000.00001; note that coinbase outputs will not be selected if you specify ANY_TADDR or if any transparent recipients are included.") + + # Send will fail because of insufficient funds unless sender uses coinbase utxos + try: + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 21) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr" in errorString, True) + + # Verify that mempools accept tx with joinsplits which have at least the default z_sendmany fee. + # If this test passes, it confirms that issue #1851 has been resolved, where sending from + # a zaddr to 1385 taddr recipients fails because the default fee was considered too low + # given the tx size, resulting in mempool rejection. + errorString = '' + recipients = [] + num_t_recipients = 2500 + amount_per_recipient = Decimal('0.00000546') # dust threshold + # Note that regtest chainparams does not require standard tx, so setting the amount to be + # less than the dust threshold, e.g. 0.00000001 will not result in mempool rejection. + start_time = timeit.default_timer() + for i in range(0,num_t_recipients): + newtaddr = self.nodes[2].getnewaddress() + recipients.append({"address":newtaddr, "amount":amount_per_recipient}) + elapsed = timeit.default_timer() - start_time + print("...invoked getnewaddress() {} times in {} seconds".format(num_t_recipients, elapsed)) + + # Issue #2263 Workaround START + # HTTP connection to node 0 may fall into a state, during the few minutes it takes to process + # loop above to create new addresses, that when z_sendmany is called with a large amount of + # rpc data in recipients, the connection fails with a 'broken pipe' error. Making a RPC call + # to node 0 before calling z_sendmany appears to fix this issue, perhaps putting the HTTP + # connection into a good state to handle a large amount of data in recipients. + self.nodes[0].getinfo() + # Issue #2263 Workaround END + + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1) + try: + wait_and_assert_operationid_status(self.nodes[0], myopid) + except JSONRPCException as e: + print("JSONRPC error: "+e.error['message']) + assert(False) + except Exception as e: + print("Unexpected exception caught during testing: ", e.error['message'], str(sys.exc_info()[0])) + assert(False) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # check balance + node2balance = amount_per_recipient * num_t_recipients + saplingvalue -= node2balance + DEFAULT_FEE + assert_equal(self.nodes[2].getbalance(), node2balance) + check_value_pool(self.nodes[0], 'sapling', saplingvalue) + + # Send will fail because fee is negative + try: + self.nodes[0].z_sendmany(myzaddr, recipients, 1, -1) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Send will fail because fee is larger than MAX_MONEY + try: + self.nodes[0].z_sendmany(myzaddr, recipients, 1, Decimal('21000000.00000001')) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Send will fail because fee is larger than sum of outputs + try: + self.nodes[0].z_sendmany(myzaddr, recipients, 1, (amount_per_recipient * num_t_recipients) + Decimal('0.00000001')) + except JSONRPCException as e: + errorString = e.error['message'] + assert_equal("is greater than the sum of outputs" in errorString, True) + + # Send will succeed because the balance of non-coinbase utxos is 10.0 + try: + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 9) + except JSONRPCException: + assert(False) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # check balance + node2balance = node2balance + 9 + assert_equal(self.nodes[2].getbalance(), node2balance) + + # Check that chained joinsplits in a single tx are created successfully. + recipients = [] + num_recipients = 3 + amount_per_recipient = Decimal('0.002') + minconf = 1 + send_amount = num_recipients * amount_per_recipient + custom_fee = Decimal('0.00012345') + zbalance = self.nodes[0].z_getbalance(myzaddr) + for i in range(0,num_recipients): + newzaddr = self.nodes[2].z_getnewaddress('sapling') + recipients.append({"address":newzaddr, "amount":amount_per_recipient}) + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, custom_fee) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # check balances and unspent notes + resp = self.nodes[2].z_gettotalbalance() + assert_equal(Decimal(resp["private"]), send_amount) + + notes = self.nodes[2].z_listunspent() + sum_of_notes = sum([note["amount"] for note in notes]) + assert_equal(Decimal(resp["private"]), sum_of_notes) + + resp = self.nodes[0].z_getbalance(myzaddr) + assert_equal(Decimal(resp), zbalance - custom_fee - send_amount) + saplingvalue -= custom_fee + check_value_pool(self.nodes[0], 'sapling', saplingvalue) + + notes = self.nodes[0].z_listunspent(1, 99999, False, [myzaddr]) + sum_of_notes = sum([note["amount"] for note in notes]) + assert_equal(Decimal(resp), sum_of_notes) + +if __name__ == '__main__': + WalletShieldingCoinbaseTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_treestate.py b/depend/zcash/qa/rpc-tests/wallet_treestate.py new file mode 100755 index 000000000..c51097bb9 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_treestate.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status, \ + get_coinbase_address, DEFAULT_FEE + +import time +from decimal import Decimal + +class WalletTreeStateTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + # Start nodes with -regtestshieldcoinbase to set fCoinbaseMustBeShielded to true. + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestshieldcoinbase','-debug=zrpc']] * 3 ) + 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(100) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + + mytaddr = get_coinbase_address(self.nodes[0]) + myzaddr = self.nodes[0].z_getnewaddress() + + # Spend coinbase utxos to create three notes of 10 ZEC minus default fee each + recipients = [] + recipients.append({"address": myzaddr, "amount": Decimal('10.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Check balance + resp = self.nodes[0].z_getbalance(myzaddr) + assert_equal(Decimal(resp), (Decimal('10.0') - DEFAULT_FEE) * 3) + + # We want to test a real-world situation where during the time spent creating a transaction + # with joinsplits, other transactions containing joinsplits have been mined into new blocks, + # which result in the treestate changing whilst creating the transaction. + + # Tx 1 will change the treestate while Tx 2 containing chained joinsplits is still being generated + recipients = [] + recipients.append({"address": self.nodes[2].z_getnewaddress(), "amount": Decimal('10.0') - DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Tx 2 will consume all three notes, which must take at least two joinsplits. This is regardless of + # the z_sendmany implementation because there are only two inputs per joinsplit. + recipients = [] + recipients.append({"address": self.nodes[2].z_getnewaddress(), "amount": Decimal('18.0')}) + recipients.append({"address": self.nodes[2].z_getnewaddress(), "amount": Decimal('12.0') - 4*DEFAULT_FEE}) + myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1) + + # Wait for Tx 2 to begin executing... + for x in range(1, 60): + results = self.nodes[0].z_getoperationstatus([myopid]) + status = results[0]["status"] + if status == "executing": + break + time.sleep(1) + + # Now mine Tx 1 which will change global treestate before Tx 2's second joinsplit begins processing + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Wait for Tx 2 to be created + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Note that a bug existed in v1.0.0-1.0.3 where Tx 2 creation would fail with an error: + # "Witness for spendable note does not have same anchor as change input" + + # Check balance + resp = self.nodes[0].z_getbalance(myzaddr) + assert_equal(Decimal(resp), Decimal('0.0')) + + +if __name__ == '__main__': + WalletTreeStateTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_unified_change.py b/depend/zcash/qa/rpc-tests/wallet_unified_change.py new file mode 100755 index 000000000..1384d642d --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_unified_change.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + DEFAULT_FEE, + NU5_BRANCH_ID, + assert_equal, + get_coinbase_address, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) + +# Test wallet accounts behaviour +class WalletUnifiedChangeTest(BitcoinTestFramework): + def __init__(self): + super().__init__() + self.num_nodes = 4 + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 201), + ]] * self.num_nodes) + + def run_test(self): + # Activate Nu5 + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + account0 = self.nodes[0].z_getnewaccount()['account'] + ua0_sapling = self.nodes[0].z_getaddressforaccount(account0, ['sapling'])['address'] + ua0_orchard = self.nodes[0].z_getaddressforaccount(account0, ['orchard'])['address'] + + account1 = self.nodes[1].z_getnewaccount()['account'] + ua1_sapling = self.nodes[1].z_getaddressforaccount(account1, ['sapling'])['address'] + ua1 = self.nodes[1].z_getaddressforaccount(account1)['address'] + + # Fund both of ua0_sapling and ua0_orchard + recipients = [{'address': ua0_sapling, 'amount': Decimal('9.99999000')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, DEFAULT_FEE, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], opid) + + recipients = [{'address': ua0_orchard, 'amount': Decimal('9.99999000')}] + opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, DEFAULT_FEE, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[0], opid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'sapling': {'valueZat': 999999000}, 'orchard': {'valueZat': 999999000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(account0)) + + # Send both amounts to ua1 in fully-shielded transactions. This will result + # in account1 having both Sapling and Orchard balances. + + recipients = [{'address': ua1_sapling, 'amount': 5}] + opid = self.nodes[0].z_sendmany(ua0_sapling, recipients, 1, DEFAULT_FEE) + txid_sapling = wait_and_assert_operationid_status(self.nodes[0], opid) + + recipients = [{'address': ua1, 'amount': 5}] + opid = self.nodes[0].z_sendmany(ua0_orchard, recipients, 1, DEFAULT_FEE) + txid_orchard = wait_and_assert_operationid_status(self.nodes[0], opid) + + assert_equal(set([txid_sapling, txid_orchard]), set(self.nodes[0].getrawmempool())) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + assert_equal([], self.nodes[0].getrawmempool()) + assert_equal(1, self.nodes[0].gettransaction(txid_orchard)['confirmations']) + assert_equal(1, self.nodes[0].gettransaction(txid_sapling)['confirmations']) + + assert_equal( + {'pools': {'sapling': {'valueZat': 500000000}, 'orchard': {'valueZat': 500000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(account1)) + + # Now send sapling->sapling, generating change. + recipients = [{'address': ua0_sapling, 'amount': Decimal('2.5')}] + opid = self.nodes[1].z_sendmany(ua1_sapling, recipients, 1, 0) + txid_sapling = wait_and_assert_operationid_status(self.nodes[1], opid) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Since this is entirely sapling->sapling, change should be returned + # to the Sapling pool. + assert_equal( + {'pools': {'sapling': {'valueZat': 250000000}, 'orchard': {'valueZat': 500000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(account1)) + + # If we send from an unrestricted UA, change should still not cross + # the pool boundary, since we can build a purely sapling->sapling tx. + recipients = [{'address': ua0_sapling, 'amount': Decimal('1.25')}] + opid = self.nodes[1].z_sendmany(ua1, recipients, 1, 0) + txid_sapling = wait_and_assert_operationid_status(self.nodes[1], opid) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'sapling': {'valueZat': 125000000}, 'orchard': {'valueZat': 500000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(account1)) + +if __name__ == '__main__': + WalletUnifiedChangeTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_z_sendmany.py b/depend/zcash/qa/rpc-tests/wallet_z_sendmany.py new file mode 100755 index 000000000..436e983be --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_z_sendmany.py @@ -0,0 +1,448 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + DEFAULT_FEE, + NU5_BRANCH_ID, + assert_equal, + assert_greater_than, + assert_raises_message, + connect_nodes_bi, + nuparams, + start_nodes, + wait_and_assert_operationid_status, +) +from test_framework.authproxy import JSONRPCException +from test_framework.mininode import COIN +from decimal import Decimal + +# Test wallet address behaviour across network upgrades +class WalletZSendmanyTest(BitcoinTestFramework): + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir, [[ + nuparams(NU5_BRANCH_ID, 238), + ]] * self.num_nodes) + 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() + + # Check we only have balances in the expected pools. + # Remember that empty pools are omitted from the output. + def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf): + rpc = getattr(self.nodes[node], rpcmethod) + actual = rpc(account, minconf) + assert_equal(set(expected), set(actual['pools'])) + total_balance = 0 + for pool in expected: + assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat']) + total_balance += expected[pool] + assert_equal(actual['minimum_confirmations'], minconf) + return total_balance + + def check_balance(self, node, account, address, expected, minconf=1): + acct_balance = self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf) + z_getbalance = self.nodes[node].z_getbalance(address, minconf) + assert_equal(acct_balance, z_getbalance) + fvk = self.nodes[node].z_exportviewingkey(address) + self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf) + + def run_test(self): + # z_sendmany is expected to fail if tx size breaks limit + myzaddr = self.nodes[0].z_getnewaddress() + + recipients = [] + num_t_recipients = 1000 + num_z_recipients = 2100 + amount_per_recipient = Decimal('0.00000001') + errorString = '' + for i in range(0,num_t_recipients): + newtaddr = self.nodes[2].getnewaddress() + recipients.append({"address":newtaddr, "amount":amount_per_recipient}) + for i in range(0,num_z_recipients): + newzaddr = self.nodes[2].z_getnewaddress() + recipients.append({"address":newzaddr, "amount":amount_per_recipient}) + + # Issue #2759 Workaround START + # HTTP connection to node 0 may fall into a state, during the few minutes it takes to process + # loop above to create new addresses, that when z_sendmany is called with a large amount of + # rpc data in recipients, the connection fails with a 'broken pipe' error. Making a RPC call + # to node 0 before calling z_sendmany appears to fix this issue, perhaps putting the HTTP + # connection into a good state to handle a large amount of data in recipients. + self.nodes[0].getinfo() + # Issue #2759 Workaround END + + try: + self.nodes[0].z_sendmany(myzaddr, recipients) + except JSONRPCException as e: + errorString = e.error['message'] + assert("size of raw transaction would be larger than limit" in errorString) + + # add zaddr to node 2 + myzaddr = self.nodes[2].z_getnewaddress() + + # add taddr to node 2 + mytaddr = self.nodes[2].getnewaddress() + + # send from node 0 to node 2 taddr + mytxid = self.nodes[0].sendtoaddress(mytaddr, 10.0) + self.sync_all() + self.nodes[0].generate(10) + self.sync_all() + + # send node 2 taddr to zaddr + recipients = [] + recipients.append({"address":myzaddr, "amount":7}) + opid = self.nodes[2].z_sendmany(mytaddr, recipients) + mytxid = wait_and_assert_operationid_status(self.nodes[2], opid) + + self.sync_all() + + # check balances + zsendmanynotevalue = Decimal('7.0') + zsendmanyfee = DEFAULT_FEE + node2utxobalance = Decimal('260.00000000') - zsendmanynotevalue - zsendmanyfee + + # check shielded balance status with getwalletinfo + wallet_info = self.nodes[2].getwalletinfo() + assert_equal(Decimal(wallet_info["shielded_unconfirmed_balance"]), zsendmanynotevalue) + assert_equal(Decimal(wallet_info["shielded_balance"]), Decimal('0.0')) + + self.nodes[2].generate(10) + self.sync_all() + + assert_equal(self.nodes[2].getbalance(), node2utxobalance) + assert_equal(self.nodes[2].getbalance("*"), node2utxobalance) + + # check zaddr balance with z_getbalance + zbalance = zsendmanynotevalue + assert_equal(self.nodes[2].z_getbalance(myzaddr), zbalance) + + # check via z_gettotalbalance + resp = self.nodes[2].z_gettotalbalance() + assert_equal(Decimal(resp["transparent"]), node2utxobalance) + assert_equal(Decimal(resp["private"]), zbalance) + assert_equal(Decimal(resp["total"]), node2utxobalance + zbalance) + + # check confirmed shielded balance with getwalletinfo + wallet_info = self.nodes[2].getwalletinfo() + assert_equal(Decimal(wallet_info["shielded_unconfirmed_balance"]), Decimal('0.0')) + assert_equal(Decimal(wallet_info["shielded_balance"]), zsendmanynotevalue) + + # there should be at least one Sapling output + mytxdetails = self.nodes[2].getrawtransaction(mytxid, 1) + assert_greater_than(len(mytxdetails["vShieldedOutput"]), 0) + # the Sapling output should take in all the public value + assert_equal(mytxdetails["valueBalance"], -zsendmanynotevalue) + + # send from private note to node 0 and node 2 + node0balance = self.nodes[0].getbalance() + # The following assertion fails nondeterministically + # assert_equal(node0balance, Decimal('25.99798873')) + node2balance = self.nodes[2].getbalance() + # The following assertion might fail nondeterministically + # assert_equal(node2balance, Decimal('16.99799000')) + + recipients = [] + recipients.append({"address":self.nodes[0].getnewaddress(), "amount":1}) + recipients.append({"address":self.nodes[2].getnewaddress(), "amount":1.0}) + + opid = self.nodes[2].z_sendmany(myzaddr, recipients) + wait_and_assert_operationid_status(self.nodes[2], opid) + zbalance -= Decimal('2.0') + zsendmanyfee + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + node0balance += Decimal('11.0') + node2balance += Decimal('1.0') + assert_equal(Decimal(self.nodes[0].getbalance()), node0balance) + assert_equal(Decimal(self.nodes[0].getbalance("*")), node0balance) + assert_equal(Decimal(self.nodes[2].getbalance()), node2balance) + assert_equal(Decimal(self.nodes[2].getbalance("*")), node2balance) + + # Get a new unified account on node 2 & generate a UA + n0account0 = self.nodes[0].z_getnewaccount()['account'] + n0ua0 = self.nodes[0].z_getaddressforaccount(n0account0)['address'] + + # Change went to a fresh address, so use `ANY_TADDR` which + # should hold the rest of our transparent funds. + source = 'ANY_TADDR' + recipients = [] + recipients.append({"address":n0ua0, "amount":10}) + + # If we attempt to spend with the default privacy policy, z_sendmany + # fails because it needs to spend transparent coins in a transaction + # involving a Unified Address. + revealed_senders_msg = 'This transaction requires selecting transparent coins, which is not enabled by default because it will publicly reveal transaction senders and amounts. THIS MAY AFFECT YOUR PRIVACY. Resubmit with the `privacyPolicy` parameter set to `AllowRevealedSenders` or weaker if you wish to allow this transaction to proceed anyway.' + opid = self.nodes[2].z_sendmany(source, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[2], opid, 'failed', revealed_senders_msg) + + # We can't create a transaction with an unknown privacy policy. + assert_raises_message( + JSONRPCException, + 'Unknown privacy policy name \'ZcashIsAwesome\'', + self.nodes[2].z_sendmany, + source, recipients, 1, 0, 'ZcashIsAwesome') + + # If we set any policy that does not include AllowRevealedSenders, + # z_sendmany also fails. + for policy in [ + 'FullPrivacy', + 'AllowRevealedAmounts', + 'AllowRevealedRecipients', + ]: + opid = self.nodes[2].z_sendmany(source, recipients, 1, 0, policy) + wait_and_assert_operationid_status(self.nodes[2], opid, 'failed', revealed_senders_msg) + + # By setting the correct policy, we can create the transaction. + opid = self.nodes[2].z_sendmany(source, recipients, 1, 0, 'AllowRevealedSenders') + wait_and_assert_operationid_status(self.nodes[2], opid) + + self.nodes[2].generate(1) + self.sync_all() + + node2balance -= Decimal('10.0') + node0balance += Decimal('10.0') + assert_equal(Decimal(self.nodes[2].getbalance()), node2balance) + assert_equal(Decimal(self.nodes[0].getbalance()), node0balance) + self.check_balance(0, 0, n0ua0, {'sapling': 10}) + + # Send some funds to a specific legacy taddr that we can spend from + recipients = [] + recipients.append({"address":mytaddr, "amount":5}) + + # If we attempt to spend with the default privacy policy, z_sendmany + # returns an error because it needs to create a transparent recipient in + # a transaction involving a Unified Address. + revealed_recipients_msg = "This transaction would have transparent recipients, which is not enabled by default because it will publicly reveal transaction recipients and amounts. THIS MAY AFFECT YOUR PRIVACY. Resubmit with the `privacyPolicy` parameter set to `AllowRevealedRecipients` or weaker if you wish to allow this transaction to proceed anyway." + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid, 'failed', revealed_recipients_msg) + + # If we set any policy that does not include AllowRevealedRecipients, + # z_sendmany also returns an error. + for policy in [ + 'FullPrivacy', + 'AllowRevealedAmounts', + 'AllowRevealedSenders', + 'AllowLinkingAccountAddresses', + ]: + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0, policy) + wait_and_assert_operationid_status(self.nodes[0], opid, 'failed', revealed_recipients_msg) + + # By setting the correct policy, we can create the transaction. + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0, 'AllowRevealedRecipients') + wait_and_assert_operationid_status(self.nodes[0], opid) + + self.nodes[0].generate(1) + self.sync_all() + + node2balance += Decimal('5.0') + self.check_balance(0, 0, n0ua0, {'sapling': 5}) + assert_equal(Decimal(self.nodes[2].getbalance()), node2balance) + + # Send some funds to a legacy sapling address that we can spend from + recipients = [] + recipients.append({"address":myzaddr, "amount":3}) + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid) + + self.nodes[0].generate(1) + self.sync_all() + + zbalance += Decimal('3.0') + self.check_balance(0, 0, n0ua0, {'sapling': 2}) + assert_equal(Decimal(self.nodes[2].z_getbalance(myzaddr)), zbalance) + + # Send funds back from the legacy taddr to the UA. This requires + # AllowRevealedSenders, but we can also use any weaker policy that + # includes it. + recipients = [] + recipients.append({"address":n0ua0, "amount":4}) + opid = self.nodes[2].z_sendmany(mytaddr, recipients, 1, 0, 'AllowFullyTransparent') + wait_and_assert_operationid_status(self.nodes[2], opid) + + self.nodes[2].generate(1) + self.sync_all() + + node2balance -= Decimal('4.0') + self.check_balance(0, 0, n0ua0, {'sapling': 6}) + assert_equal(Decimal(self.nodes[2].getbalance()), node2balance) + + # Send funds back from the legacy zaddr to the UA + recipients = [] + recipients.append({"address":n0ua0, "amount":2}) + opid = self.nodes[2].z_sendmany(myzaddr, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[2], opid) + + self.nodes[2].generate(1) + self.sync_all() + + zbalance -= Decimal('2.0') + self.check_balance(0, 0, n0ua0, {'sapling': 8}) + assert_equal(Decimal(self.nodes[2].z_getbalance(myzaddr)), zbalance) + + # + # Test that z_sendmany avoids UA linkability unless we allow it. + # + + # Generate a new account with two new addresses. + n1account = self.nodes[1].z_getnewaccount()['account'] + n1ua0 = self.nodes[1].z_getaddressforaccount(n1account)['address'] + n1ua1 = self.nodes[1].z_getaddressforaccount(n1account)['address'] + + # Send funds to the transparent receivers of both addresses. + for ua in [n1ua0, n1ua1]: + taddr = self.nodes[1].z_listunifiedreceivers(ua)['p2pkh'] + self.nodes[0].sendtoaddress(taddr, 2) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # The account should see all funds. + assert_equal( + self.nodes[1].z_getbalanceforaccount(n1account)['pools'], + {'transparent': {'valueZat': 4 * COIN}}, + ) + + # The addresses should see only the transparent funds sent to them. + assert_equal(self.nodes[1].z_getbalance(n1ua0), 2) + assert_equal(self.nodes[1].z_getbalance(n1ua1), 2) + + # If we try to send 3 ZEC from n1ua0, it will fail with too-few funds. + recipients = [{"address":n0ua0, "amount":3}] + linked_addrs_msg = 'Insufficient funds: have 2.00, need 3.00 (This transaction may require selecting transparent coins that were sent to multiple Unified Addresses, which is not enabled by default because it would create a public link between the transparent receivers of these addresses. THIS MAY AFFECT YOUR PRIVACY. Resubmit with the `privacyPolicy` parameter set to `AllowLinkingAccountAddresses` or weaker if you wish to allow this transaction to proceed anyway.)' + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], opid, 'failed', linked_addrs_msg) + + # If we try it again with any policy that is too strong, it also fails. + for policy in [ + 'FullPrivacy', + 'AllowRevealedAmounts', + 'AllowRevealedRecipients', + 'AllowRevealedSenders', + 'AllowFullyTransparent', + ]: + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0, policy) + wait_and_assert_operationid_status(self.nodes[1], opid, 'failed', linked_addrs_msg) + + # Once we provide a sufficiently-weak policy, the transaction succeeds. + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0, 'AllowLinkingAccountAddresses') + wait_and_assert_operationid_status(self.nodes[1], opid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # The account should see the remaining funds, and they should have been + # sent to the Sapling change address (because NU5 is not active). + assert_equal( + self.nodes[1].z_getbalanceforaccount(n1account)['pools'], + {'sapling': {'valueZat': 1 * COIN}}, + ) + + # The addresses should both show the same balance, as they both show the + # Sapling balance. + assert_equal(self.nodes[1].z_getbalance(n1ua0), 1) + assert_equal(self.nodes[1].z_getbalance(n1ua1), 1) + + # + # Test NoPrivacy policy + # + + # Send some legacy transparent funds to n1ua0, creating Sapling outputs. + recipients = [{"address":n1ua0, "amount":10}] + # This requires the AllowRevealedSenders policy... + opid = self.nodes[2].z_sendmany('ANY_TADDR', recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[2], opid, 'failed', revealed_senders_msg) + # ... which we can always override with the NoPrivacy policy. + opid = self.nodes[2].z_sendmany('ANY_TADDR', recipients, 1, 0, 'NoPrivacy') + wait_and_assert_operationid_status(self.nodes[2], opid) + + self.sync_all() + self.nodes[2].generate(1) + self.sync_all() + + # Send some funds from node 1's account to a transparent address. + recipients = [{"address":mytaddr, "amount":5}] + # This requires the AllowRevealedRecipients policy... + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], opid, 'failed', revealed_recipients_msg) + # ... which we can always override with the NoPrivacy policy. + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0, 'NoPrivacy') + wait_and_assert_operationid_status(self.nodes[1], opid) + + # Activate NU5 + + self.sync_all() + self.nodes[1].generate(10) + self.sync_all() + + # + # Test AllowRevealedAmounts policy + # + + assert_equal( + {'pools': {'sapling': {'valueZat': 600000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(n1account)) + + # Sending some funds to the Orchard pool in n0account0 ... + n0ua1 = self.nodes[0].z_getaddressforaccount(n0account0, ["orchard"])['address'] + recipients = [{"address":n0ua1, "amount": 6}] + + # Should fail under default and 'FullPrivacy' policies ... + revealed_amounts_msg = 'Sending from the Sapling shielded pool to the Orchard shielded pool is not enabled by default because it will publicly reveal the transaction amount. THIS MAY AFFECT YOUR PRIVACY. Resubmit with the `privacyPolicy` parameter set to `AllowRevealedAmounts` or weaker if you wish to allow this transaction to proceed anyway.' + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[1], opid, 'failed', revealed_amounts_msg) + + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0, 'FullPrivacy') + wait_and_assert_operationid_status(self.nodes[1], opid, 'failed', revealed_amounts_msg) + + # Should succeed under 'AllowRevealedAmounts' + opid = self.nodes[1].z_sendmany(n1ua0, recipients, 1, 0, 'AllowRevealedAmounts') + wait_and_assert_operationid_status(self.nodes[1], opid) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal( + {'pools': {'sapling': {'valueZat': 1100000000}, 'orchard': {'valueZat': 600000000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(n0account0)) + + # A total that requires selecting from both pools should fail under default and + # FullPrivacy policies... + + recipients = [{"address":n1ua0, "amount": 15}] + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0) + wait_and_assert_operationid_status(self.nodes[0], opid, 'failed', revealed_amounts_msg) + + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0, 'FullPrivacy') + wait_and_assert_operationid_status(self.nodes[0], opid, 'failed', revealed_amounts_msg) + + # Should succeed under 'AllowRevealedAmounts' + opid = self.nodes[0].z_sendmany(n0ua0, recipients, 1, 0, 'AllowRevealedAmounts') + wait_and_assert_operationid_status(self.nodes[0], opid) + + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # All funds should be received to the Orchard pool + assert_equal( + {'pools': {'orchard': {'valueZat': 1500000000}}, 'minimum_confirmations': 1}, + self.nodes[1].z_getbalanceforaccount(n1account)) + + # And all change should be optimistically shielded + assert_equal( + {'pools': {'orchard': {'valueZat': 200000000}}, 'minimum_confirmations': 1}, + self.nodes[0].z_getbalanceforaccount(n0account0)) + +if __name__ == '__main__': + WalletZSendmanyTest().main() diff --git a/depend/zcash/qa/rpc-tests/wallet_zero_value.py b/depend/zcash/qa/rpc-tests/wallet_zero_value.py new file mode 100755 index 000000000..00b1d76c2 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/wallet_zero_value.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# Copyright (c) 2020 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, connect_nodes_bi, start_nodes +from decimal import Decimal + +# Test wallet address behaviour across network upgrades +class WalletZeroValueTest(BitcoinTestFramework): + def setup_network(self, split=False): + self.nodes = start_nodes(2, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + self.is_network_split=False + self.sync_all() + + def run_test(self): + #check if we can list zero value tx as available coins + #1. create rawtx + #2. hex-changed one output to 0.0 + #3. sign and send + #4. check if recipient (node0) can list the zero value tx + usp = self.nodes[1].listunspent() + inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}] + outputs = {self.nodes[1].getnewaddress(): 9.998, self.nodes[0].getnewaddress(): 11.11} + + rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32) + decRawTx = self.nodes[1].decoderawtransaction(rawTx) + signedRawTx = self.nodes[1].signrawtransaction(rawTx) + decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex']) + zeroValueTxid= decRawTx['txid'] + self.nodes[1].sendrawtransaction(signedRawTx['hex']) + + self.sync_all() + self.nodes[1].generate(1) #mine a block + self.sync_all() + + unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output + found = False + for uTx in unspentTxs: + if uTx['txid'] == zeroValueTxid: + found = True + assert_equal(uTx['amount'], Decimal('0.00000000')) + assert_equal(uTx['amountZat'], 0) + assert(found) + +if __name__ == '__main__': + WalletZeroValueTest().main() diff --git a/depend/zcash/qa/rpc-tests/walletbackup.py b/depend/zcash/qa/rpc-tests/walletbackup.py new file mode 100755 index 000000000..ee2f88460 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/walletbackup.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +""" +Exercise the wallet backup code. Ported from walletbackup.sh. + +Test case is: +4 nodes. 1 2 and 3 send transactions between each other, +fourth node is a miner. +1 2 3 each mine a block to start, then +Miner creates 100 blocks so 1 2 3 each have 40 mature +coins to spend. +Then 5 iterations of 1/2/3 sending coins amongst +themselves to get transactions in the wallets, +and the miner mining one block. + +Wallets are backed up using dumpwallet/backupwallet. +Then 5 more iterations of transactions and mining a block. + +Miner then generates 101 more blocks, so any +transaction fees paid mature. + +Sanity check: + Sum(1,2,3,4 balances) == 114*40 + +1/2/3 are shutdown, and their wallets erased. +Then restore using wallet.dat backup. And +confirm 1/2/3/4 balances are same as before. + +Shutdown again, restore using importwallet, +and confirm again balances are correct. +""" + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, \ + start_nodes, start_node, connect_nodes, stop_node, \ + sync_blocks, sync_mempools + +import os +import shutil +from random import randint +from decimal import Decimal +import logging +import sys + +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout) + +class WalletBackupTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 4 + + # This mirrors how the network was setup in the bash test + def setup_network(self, split=False): + # -exportdir option means we must provide a valid path to the destination folder for wallet backups + ed0 = "-exportdir=" + self.options.tmpdir + "/node0" + ed1 = "-exportdir=" + self.options.tmpdir + "/node1" + ed2 = "-exportdir=" + self.options.tmpdir + "/node2" + + # nodes 1, 2,3 are spenders, let's give them a keypool=100 + extra_args = [["-keypool=100", ed0], ["-keypool=100", ed1], ["-keypool=100", ed2], []] + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args) + connect_nodes(self.nodes[0], 3) + connect_nodes(self.nodes[1], 3) + connect_nodes(self.nodes[2], 3) + connect_nodes(self.nodes[2], 0) + self.is_network_split=False + self.sync_all() + + def one_send(self, from_node, to_address): + if (randint(1,2) == 1): + amount = Decimal(randint(1,10)) / Decimal(10) + self.nodes[from_node].sendtoaddress(to_address, amount) + + def do_one_round(self): + a0 = self.nodes[0].getnewaddress() + a1 = self.nodes[1].getnewaddress() + a2 = self.nodes[2].getnewaddress() + + self.one_send(0, a1) + self.one_send(0, a2) + self.one_send(1, a0) + self.one_send(1, a2) + self.one_send(2, a0) + self.one_send(2, a1) + + # Have the miner (node3) mine a block. + # Must sync mempools before mining. + sync_mempools(self.nodes) + self.nodes[3].generate(1) + self.sync_all() + + # As above, this mirrors the original bash test. + def start_three(self, extra_args=None): + self.nodes[0] = start_node(0, self.options.tmpdir, extra_args) + self.nodes[1] = start_node(1, self.options.tmpdir, extra_args) + self.nodes[2] = start_node(2, self.options.tmpdir, extra_args) + connect_nodes(self.nodes[0], 3) + connect_nodes(self.nodes[1], 3) + connect_nodes(self.nodes[2], 3) + connect_nodes(self.nodes[2], 0) + + def stop_three(self): + stop_node(self.nodes[0], 0) + stop_node(self.nodes[1], 1) + stop_node(self.nodes[2], 2) + + def erase_three(self): + os.remove(self.options.tmpdir + "/node0/regtest/wallet.dat") + os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat") + os.remove(self.options.tmpdir + "/node2/regtest/wallet.dat") + + def run_test(self): + logging.info("Generating initial blockchain") + self.nodes[0].generate(1) + sync_blocks(self.nodes) + self.nodes[1].generate(1) + sync_blocks(self.nodes) + self.nodes[2].generate(1) + sync_blocks(self.nodes) + self.nodes[3].generate(100) + sync_blocks(self.nodes) + + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[1].getbalance(), 10) + assert_equal(self.nodes[2].getbalance(), 10) + assert_equal(self.nodes[3].getbalance(), 0) + + logging.info("Creating transactions") + # Five rounds of sending each other transactions. + for i in range(5): + self.do_one_round() + + logging.info("Backing up") + tmpdir = self.options.tmpdir + self.nodes[0].backupwallet("walletbak") + self.nodes[0].dumpwallet("walletdump") + self.nodes[1].backupwallet("walletbak") + self.nodes[1].dumpwallet("walletdump") + self.nodes[2].backupwallet("walletbak") + self.nodes[2].dumpwallet("walletdump") + + # Verify dumpwallet cannot overwrite an existing file + try: + self.nodes[2].dumpwallet("walletdump") + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Cannot overwrite existing file" in errorString) + + logging.info("More transactions") + for i in range(5): + self.do_one_round() + + # Generate 101 more blocks, so any fees paid mature + self.nodes[3].generate(101) + self.sync_all() + + balance0 = self.nodes[0].getbalance() + balance1 = self.nodes[1].getbalance() + balance2 = self.nodes[2].getbalance() + balance3 = self.nodes[3].getbalance() + total = balance0 + balance1 + balance2 + balance3 + + # At this point, there are 214 blocks (103 for setup, then 10 rounds, then 101.) + # 114 are mature, so the sum of all wallets should be 114 * 10 = 1140. + assert_equal(total, 1140) + + ## + # Test restoring spender wallets from backups + ## + logging.info("Restoring using wallet.dat") + self.stop_three() + self.erase_three() + + # Start node2 with no chain + shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks") + shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate") + + # Restore wallets from backup + shutil.copyfile(tmpdir + "/node0/walletbak", tmpdir + "/node0/regtest/wallet.dat") + shutil.copyfile(tmpdir + "/node1/walletbak", tmpdir + "/node1/regtest/wallet.dat") + shutil.copyfile(tmpdir + "/node2/walletbak", tmpdir + "/node2/regtest/wallet.dat") + + logging.info("Re-starting nodes") + self.start_three() + sync_blocks(self.nodes) + + # We made extra transactions that involved addresses generated after the + # backups were taken, and external addresses do not use the keypool, so + # the balances shouldn't line up. + balance0backup = self.nodes[0].getbalance() + balance1backup = self.nodes[1].getbalance() + balance2backup = self.nodes[2].getbalance() + assert(balance0backup != balance0) + assert(balance1backup != balance1) + assert(balance2backup != balance2) + + # However, because addresses are derived deterministically, we can + # recover the balances by generating the extra addresses and then + # rescanning. + for i in range(5): + self.nodes[0].getnewaddress() + self.nodes[1].getnewaddress() + self.nodes[2].getnewaddress() + + logging.info("Re-starting nodes with -rescan") + self.stop_three() + self.start_three(['-rescan']) + sync_blocks(self.nodes) + + assert_equal(self.nodes[0].getbalance(), balance0) + assert_equal(self.nodes[1].getbalance(), balance1) + assert_equal(self.nodes[2].getbalance(), balance2) + + logging.info("Restoring using dumped wallet") + self.stop_three() + self.erase_three() + + #start node2 with no chain + shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks") + shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate") + + self.start_three() + + assert_equal(self.nodes[0].getbalance(), 0) + assert_equal(self.nodes[1].getbalance(), 0) + assert_equal(self.nodes[2].getbalance(), 0) + + self.nodes[0].importwallet(tmpdir + "/node0/walletdump") + self.nodes[1].importwallet(tmpdir + "/node1/walletdump") + self.nodes[2].importwallet(tmpdir + "/node2/walletdump") + + sync_blocks(self.nodes) + + assert_equal(self.nodes[0].getbalance(), balance0backup) + assert_equal(self.nodes[1].getbalance(), balance1backup) + assert_equal(self.nodes[2].getbalance(), balance2backup) + + +if __name__ == '__main__': + WalletBackupTest().main() diff --git a/depend/zcash/qa/rpc-tests/zapwallettxes.py b/depend/zcash/qa/rpc-tests/zapwallettxes.py new file mode 100755 index 000000000..1f02234db --- /dev/null +++ b/depend/zcash/qa/rpc-tests/zapwallettxes.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +# Copyright (c) 2014-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://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, \ + start_nodes, start_node, connect_nodes_bi, bitcoind_processes + + +class ZapWalletTXesTest (BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.setup_clean_chain = True + self.num_nodes = 3 + + def setup_network(self, split=False): + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) + 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) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 40) + + txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5) + + tx0 = self.nodes[0].gettransaction(txid0) + assert_equal(tx0['txid'], txid0) # tx0 must be available (confirmed) + + tx1 = self.nodes[0].gettransaction(txid1) + assert_equal(tx1['txid'], txid1) # tx1 must be available (confirmed) + + tx2 = self.nodes[0].gettransaction(txid2) + assert_equal(tx2['txid'], txid2) # tx2 must be available (unconfirmed) + + tx3 = self.nodes[0].gettransaction(txid3) + assert_equal(tx3['txid'], txid3) # tx3 must be available (unconfirmed) + + # restart zcashd + self.nodes[0].stop() + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0,self.options.tmpdir) + + tx3 = self.nodes[0].gettransaction(txid3) + assert_equal(tx3['txid'], txid3) # tx must be available (unconfirmed) + + self.nodes[0].stop() + bitcoind_processes[0].wait() + + # restart zcashd with zapwallettxes + self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) + + aException = False + try: + tx3 = self.nodes[0].gettransaction(txid3) + except JSONRPCException as e: + print(e) + aException = True + + assert_equal(aException, True) # there must be an exception because the unconfirmed wallet tx0 must be gone by now + + tx0 = self.nodes[0].gettransaction(txid0) + assert_equal(tx0['txid'], txid0) # tx0 (confirmed) must still be available because it was confirmed + + +if __name__ == '__main__': + ZapWalletTXesTest().main() diff --git a/depend/zcash/qa/rpc-tests/zcjoinsplit.py b/depend/zcash/qa/rpc-tests/zcjoinsplit.py new file mode 100755 index 000000000..718c5102a --- /dev/null +++ b/depend/zcash/qa/rpc-tests/zcjoinsplit.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +# +# 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 __init__(self): + super().__init__() + self.num_nodes = 1 + + def setup_network(self): + self.nodes = [] + self.is_network_split = False + self.nodes.append(start_node(0, self.options.tmpdir, + ["-allowdeprecated=zcrawkeygen", "-allowdeprecated=zcrawjoinsplit", "-allowdeprecated=zcrawreceive"] + )) + + def run_test(self): + zckeypair = self.nodes[0].zcrawkeygen() + zcsecretkey = zckeypair["zcsecretkey"] + zcaddress = zckeypair["zcaddress"] + + (total_in, inputs) = gather_inputs(self.nodes[0], 40) + shield_tx = self.nodes[0].createrawtransaction(inputs, {}) + joinsplit_result = self.nodes[0].zcrawjoinsplit(shield_tx, {}, {zcaddress:39.99}, 39.99, 0) + + receive_result = self.nodes[0].zcrawreceive(zcsecretkey, joinsplit_result["encryptednote1"]) + assert_equal(receive_result["exists"], False) + + shield_tx = self.nodes[0].signrawtransaction(joinsplit_result["rawtxn"]) + self.nodes[0].sendrawtransaction(shield_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/depend/zcash/qa/rpc-tests/zcjoinsplitdoublespend.py b/depend/zcash/qa/rpc-tests/zcjoinsplitdoublespend.py new file mode 100755 index 000000000..3543ad10b --- /dev/null +++ b/depend/zcash/qa/rpc-tests/zcjoinsplitdoublespend.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 + +# +# 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, start_nodes, sync_blocks + +import time + +class JoinSplitTest(BitcoinTestFramework): + def setup_network(self): + # Start with split network: + return super(JoinSplitTest, self).setup_network(True) + + def setup_nodes(self): + return start_nodes(self.num_nodes, self.options.tmpdir, + extra_args = [["-allowdeprecated=zcrawjoinsplit", "-allowdeprecated=zcrawkeygen", "-allowdeprecated=zcrawreceive"]] * self.num_nodes) + + 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 ZEC: + 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() diff --git a/depend/zcash/qa/rpc-tests/zkey_import_export.py b/depend/zcash/qa/rpc-tests/zkey_import_export.py new file mode 100755 index 000000000..979d97b6e --- /dev/null +++ b/depend/zcash/qa/rpc-tests/zkey_import_export.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_greater_than, start_nodes,\ + initialize_chain_clean, connect_nodes_bi, wait_and_assert_operationid_status, \ + DEFAULT_FEE +from functools import reduce +import logging +import sys + +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout) + +fee = DEFAULT_FEE # constant (but can be changed within reason) + +class ZkeyImportExportTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 5) + + def setup_network(self, split=False): + self.nodes = start_nodes(5, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + connect_nodes_bi(self.nodes,0,4) + self.is_network_split=False + self.sync_all() + + def run_test(self): + [alice, bob, charlie, david, miner] = self.nodes + + # the sender loses 'amount' plus fee; to_addr receives exactly 'amount' + def z_send(from_node, from_addr, to_addr, amount): + global fee + + opid = from_node.z_sendmany(from_addr, + [{"address": to_addr, "amount": Decimal(amount)}], 1, int(fee)) + wait_and_assert_operationid_status(from_node, opid) + self.sync_all() + miner.generate(1) + self.sync_all() + + def verify_utxos(node, amts, zaddr): + amts.sort(reverse=True) + txs = node.z_listreceivedbyaddress(zaddr) + txs.sort(key=lambda x: x["amount"], reverse=True) + print("Sorted txs", txs) + print("amts", amts) + + try: + assert_equal(amts, [tx["amount"] for tx in txs]) + for tx in txs: + # make sure Sapling outputs exist and have valid values + assert_equal("outindex" in tx, True) + assert_greater_than(tx["outindex"], -1) + except AssertionError: + logging.error( + 'Expected amounts: %r; txs: %r', + amts, txs) + raise + + def get_private_balance(node): + balance = node.z_gettotalbalance() + return balance['private'] + + # Seed Alice with some funds + alice.generate(10) + self.sync_all() + miner.generate(100) + self.sync_all() + # Shield Alice's coinbase funds to her zaddr + alice_zaddr = alice.z_getnewaddress() + res = alice.z_shieldcoinbase("*", alice_zaddr) + wait_and_assert_operationid_status(alice, res['opid']) + self.sync_all() + miner.generate(1) + self.sync_all() + + # Now get a pristine z-address for receiving transfers: + bob_zaddr = bob.z_getnewaddress() + verify_utxos(bob, [], bob_zaddr) + # TODO: Verify that charlie doesn't have funds in addr + # verify_utxos(charlie, []) + + # the amounts of each txn embodied which generates a single UTXO: + amounts = list(map(Decimal, ['2.3', '3.7', '0.1', '0.5', '1.0', '0.19'])) + + # Internal test consistency assertion: + assert_greater_than( + Decimal(get_private_balance(alice)), + reduce(Decimal.__add__, amounts)) + + logging.info("Sending pre-export txns...") + for amount in amounts[0:2]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + logging.info("Exporting privkey from bob...") + bob_privkey = bob.z_exportkey(bob_zaddr) + + logging.info("Sending post-export txns...") + for amount in amounts[2:4]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + verify_utxos(bob, amounts[:4], bob_zaddr) + # verify_utxos(charlie, []) + + logging.info("Importing bob_privkey into charlie...") + # z_importkey rescan defaults to "whenkeyisnew", so should rescan here + ipk_zaddr = charlie.z_importkey(bob_privkey) + + # z_importkey should have rescanned for new key, so this should pass: + verify_utxos(charlie, amounts[:4], ipk_zaddr["address"]) + + # address is Sapling + assert_equal(ipk_zaddr["type"], "sapling") + + # Verify idempotent behavior: + ipk_zaddr2 = charlie.z_importkey(bob_privkey) + assert_equal(ipk_zaddr["address"], ipk_zaddr2["address"]) + + # amounts should be unchanged + verify_utxos(charlie, amounts[:4], ipk_zaddr2["address"]) + + logging.info("Sending post-import txns...") + for amount in amounts[4:]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + verify_utxos(bob, amounts, bob_zaddr) + verify_utxos(charlie, amounts, ipk_zaddr["address"]) + verify_utxos(charlie, amounts, ipk_zaddr2["address"]) + + # keep track of the fees incurred by bob (his sends) + bob_fee = Decimal("0") + + # Try to reproduce zombie balance reported in #1936 + # At generated zaddr, receive ZEC, and send ZEC back out. bob -> alice + for amount in amounts[:2]: + print("Sending amount from bob to alice: ", amount) + z_send(bob, bob_zaddr, alice_zaddr, amount) + bob_fee += fee + + bob_balance = sum(amounts[2:]) - int(bob_fee) + + assert_equal(bob.z_getbalance(bob_zaddr), bob_balance) + + # z_import onto new node "david" (blockchain rescan, default or True?) + d_ipk_zaddr = david.z_importkey(bob_privkey) + + # Check if amt bob spent is deducted for charlie and david + assert_equal(charlie.z_getbalance(ipk_zaddr["address"]), bob_balance) + assert_equal(david.z_getbalance(d_ipk_zaddr["address"]), bob_balance) + +if __name__ == '__main__': + ZkeyImportExportTest().main() diff --git a/depend/zcash/qa/rpc-tests/zmq_test.py b/depend/zcash/qa/rpc-tests/zmq_test.py new file mode 100755 index 000000000..c679bc8f7 --- /dev/null +++ b/depend/zcash/qa/rpc-tests/zmq_test.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Test ZMQ interface +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, bytes_to_hex_str, start_nodes + +import zmq +import struct + +class ZMQTest(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 4 + + port = 28332 + + def setup_nodes(self): + self.zmqContext = zmq.Context() + self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashblock") + self.zmqSubSocket.setsockopt(zmq.SUBSCRIBE, b"hashtx") + self.zmqSubSocket.connect("tcp://127.0.0.1:%i" % self.port) + return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[ + ['-zmqpubhashtx=tcp://127.0.0.1:'+str(self.port), '-zmqpubhashblock=tcp://127.0.0.1:'+str(self.port)], + [], + [], + [] + ]) + + def run_test(self): + self.sync_all() + + genhashes = self.nodes[0].generate(1) + self.sync_all() + + print("listen...") + msg = self.zmqSubSocket.recv_multipart() + topic = msg[0] + body = msg[1] + msgSequence = struct.unpack(' /dev/null 2>&1; +} + +if [[ $(id -u) != 0 ]]; then + export PATH=${PATH}:/sbin/:/usr/sbin/ +fi + +for command in cat awk sed sysctl uname mktemp openssl grep stat file find sort head ps readlink basename id which xargs; do + if ! (command_exists ${command}); then + >&2 echo -e "\e[31mWARNING: '${command}' not found! It's required for most checks.\e[0m" + commandsmissing=true + fi +done + +if [[ ${commandsmissing} == true ]]; then + >&2 echo -e "\n\e[31mWARNING: Not all necessary commands found. Some tests might not work!\e[0m\n" + sleep 2 +fi + +if (command_exists readelf); then + readelf="readelf -W" +elif (command_exists eu-readelf); then + readelf="eu-readelf -W" +elif (command_exists greadelf); then + readelf="greadelf -W" +else + echo -e "\n\e[31mERROR: readelf is a required tool for almost all tests. Aborting...\e[0m\n" + exit +fi + +sysarch=$(uname -m) +if [[ "${sysarch}" == "x86_64" ]]; then + arch="64" +elif [[ "${sysarch}" == "i?86" ]]; then + arch="32" +elif [[ "${sysarch}" =~ "arm" ]]; then + arch="arm" +elif [[ "${sysarch}" =~ "aarch64" ]]; then + arch="aarch64" +fi + +#openssl public key for verification of updates +read -r PUBKEY < /dev/null 2>&1 ; then + ${debug} && echo "fetching update via wget" + wget --no-check-certificate -O "${2}" "${1}" >/dev/null 2>&1 + elif type curl > /dev/null 2>&1 ; then + ${debug} && echo "fetching update via curl" + curl --insecure --remote-name -o "${2}" "${1}" >/dev/null 2>&1 + else + echo 'Warning: Neither wget nor curl is available. online updates unavailable' >&2 + exit 1 + fi +} + +# Version compare +vercomp() { + if [[ "${1}" == "${2}" ]] + then + return 0 + fi + local IFS=. + local i ver1="${1}" ver2="${2}" + # fill empty fields in ver1 with zeros + for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) + do + ver1[i]=0 + done + for ((i=0; i<${#ver1[@]}; i++)) + do + if [[ -z ${ver2[i]} ]] + then + # fill empty fields in ver2 with zeros + ver2[i]=0 + fi + if ((10#${ver1[i]} > 10#${ver2[i]})) + then + return 1 + fi + if ((10#${ver1[i]} < 10#${ver2[i]})) + then + return 2 + fi + done + return 0 +} + +# Update/Upgrade +# shellcheck disable=SC2120 +upgrade() { + if ${pkg_release}; then + printf "\033[31mError: Unknown option '%s'.\033[m\n\n" "${1}" + help + exit 1 + fi + umask 027 + TMP_FILE=$(mktemp /tmp/checksec.XXXXXXXXXX) + SIG_FILE=$(mktemp /tmp/checksec_sig.XXXXXXXX) + PUBKEY_FILE=$(mktemp /tmp/checksec_pubkey.XXXXXXXXXX) + fetch "${SCRIPT_URL}" "${TMP_FILE}" + fetch "${SIG_URL}" "${SIG_FILE}" + echo "${PUBKEY}" | base64 -d > "${PUBKEY_FILE}" + if ! openssl dgst -sha256 -verify "${PUBKEY_FILE}" -signature "${SIG_FILE}" "${TMP_FILE}" >/dev/null 2>&1; then + echo "file signature does not match. Update may be tampered" + rm -f "${TMP_FILE}" "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 + exit 1 + fi + UPDATE_VERSION=$(grep "^SCRIPT_VERSION" "${TMP_FILE}" | awk -F"=" '{ print $2 }') + if [[ "${SCRIPT_VERSION}" != "${UPDATE_VERSION}" ]]; then + PERMS=$(stat -c "%a" "$0") + rm -f "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 + mv "${TMP_FILE}" "$0" >/dev/null 2>&1 + exit_status=$? + if [[ "${exit_status}" -eq "0" ]]; then + echo "checksec.sh updated - Rev. ${UPDATE_VERSION}" + chmod "${PERMS}" "${0}" + else + echo "Error: Could not update... Please check permissions" + rm -f "${TMP_FILE}" >/dev/null 2>&1 + exit 1 + fi + else + echo "checksec.sh not updated... Already on latest version" + rm -f "${TMP_FILE}" "${SIG_FILE}" "${PUBKEY_FILE}" >/dev/null 2>&1 + exit 1 + fi + exit 0 +} + +# version information +version() { + echo "checksec v${SCRIPT_MAJOR}.${SCRIPT_MINOR}.${SCRIPT_REVISION}, Brian Davis, github.com/slimm609/checksec.sh, Dec 2015" + echo "Based off checksec v1.5, Tobias Klein, www.trapkit.de, November 2011" + echo +} + +# help +help() { + echo "Usage: checksec [--format={cli,csv,xml,json}] [OPTION]" + echo + echo + echo "Options:" + echo + echo " ## Checksec Options" + echo " --file={file}" + echo " --dir={directory}" + echo " --proc={process name}" + echo " --proc-all" + echo " --proc-libs={process ID}" + echo " --kernel[=kconfig]" + echo " --fortify-file={executable-file}" + echo " --fortify-proc={process ID}" + echo " --version" + echo " --help" + if ! ${pkg_release}; then + echo " --update or --upgrade" + fi + echo + echo " ## Modifiers" + echo " --debug" + echo " --verbose" + echo " --format={cli,csv,xml,json}" + echo " --output={cli,csv,xml,json}" + echo " --extended" + echo + echo "For more information, see:" + echo " https://github.com/slimm609/checksec.sh" + echo +} + +# format +format () { + list="cli csv xml json" + if [[ -n "${output_format}" ]]; then + if [[ ! ${list} =~ ${output_format} ]]; then + printf "\033[31mError: Please provide a valid format {cli, csv, xml, json}.\033[m\n\n" + exit 1 + fi + fi + if [[ "${output_format}" == "xml" ]]; then + echo '' + fi + format="${output_format}" +} + +#run help if nothing is passed +if [[ $# -lt 1 ]]; then + help + exit 1 +fi + +echo_message() { + if [[ ${format} == "csv" ]]; then + echo -n -e "$2" + elif [[ ${format} == "xml" ]]; then + echo -n -e "$3" + elif [[ ${format} == "json" ]]; then + echo -n -e "$4" + else #default to cli + echo -n -e "${1}" + fi +} + +# check selinux status +getsestatus() { + local status + ${debug} && echo -e "\n***function getsestatus" + if (command_exists getenforce); then + ${debug} && echo "***function getsestatus->getenforce" + sestatus=$(getenforce) + if [[ "${sestatus}" == "Disabled" ]]; then + status=0 + elif [[ "${sestatus}" == "Permissive" ]]; then + status=1 + elif [[ "${sestatus}" == "Enforcing" ]]; then + status=2 + fi + elif (command_exists sestatus); then + ${debug} && echo "***function getsestatus->sestatus" + sestatus=$(sestatus | grep "SELinux status" | awk '{ print $3}') + if [[ "${sestatus}" == "disabled" ]]; then + status=0 + elif [[ "${sestatus}" == "enabled" ]]; then + sestatus2=$(sestatus | grep "Current" | awk '{ print $3}') + if [[ "${sestatus2}" == "permissive" ]]; then + status=1 + elif [[ "${sestatus2}" == "enforcing" ]]; then + status=2 + fi + fi + fi +return ${status} +} + +# check if directory exists +dir_exists () { + ${debug} && echo "function dir_exists" + if [[ -d "${1}" ]] ; then + return 0 + else + return 1 + fi +} + +# check user privileges +root_privs () { + ${debug} && echo "***function root_privs" + if [[ $(/usr/bin/id -u) -eq 0 ]] ; then + return 0 + else + return 1 + fi +} + +# check if input is numeric +isNumeric () { + ${debug} && echo "***function isNumeric" + echo "$@" | grep -q -v "[^0-9]" +} + +# check if input is a string +isString () { + ${debug} && echo "***function isString" + echo "$@" | grep -q -v "[^ A-Z_a-z]" +} + +# check file(s) +filecheck() { + ${debug} && echo "***function filecheck" + # check for RELRO support + ${debug} && echo "***function filecheck->RELRO" + if ${readelf} -l "${1}" 2>/dev/null | grep -q 'GNU_RELRO'; then + if ${readelf} -d "${1}" 2>/dev/null | grep -q 'BIND_NOW'; then + echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' 'canary" + if ${readelf} -s "${1}" 2>/dev/null | grep -Eq '__stack_chk_fail|__intel_security_cookie'; then + echo_message '\033[32mCanary found \033[m ' 'Canary found,' ' canary="yes"' '"canary":"yes",' + else + echo_message '\033[31mNo canary found\033[m ' 'No Canary found,' ' canary="no"' '"canary":"no",' + fi + + # check for NX support + ${debug} && echo -e "\n***function filecheck->nx" + if ${readelf} -l "${1}" 2>/dev/null | grep -q 'GNU_STACK'; then + if ${readelf} -l "${1}" 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then + echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",' + else + echo_message '\033[32mNX enabled \033[m ' 'NX enabled,' ' nx="yes"' '"nx":"yes",' + fi + else + echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",' + fi + + # check for PIE support + ${debug} && echo -e "\n***function filecheck->pie" + if ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then + echo_message '\033[31mNo PIE \033[m ' 'No PIE,' ' pie="no"' '"pie":"no",' + elif ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then + if ${readelf} -d "${1}" 2>/dev/null | grep -q 'DEBUG'; then + echo_message '\033[32mPIE enabled \033[m ' 'PIE enabled,' ' pie="yes"' '"pie":"yes",' + else + echo_message '\033[33mDSO \033[m ' 'DSO,' ' pie="dso"' '"pie":"dso",' + fi + elif ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*REL'; then + echo_message '\033[33mREL \033[m ' 'REL,' ' pie="rel"' '"pie":"rel",' + else + echo_message '\033[33mNot an ELF file\033[m ' 'Not an ELF file,' ' pie="not_elf"' '"pie":"not_elf",' + fi + + if ${extended_checks}; then + # check for selfrando support + ${debug} && echo -e "\n***function filecheck->selfrando" + if ${readelf} -S "${1}" 2>/dev/null | grep -c txtrp | grep -q '1'; then + echo_message '\033[32mSelfrando enabled \033[m ' + else + echo_message '\033[31mNo Selfrando \033[m ' + fi + fi + + if ${extended_checks}; then + # check if compiled with Clang CFI + ${debug} && echo -e "\n***function filecheck->clangcfi" + #if $readelf -s "$1" 2>/dev/null | grep -Eq '\.cfi'; then + read -r cfifunc <<< "$($readelf -s "${1}" 2>/dev/null | grep .cfi | awk '{ print $8 }')" + func=${cfifunc/.cfi/} + if [ -n "$cfifunc" ] && $readelf -s "$1" 2>/dev/null | grep -q "$func$"; then + echo_message '\033[32mClang CFI found \033[m ' 'with CFI,' ' clangcfi="yes"' '"clangcfi":"yes",' + else + echo_message '\033[31mNo Clang CFI found\033[m ' 'without CFI,' ' clangcfi="no"' '"clangcfi":"no",' + fi + + # check if compiled with Clang SafeStack + ${debug} && echo -e "\n***function filecheck->safestack" + if $readelf -s "$1" 2>/dev/null | grep -Eq '__safestack_init'; then + echo_message '\033[32mSafeStack found \033[m ' 'with SafeStack,' ' safestack="yes"' '"safestack":"yes",' + else + echo_message '\033[31mNo SafeStack found\033[m ' 'without SafeStack,' ' safestack="no"' '"safestack":"no",' + fi + fi + + # check for rpath / run path + ${debug} && echo -e "\n***function filecheck->rpath" + # search for a line that matches RPATH and extract the colon-separated path list within brackets + # example input: "0x000000000000000f (RPATH) Library rpath: [/lib/systemd:/lib/apparmor]" + IFS=: read -r -a rpath_array <<< "$(${readelf} -d "${1}" 2>/dev/null | awk -F'[][]' '/RPATH/ {print $2}')" + if [[ "${#rpath_array[@]}" -gt 0 ]]; then + if xargs stat -c %A <<< "${rpath_array[*]}" 2>/dev/null | grep -q 'rw'; then + echo_message '\033[31mRW-RPATH \033[m ' 'RPATH,' ' rpath="yes"' '"rpath":"yes",' + else + echo_message '\033[31mRPATH \033[m ' 'RPATH,' ' rpath="yes"' '"rpath":"yes",' + fi + else + echo_message '\033[32mNo RPATH \033[m ' 'No RPATH,' ' rpath="no"' '"rpath":"no",' + fi + + ${debug} && echo -e "\n***function filecheck->runpath" + # search for a line that matches RUNPATH and extract the colon-separated path list within brackets + IFS=: read -r -a runpath_array <<< "$(${readelf} -d "${1}" 2>/dev/null | awk -F'[][]' '/RUNPATH/ {print $2}')" + if [[ "${#runpath_array[@]}" -gt 0 ]]; then + if xargs stat -c %A <<< "${runpath_array[*]}" 2>/dev/null | grep -q 'rw'; then + echo_message '\033[31mRW-RUNPATH \033[m ' 'RUNPATH,' ' runpath="yes"' '"runpath":"yes",' + else + echo_message '\033[31mRUNPATH \033[m ' 'RUNPATH,' ' runpath="yes"' '"runpath":"yes",' + fi + else + echo_message '\033[32mNo RUNPATH \033[m ' 'No RUNPATH,' ' runpath="no"' '"runpath":"no",' + fi + + # check for stripped symbols in the binary + IFS=" " read -r -a SYM_cnt <<< "$(${readelf} --symbols "${1}" 2>/dev/null | grep '\.symtab' | cut -d' ' -f5 | cut -d: -f1))" + if ${readelf} --symbols "${1}" 2>/dev/null | grep -q '\.symtab'; then + echo_message "\033[31m${SYM_cnt[0]} Symbols\t\033[m " 'Symbols,' ' symbols="yes"' '"symbols":"yes",' + else + echo_message '\033[32mNo Symbols\t\033[m ' 'No Symbols,' ' symbols="no"' '"symbols":"no",' + fi + + # check for FORTIFY SOURCE + ${debug} && echo "***function filecheck->fortify" + if [[ -e /lib/libc.so.6 ]] ; then + FS_libc=/lib/libc.so.6 + elif [[ -e /lib/libc.so.7 ]] ; then + FS_libc=/lib/libc.so.7 + elif [[ -e /lib/libc.so ]] ; then + FS_libc=/lib/libc.so + elif [[ -e /lib64/libc.so.6 ]] ; then + FS_libc=/lib64/libc.so.6 + elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/i386-linux-gnu/libc.so.6 + elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/x86_64-linux-gnu/libc.so.6 + elif [[ -e /lib/arm-linux-gnueabihf/libc.so.6 ]] ; then + FS_libc=/lib/arm-linux-gnueabihf/libc.so.6 + elif [[ -e /lib/aarch64-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/aarch64-linux-gnu/libc.so.6 + elif [[ -e /usr/x86_64-gentoo-linux-musl/bin/ld ]] ; then + FS_libc=/usr/x86_64-gentoo-linux-musl/bin/ld + else + printf "\033[31mError: libc not found.\033[m\n\n" + exit 1 + fi + + FS_chk_func_libc="$(${readelf} -s $FS_libc 2>/dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')" + FS_func_libc="${FS_chk_func_libc//_chk/}" + FS_functions="$(${readelf} --dyn-syms "${1}" 2>/dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d')" + FS_cnt_checked=$(grep -cFxf <(sort <<< "${FS_chk_func_libc}") <(sort <<< "${FS_functions}")) + FS_cnt_unchecked=$(grep -cFxf <(sort <<< "${FS_func_libc}") <(sort <<< "${FS_functions}")) + FS_cnt_total=$((FS_cnt_unchecked+FS_cnt_checked)) + + if grep -q '_chk$' <<<"$FS_functions"; then + echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' + else + echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' + fi + echo_message "\t${FS_cnt_checked}\t" "${FS_cnt_checked}", "fortified=\"${FS_cnt_checked}\" " "\"fortified\":\"${FS_cnt_checked}\"," + echo_message "\t${FS_cnt_total}\t\t" "${FS_cnt_total}" "fortify-able=\"${FS_cnt_total}\"" "\"fortify-able\":\"${FS_cnt_total}\"" +} + +# check process(es) +proccheck() { + ${debug} && echo -e "\n***function proccheck" + # check for RELRO support + ${debug} && echo "***function proccheck->RELRO" + if ${readelf} -l "${1}/exe" 2>/dev/null | grep -q 'Program Headers'; then + if ${readelf} -l "${1}/exe" 2>/dev/null | grep -q 'GNU_RELRO'; then + if ${readelf} -d "${1}/exe" 2>/dev/null | grep -q 'BIND_NOW'; then + echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' ' relro="full"' '"relro":"full",' + else + echo_message '\033[33mPartial RELRO\033[m ' 'Partial RELRO,' ' relro="partial"' '"relro":"partial",' + fi + else + echo_message '\033[31mNo RELRO \033[m ' 'No RELRO,' ' relro="no"' '"relro":"no",' + fi + else + echo -n -e '\033[31mPermission denied (please run as root)\033[m\n' + exit 1 + fi + + # check for stack canary support + ${debug} && echo -e "\n***function proccheck->canary" + if ${readelf} -s "${1}/exe" 2>/dev/null | grep -q 'Symbol table'; then + if ${readelf} -s "${1}/exe" 2>/dev/null | grep -Eq '__stack_chk_fail|__intel_security_cookie'; then + echo_message '\033[32mCanary found \033[m ' 'Canary found,' ' canary="yes"' '"canary":"yes",' + else + echo_message '\033[31mNo canary found \033[m ' 'No Canary found,' ' canary="no"' '"canary":"no",' + fi + else + if [[ "${1}" == "1" ]] ; then + echo_message '\033[33mPermission denied \033[m ' 'Permission denied,' ' canary="Permission denied"' '"canary":"Permission denied",' + else + echo_message '\033[33mNo symbol table found \033[m ' 'No symbol table found,' ' canary="No symbol table found"' '"canary":"No symbol table found",' + fi + fi + + if ${extended_checks}; then + # check if compiled with Clang CFI + $debug && echo -e "\n***function proccheck->clangcfi" + #if $readelf -s "$1" 2>/dev/null | grep -Eq '\.cfi'; then + read -r -a cfifunc <<< "$($readelf -s "$1/exe" 2>/dev/null | grep .cfi | awk '{ print $8 }')" + func=${cfifunc/.cfi/} + # TODO: fix this check properly, need more clang CFI files to be able to test properly + # shellcheck disable=SC2128 + if [ -n "$cfifunc" ] && $readelf -s "$1/exe" 2>/dev/null | grep -q "$func$"; then + echo_message '\033[32mClang CFI found \033[m ' 'with CFI,' ' clangcfi="yes"' '"clangcfi":"yes",' + else + echo_message '\033[31mNo Clang CFI found\033[m ' 'without CFI,' ' clangcfi="no"' '"clangcfi":"no",' + fi + + # check if compiled with Clang SafeStack + $debug && echo -e "\n***function proccheck->safestack" + if $readelf -s "$1/exe" 2>/dev/null | grep -Eq '__safestack_init'; then + echo_message '\033[32mSafeStack found \033[m ' 'with SafeStack,' ' safestack="yes"' '"safestack":"yes",' + else + echo_message '\033[31mNo SafeStack found\033[m ' 'without SafeStack,' ' safestack="no"' '"safestack":"no",' + fi + fi + + # check for Seccomp mode + ${debug} && echo -e "\n***function proccheck->Seccomp" + seccomp=$(grep 'Seccomp:' "${1}/status" 2> /dev/null | cut -b10) + if [[ "${seccomp}" == "1" ]] ; then + echo_message '\033[32mSeccomp strict\033[m ' 'Seccomp strict,' ' seccomp="strict"' '"seccomp":"strict",' + elif [[ "${seccomp}" == "2" ]] ; then + echo_message '\033[32mSeccomp-bpf \033[m ' 'Seccomp-bpf,' ' seccomp="bpf"' '"seccomp":"bpf",' + else + echo_message '\033[31mNo Seccomp \033[m ' 'No Seccomp,' ' seccomp="no"' '"seccomp":"no",' + fi + + # first check for PaX support + ${debug} && echo -e "\n***function proccheck->PAX" + if grep -q 'PaX:' "${1}/status" 2> /dev/null ; then + pageexec=$(grep 'PaX:' "${1}/status" 2> /dev/null | cut -b6) + segmexec=$(grep 'PaX:' "${1}/status" 2> /dev/null | cut -b10) + mprotect=$(grep 'PaX:' "${1}/status" 2> /dev/null | cut -b8) + randmmap=$(grep 'PaX:' "${1}/status" 2> /dev/null | cut -b9) + if [[ "${pageexec}" = "P" || "${segmexec}" = "S" ]] && [[ "${mprotect}" = "M" && "${randmmap}" = "R" ]] ; then + echo_message '\033[32mPaX enabled\033[m ' 'Pax enabled,' ' pax="yes"' '"pax":"yes",' + elif [[ "${pageexec}" = "p" && "${segmexec}" = "s" && "${randmmap}" = "R" ]] ; then + echo_message '\033[33mPaX ASLR only\033[m ' 'Pax ASLR only,' ' pax="aslr_only"' '"pax":"aslr_only",' + elif [[ "${pageexec}" = "P" || "${segmexec}" = "S" ]] && [[ "${mprotect}" = "m" && "${randmmap}" = "R" ]] ; then + echo_message '\033[33mPaX mprot off \033[m' 'Pax mprot off,' ' pax="mprot_off"' '"pax":"mprot_off",' + elif [[ "${pageexec}" = "P" || "${segmexec}" = "S" ]] && [[ "${mprotect}" = "M" && "${randmmap}" = "r" ]] ; then + echo_message '\033[33mPaX ASLR off\033[m ' 'Pax ASLR off,' ' pax="aslr_off"' '"pax":"aslr_off",' + elif [[ "${pageexec}" = "P" || "${segmexec}" = "S" ]] && [[ "${mprotect}" = "m" && "${randmmap}" = "r" ]] ; then + echo_message '\033[33mPaX NX only\033[m ' 'Pax NX only,' ' pax="nx_only"' '"pax":"nx_only",' + else + echo_message '\033[31mPaX disabled\033[m ' 'Pax disabled,' ' pax="no"' '"pax":"no",' + fi + # fallback check for NX support + ${debug} && echo -e "\n***function proccheck->NX" + elif ${readelf} -l "${1}/exe" 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then + echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",' + else + echo_message '\033[32mNX enabled \033[m ' 'NX enabled,' ' pax="yes"' '"nx":"yes",' + fi + + # check for PIE support + ${debug} && echo -e "\n***function proccheck->PIE" + if ${readelf} -h "${1}/exe" 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then + echo_message '\033[31mNo PIE \033[m ' 'No PIE,' ' pie="no"' '"pie":"no",' + elif ${readelf} -h "${1}/exe" 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then + if ${readelf} -d "${1}/exe" 2>/dev/null | grep -q 'DEBUG'; then + echo_message '\033[32mPIE enabled \033[m ' 'PIE enabled,' ' pie="yes"' '"pie":"yes",' + else + echo_message '\033[33mDynamic Shared Object\033[m ' 'Dynamic Shared Object,' ' pie="dso"' '"pie":"dso",' + fi + else + echo_message '\033[33mNot an ELF file \033[m ' 'Not an ELF file,' ' pie="not_elf"' '"pie":"not_elf",' + fi + + if ${extended_checks}; then + # check for selfrando support + ${debug} && echo -e "\n***function proccheck->selfrando" + if ${readelf} -S "${1}/exe" 2>/dev/null | grep -c txtrp | grep -q '1'; then + echo_message '\033[32mSelfrando enabled \033[m ' + else + echo_message '\033[31mNo Selfrando \033[m ' + fi + fi + + #check for forifty source support + FS_functions="$(${readelf} -s "${1}/exe" 2>/dev/null | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//')" + if grep -q '_chk$' <<<"$FS_functions"; then + echo_message '\033[32mYes\033[m' 'Yes' " fortify_source='yes'>" '"fortify_source":"yes" }' + else + echo_message "\033[31mNo\033[m" "No" " fortify_source='no'>" '"fortify_source":"no" }' + fi +} + +# check mapped libraries +libcheck() { + ${debug} && echo "***function libcheck" + IFS=" " read -r -a libs <<< "$(awk '{ print $6 }' "/proc/${1}/maps" | grep '/' | sort -u | xargs file | grep ELF | awk '{ print $1 }' | sed 's/:/ /')" + echo_message "\n* Loaded libraries (file information, # of mapped files: ${#libs[@]}):\n\n" "" "" "\"libs\": {" + + for ((element=0; element<${#libs[@]}; element++)) + do + echo_message " ${libs[$element]}:\n" "${libs[$element]}," "" "" + echo_message " " "" " " "" + filecheck "${libs[$element]}" + if [[ ${element} == $((${#libs[@]} - 1)) ]]; then + echo_message "\n\n" "\n" " filename='${libs[$element]}' />\n" "" + else + echo_message "\n\n" "\n" " filename='${libs[$element]}' />\n" "}," + fi + done +} + +# check for system-wide ASLR support +aslrcheck() { + ${debug} && echo "***function aslrcheck" + # PaX ASLR support + ${debug} && echo -e "\n***function aslrcheck->PAX ASLR" + if ! (grep -q 'Name:' /proc/1/status 2> /dev/null) ; then + echo_message '\033[33m insufficient privileges for PaX ASLR checks\033[m\n' '' '' '' + echo_message ' Fallback to standard Linux ASLR check' '' '' '' + fi + + if grep -q 'PaX:' /proc/1/status 2> /dev/null; then + if grep -q 'PaX:' /proc/1/status 2> /dev/null | grep -q 'R'; then + echo_message '\033[32mPaX ASLR enabled\033[m\n\n' '' '' '' + else + echo_message '\033[31mPaX ASLR disabled\033[m\n\n' '' '' '' + fi + else + ${debug} && echo -e "\n***function aslrcheck->randomize_va_space" + # standard Linux 'kernel.randomize_va_space' ASLR support + # (see the kernel file 'Documentation/sysctl/kernel.txt' for a detailed description) + echo_message " (kernel.randomize_va_space): " '' '' '' + if sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 1'; then + echo_message '\033[33mPartial (Setting: 1)\033[m\n\n' '' '' '' + echo_message " Description - Make the addresses of mmap base, stack and VDSO page randomized.\n" '' '' '' + echo_message " This, among other things, implies that shared libraries will be loaded to \n" '' '' '' + echo_message " random addresses. Also for PIE-linked binaries, the location of code start\n" '' '' '' + echo_message " is randomized. Heap addresses are *not* randomized.\n\n" '' '' '' + elif sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 2'; then + echo_message '\033[32mFull (Setting: 2)\033[m\n\n' '' '' '' + echo_message " Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.\n" '' '' '' + echo_message " This, among other things, implies that shared libraries will be loaded to random \n" '' '' '' + echo_message " addresses. Also for PIE-linked binaries, the location of code start is randomized.\n\n" '' '' '' + elif sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 0'; then + echo_message '\033[31mNone (Setting: 0)\033[m\n' '' '' '' + else + echo_message '\033[31mNot supported\033[m\n' '' '' '' + fi + echo_message " See the kernel file 'Documentation/sysctl/kernel.txt' for more details.\n\n" '' '' '' + fi +} + +# check cpu nx flag +nxcheck() { + ${debug} && echo -e "\n***function nxcheck" + if grep -qFw nx /proc/cpuinfo; then + echo_message '\033[32mYes\033[m\n\n' '' '' '' + else + echo_message '\033[31mNo\033[m\n\n' '' '' '' + fi +} + +#Check core dumps restricted? +coredumpcheck() { + ${debug} && echo -e "\n***function coredumpcheck" + coreValue=$(grep -Exic "hard[[:blank:]]+core[[:blank:]]+0" /etc/security/limits.conf) + coreValueDefault=$(grep -Exic "\*[[:blank:]]+hard[[:blank:]]+core[[:blank:]]+0" /etc/security/limits.conf) + dumpableValue=$(sysctl -b -e fs.suid_dumpable) + if { [[ "${coreValue}" == 1 ]] || [[ "${coreValueDefault}" == 1 ]]; } && { [[ "${dumpableValue}" == 0 ]] || [[ "${dumpableValue}" == 2 ]]; }; then + echo_message '\033[32mRestricted\033[m\n\n' '' '' '' + else + echo_message '\033[31mNot Restricted\033[m\n\n' '' '' '' + fi +} + +# check for kernel protection mechanisms +kernelcheck() { + ${debug} && echo "***function kernelcheck" + echo_message " Description - List the status of kernel protection mechanisms. Rather than\n" '' '' '' + echo_message " inspect kernel mechanisms that may aid in the prevention of exploitation of\n" '' '' '' + echo_message " userspace processes, this option lists the status of kernel configuration\n" '' '' '' + echo_message " options that harden the kernel itself against attack.\n\n" '' '' '' + echo_message " Kernel config:\n" '' '' '{ "kernel": ' + + if [[ ! "${1}" == "" ]] ; then + kconfig="cat ${1}" + echo_message " Warning: The config ${1} on disk may not represent running kernel config!\n\n" "${1}" "" '{ "KernelConfig":"not_found" } }' + exit 0 + fi + ${debug} && ${kconfig} | grep "CONFIG_GRKERNSEC" + ${debug} && ${kconfig} | grep "CONFIG_PAX" + + echo_message " Vanilla Kernel ASLR: " "" "" "" + randomize_va=$(sysctl -b -e kernel.randomize_va_space) + if [[ "x${randomize_va}" == "x2" ]]; then + echo_message "\033[32mFull\033[m\n" "Full," " randomize_va_space='full'" ', "randomize_va_space":"full"' + elif [[ "x${randomize_va}" == "x1" ]]; then + echo_message "\033[33mPartial\033[m\n" "Partial," " randomize_va_space='partial'" ', "randomize_va_space":"partial"' + else + echo_message "\033[31mNone\033[m\n" "None," " randomize_va_space='none'" ', "randomize_va_space":"none"' + fi + + echo_message " NX protection: " "" "" "" + if (command_exists dmesg) && (root_privs); then + nx_protection=$(dmesg -t 2>/dev/null | grep -Fw NX) + if [[ "x${nx_protection}" == "xNX (Execute Disable) protection: active" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " nx_protection='yes'" ', "nx_protection":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " nx_protection='no'" ', "nx_protection":"no"' + fi + else + echo_message "\033[33mSkipped\033[m\n" "Skipped," " nx_protection='skipped'" ', "nx_protection":"skipped"' + fi + + echo_message " Protected symlinks: " "" "" "" + symlink=$(sysctl -b -e fs.protected_symlinks) + if [[ "x${symlink}" == "x1" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_symlinks='yes'" ', "protect_symlinks":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_symlinks='no'" ', "protect_symlinks":"no"' + fi + + echo_message " Protected hardlinks: " "" "" "" + hardlink=$(sysctl -b -e fs.protected_hardlinks) + if [[ "x${hardlink}" == "x1" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_hardlinks='yes'" ', "protect_hardlinks":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_hardlinks='no'" ', "protect_hardlinks":"no"' + fi + + echo_message " Protected fifos: " "" "" "" + fifos=$(sysctl -b -e fs.protected_fifos) + if [[ "x${fifos}" == "x" ]]; then + echo_message "\033[33mUnsupported\033[m\n" "Unsupported," " protect_fifos='unsupported'" ', "protect_fifos":"unsupported"' + elif [[ "x${fifos}" == "x2" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_fifos='yes'" ', "protect_fifos":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_fifos='no'" ', "protect_fifos":"no"' + fi + + echo_message " Protected regular: " "" "" "" + regular=$(sysctl -b -e fs.protected_regular) + if [[ "x${regular}" == "x" ]]; then + echo_message "\033[33mUnsupported\033[m\n" "Unsupported," " protect_regular='unsupported'" ', "protect_regular":"unsupported"' + elif [[ "x${regular}" == "x2" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " protect_regular='yes'" ', "protect_regular":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " protect_regular='no'" ', "protect_regular":"no"' + fi + + echo_message " Ipv4 reverse path filtering: " "" "" "" + ipv4_rpath=$(sysctl -b -e net.ipv4.conf.all.rp_filter) + if [[ "x${ipv4_rpath}" == "x1" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " ipv4_rpath='yes'" ', "ipv4_rpath":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " ipv4_rpath='no'" ', "ipv4_rpath":"no"' + fi + + echo_message " Kernel heap randomization: " "" "" "" + # NOTE: y means it turns off kernel heap randomization for backwards compatibility (libc5) + if ${kconfig} | grep -qi 'CONFIG_COMPAT_BRK=y'; then + echo_message "\033[31mDisabled\033[m\n" "Disabled," " kernel_heap_randomization='no'" ', "kernel_heap_randomization":"no"' + else + echo_message "\033[32mEnabled\033[m\n" "Enabled," " kernel_heap_randomization='yes'" ', "kernel_heap_randomization":"yes"' + fi + + if ${kconfig} | grep -qi 'CONFIG_CC_STACKPROTECTOR' || ${kconfig} | grep -qa 'CONFIG_STACKPROTECTOR'; then + echo_message " GCC stack protector support: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_CC_STACKPROTECTOR=y' || ${kconfig} | grep -qi 'CONFIG_STACKPROTECTOR=y' ; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_stack_protector='yes'" ', "gcc_stack_protector":"yes"' + + if ${kconfig} | grep -qi 'CONFIG_CC_STACKPROTECTOR_STRONG' || ${kconfig} | grep -qi 'CONFIG_STACKPROTECTOR_STRONG'; then + echo_message " GCC stack protector strong: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_CC_STACKPROTECTOR_STRONG=y' || ${kconfig} | grep -qi 'CONFIG_STACKPROTECTOR_STRONG=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_stack_protector_strong='yes'" ', "gcc_stack_protector_strong":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " gcc_stack_protector_strong='no'" ', "gcc_stack_protector_strong":"no"' + fi + fi + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " gcc_stack_protector='no'" ', "gcc_stack_protector":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_GCC_PLUGIN_STRUCTLEAK'; then + echo_message " GCC structleak plugin: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_GCC_PLUGIN_STRUCTLEAK=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_structleak='yes'" ', "gcc_structleak":"yes"' + echo_message " GCC structleak by ref plugin: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_structleak_byref='yes'" ', "gcc_structleak_byref":"yes"' + else + echo_message "\033[32mEnabled\033[m\n" "Enabled," " gcc_structleak_byref='no'" ', "gcc_structleak_byref":"no"' + fi + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " gcc_structleak='no'" ', "gcc_structleak":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_SLAB_FREELIST_RANDOM'; then + echo_message " SLAB freelist randomization: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_SLAB_FREELIST_RANDOM=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " slab_freelist_randomization='yes'" ', "slab_freelist_randomization":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " slab_freelist_randomization='no'" ', "slab_freelist_randomization":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CPU_SW_DOMAIN_PAN=y'; then + echo_message " Use CPU domains: " "" "" "" + if ${kconfig} | grep -qi 'CPU_SW_DOMAIN_PAN=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " cpu_sw_domain'yes'" ', "cpu_sw_domain":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " cpu_sw_domain='no'" ', "cpu_sw_domain":"no"' + fi + fi + + + if ${kconfig} | grep -qi 'CONFIG_VMAP_STACK'; then + echo_message " Virtually-mapped kernel stack: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_VMAP_STACK=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " virtually_mapped_stack='yes'" ', "virtually_mapped_stack":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " virtually_mapped_stack='no'" ', "virtually_mapped_stack":"no"' + fi + fi + + + if ${kconfig} | grep -qi 'CONFIG_DEVMEM'; then + if ${kconfig} | grep -qi 'CONFIG_DEVMEM=y'; then + echo_message " Restrict /dev/mem access: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_STRICT_DEVMEM=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " restrict_dev_mem_access='yes'" ', "restrict_dev_mem_access":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " restrict_dev_mem_access='no'" ', "restrict_dev_mem_access":"no"' + fi + + echo_message " Restrict I/O access to /dev/mem: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_IO_STRICT_DEVMEM=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " restrict_io_dev_mem_access='yes'" ', "restrict_io_dev_mem_access":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " restrict_io_dev_mem_access='no'" ', "restrict_io_dev_mem_access":"no"' + fi + fi + fi + + + if ! ${kconfig} | grep -qi 'CONFIG_PAX'; then + if ${kconfig} | grep -qi 'CONFIG_DEBUG_RODATA' || ${kconfig} | grep -qi '|CONFIG_STRICT_KERNEL_RWX'; then + echo_message " Enforce read-only kernel data: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_DEBUG_RODATA=y\|CONFIG_STRICT_KERNEL_RWX=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " ro_kernel_data='yes'" ', "ro_kernel_data":"yes"' + echo_message " Enforce read-only module data: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_STRICT_MODULE_RWX=y\|CONFIG_DEBUG_SET_MODULE_RONX'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " ro_module_data='yes'" ', "ro_module_data":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " ro_module_data='no'" ', "ro_module_data":"no"' + fi + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " ro_kernel_data='no'" ', "ro_kernel_data":"no"' + fi + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_REFCOUNT_FULL'; then + echo_message " Full reference count validation: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_REFCOUNT_FULL=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " full_refcount_validation='yes'" ', "full_refcount_validation":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " full_refcount_validation='no'" ', "full_refcount_validation":"no"' + fi + fi + + echo_message " Exec Shield: " """" "" + execshield=$(sysctl -b -e kernel.exec-shield) + if [[ "x${execshield}" == "x" ]]; then + echo_message '\033[32mUnsupported\033[m\n\n' '' '' '' + elif [[ "x${execshield}" == "x1" ]]; then + echo_message '\033[32mEnabled\033[m\n\n' '' '' '' + else + echo_message '\033[31mDisabled\033[m\n\n' '' '' '' + fi + + if ${kconfig} | grep -qi 'CONFIG_HARDENED_USERCOPY'; then + echo_message " Hardened Usercopy: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_HARDENED_USERCOPY=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " hardened_usercopy='yes'" ', "hardened_usercopy":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " hardened_usercopy='no'" ', "hardened_usercopy":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_FORTIFY_SOURCE'; then + echo_message " Harden str/mem functions: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_FORTIFY_SOURCE=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " fortify_source='yes'" ', "fortify_source":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " fortify_source='no'" ', "fortify_source":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_DEVKMEM'; then + echo_message " Restrict /dev/kmem access: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_DEVKMEM=y'; then + echo_message "\033[31mDisabled\033[m\n" "Disabled," " restrict_dev_kmem_access='no'" ', "restrict_dev_kmem_access":"no"' + else + echo_message "\033[32mEnabled\033[m\n" "Enabled," " restrict_dev_kmem_access='yes'" ', "restrict_dev_kmem_access":"yes"' + fi + fi + + #x86 only + if [[ "${arch}" == "32" ]] || [[ "${arch}" == "64" ]]; then + echo_message "\n" "\n" "" "" + echo_message "* X86 only: \n" "" "" "" + + if ! ${kconfig} | grep -qi 'CONFIG_PAX_SIZE_OVERFLOW=y'; then + if ${kconfig} | grep -qi 'CONFIG_DEBUG_STRICT_USER_COPY_CHECKS'; then + echo_message " Strict user copy checks: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " strict_user_copy_check='yes'" ', "strict_user_copy_check":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " strict_user_copy_check='no'" ', "strict_user_copy_check":"no"' + fi + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_BASE' || ${kconfig} | grep -qi 'CONFIG_PAX_ASLR'; then + echo_message " Address space layout randomization: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_BASE=y' || ${kconfig} | grep -qi 'CONFIG_PAX_ASLR=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " random_address_space_layout='yes'" ', "random_address_space_layout":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " random_address_space_layout='no'" ', "random_address_space_layout":"no"' + fi + fi + fi + + #ARM only + if [[ "${arch}" == "arm" ]]; then + echo_message "\n" "\n" "\n" "" + echo_message "* ARM only: \n" "" "" "" + + if ${kconfig} | grep -qi 'CONFIG_ARM_KERNMEM_PERMS'; then + echo_message " Restrict kernel memory permissions: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_ARM_KERNMEM_PERMS=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " arm_kernmem_perms='yes'" ', "arm_kernmem_perms":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " arm_kernmem_perms='no'" ', "arm_kernmem_perms":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_DEBUG_ALIGN_RODATA'; then + echo_message " Make rodata strictly non-excutable: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_DEBUG_ALIGN_RODATA=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " arm_strict_rodata='yes'" ', "arm_strict_rodata":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " arm_strict_rodata='no'" ', "arm_strict_rodata":"no"' + fi + fi + + fi + + #ARM64 only + if [[ "${arch}" == "aarch64" ]]; then + echo_message "\n" "\n" "\n" "" + echo_message "* ARM64 only: \n" "" "" "" + + if ${kconfig} | grep -qi 'CONFIG_UNMAP_KERNEL_AT_EL0'; then + echo_message " Unmap kernel in userspace (KAISER): " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_UNMAP_KERNEL_AT_EL0=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " unmap_kernel_in_userspace='yes'" ', "unmap_kernel_in_userspace":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " unmap_kernel_in_userspace='no'" ', "unmap_kernel_in_userspace":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_HARDEN_BRANCH_PREDICTOR'; then + echo_message " Harden branch predictor: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_HARDEN_BRANCH_PREDICTOR=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " harden_branch_predictor='yes'" ', "harden_branch_predictor":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " harden_branch_predictor='no'" ', "harden_branch_predictor":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_HARDEN_EL2_VECTORS'; then + echo_message " Harden EL2 vector mapping: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_HARDEN_EL2_VECTORS=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " harden_el2_vector_mapping='yes'" ', "harden_el2_vector_mapping":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " harden_el2_vector_mapping='no'" ', "harden_el2_vector_mapping":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_ARM64_SSBD'; then + echo_message " Speculative store bypass disable: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_ARM64_SSBD=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " speculative_store_bypass_disable='yes'" ', "speculative_store_bypass_disable":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " speculative_store_bypass_disable='no'" ', "speculative_store_bypass_disable":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_ARM64_SW_TTBR0_PAN'; then + echo_message " Emulate privileged access never: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_ARM64_SW_TTBR0_PAN=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " emulate_privileged_access_never='yes'" ', "emulate_privileged_access_never":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " emulate_privileged_access_never='no'" ', "emulate_privileged_access_never":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_BASE'; then + echo_message " Randomize address of kernel image: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_BASE=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " randomize_kernel_address='yes'" ', "randomize_kernel_address":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " randomize_kernel_address='no'" ', "randomize_kernel_address":"no"' + fi + fi + + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_MODULE_REGION_FULL'; then + echo_message " Randomize module region over 4GB: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_RANDOMIZE_MODULE_REGION_FULL=y'; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " randomize_module_region_full='yes'" ', "randomize_module_region_full":"yes"' + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " randomize_module_region_full='no'" ', "randomize_module_region_full":"no"' + fi + fi + fi + + echo_message "" "" ">" "}," + + + echo_message "\n" "\n" "\n" "" + echo_message "* SELinux: " "" "" "" + if ${kconfig} | grep -qi 'CONFIG_SECURITY_SELINUX=y'; then + getsestatus + sestatus=$? + if [[ ${sestatus} == 0 ]]; then + echo_message "\033[31mDisabled\033[m\n" "Disabled,," " \n" " }" + echo_message "* grsecurity / PaX: " "" "" "" + + if ${kconfig} | grep -qi 'CONFIG_GRKERNSEC=y'; then + if ${kconfig} | grep -qi 'CONFIG_GRKERNSEC_HIGH=y'; then + echo_message "\033[32mHigh GRKERNSEC\033[m\n\n" "High GRKERNSEC," " /dev/null || echo $?) + if [[ "x${grcheck}" != "x255" ]] && [[ "x${grcheck}" != "x0" ]]; then + echo_message "\033[32mEnabled\033[m\n" "Enabled," " grsec_sysctl_${command}='yes'" ", \"grsec_sysctl_${command}\":\"yes\"" + else + echo_message "\033[31mDisabled\033[m\n" "Disabled," " grsec_sysctl_${command}='no'" ", \"grsec_sysctl_${command}\":\"no\"" + fi + if [[ "${command}" == "tpe_restrict_all" ]]; then + echo_message "" "" "" " } }" + else + echo_message "" "" "" "" + fi + done + echo_message "" "" " />\n\n" "" + fi + else + echo_message "\033[31mNo GRKERNSEC\033[m\n\n" "No GRKERNSEC,,,,,,,," " \n\n" ', "grsecurity": { "grsecurity_config":"no" } }' + echo_message " The grsecurity / PaX patchset is available here:\n" "" "" "" + echo_message " https://grsecurity.net/\n" "" "" "" + fi +} + +# --- FORTIFY_SOURCE subfunctions (start) --- +# is FORTIFY_SOURCE supported by libc? +FS_libc_check() { + ${debug} && echo "***function FS_libc_check" + echo_message "* FORTIFY_SOURCE support available (libc) : " "" "" + + if [[ "${#FS_chk_func_libc[@]}" != "0" ]] ; then + echo_message "\033[32mYes\033[m\n" "Yes," " libc_fortify_source='yes' " ', "libc_fortify_source":"yes"' + else + echo_message "\033[31mNo\033[m\n" "No," " libc_fortify_source='no' " ', "libc_fortify_source":"no"' + exit 1 + fi +} + +# was the binary compiled with FORTIFY_SOURCE? +FS_binary_check() { + ${debug} && echo "***function FS_binary_check" + echo_message "* Binary compiled with FORTIFY_SOURCE support: " "" "" "" + + for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) + do + if [[ ${FS_functions[$FS_elem_functions]} =~ _chk$ ]] ; then + echo_message "\033[32mYes\033[m\n" "Yes\n" " binary_compiled_with_fortify='yes'>\n" ', "binary_compiled_with_fortify":"yes"' + return + fi + done + echo_message "\033[31mNo\033[m\n" "No\n" " binary_compiled_with_fortify='no'>\n" ', "binary_compiled_with_fortify":"no"' + exit 1 +} + +FS_comparison() { + ${debug} && echo "***function FS_comparison" + echo_message "\n" "" "" + echo_message " ------ EXECUTABLE-FILE ------- . -------- LIBC --------\n" "" "" "" + echo_message " Fortifiable library functions | Checked function names\n" "" "" "" + echo_message " -------------------------------------------------------\n" "" "" "" + + ${debug} && echo -e "\n***function FS_comparison->FS_elem_libc" + for ((FS_elem_libc=0; FS_elem_libc<${#FS_chk_func_libc[@]}; FS_elem_libc++)) + do + ${debug} && echo -e "\n***function FS_comparison->FS_elem_libc->FS_elem_functions" + for ((FS_elem_functions=0; FS_elem_functions<${#FS_functions[@]}; FS_elem_functions++)) + do + FS_tmp_func=${FS_functions[$FS_elem_functions]} + FS_tmp_libc=${FS_chk_func_libc[$FS_elem_libc]} + + if [[ ${FS_tmp_func} =~ ^${FS_tmp_libc}$ ]] ; then + if [[ ${format} == "cli" ]]; then + printf " \033[31m%-30s\033[m | __%s%s\n" "${FS_tmp_func}" "${FS_tmp_libc}" "${FS_end}" + else + if [[ $FS_elem_functions == 0 ]]; then + echo_message "" "${FS_tmp_func},${FS_tmp_libc},yes\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"yes\" }" + elif [[ $FS_elem_functions == $((${#FS_functions[@]} - 1 )) ]]; then + echo_message "" "${FS_tmp_func},${FS_tmp_libc},yes\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"yes\" }" + else + echo_message "" "${FS_tmp_func},${FS_tmp_libc},yes\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"yes\" }" + fi + fi + (( FS_cnt_total++ )) + (( FS_cnt_unchecked++ )) + elif [[ ${FS_tmp_func} =~ ^${FS_tmp_libc}(_chk)$ ]] ; then + if [[ ${format} == "cli" ]]; then + printf " \033[32m%-30s\033[m | __%s%s\n" "${FS_tmp_func}" "${FS_tmp_libc}" "${FS_end}" + else + if [[ $FS_elem_functions == 0 ]]; then + echo_message "" "${FS_tmp_func},${FS_tmp_libc},no\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"no\" }" + elif [[ $FS_elem_functions == $((${#FS_functions[@]} - 1 )) ]]; then + echo_message "" "${FS_tmp_func},${FS_tmp_libc},no\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"no\" }" + else + echo_message "" "${FS_tmp_func},${FS_tmp_libc},no\n" " \n" ", \"function\": { \"name\":\"${FS_tmp_func}\", \"libc\":\"${FS_tmp_libc}\", \"fortifiable\":\"no\" }" + fi + fi + (( FS_cnt_total++ )) + (( FS_cnt_checked++ )) + fi + + done + done +} + +FS_summary() { + ${debug} && echo "***function FS_summary" + echo_message "\n" "" "\n" "" + echo_message "SUMMARY:\n\n" "" "" "" + echo_message "* Number of checked functions in libc : ${#FS_chk_func_libc[@]}\n" "${#FS_chk_func_libc[@]}," " " ", \"nb_unchecked_func\":\"${FS_cnt_unchecked}\" } " + echo_message "\n" "\n" "\n" "" +} + +debug_report() { + echo "***** Checksec debug *****" + failed=false + id + uname -a + + echo "checksec version: ${SCRIPT_MAJOR}.${SCRIPT_MINOR}.${SCRIPT_REVISION} -- ${SCRIPT_VERSION}" + + if [[ -f /etc/os-release ]]; then + # freedesktop.org and systemd + # shellcheck disable=SC1091 + source /etc/os-release + # shellcheck disable=SC2153 + OS=${NAME} + VER=${VERSION_ID} + elif type lsb_release >/dev/null 2>&1; then + # linuxbase.org + OS=$(lsb_release -si) + VER=$(lsb_release -sr) + elif [[ -f /etc/lsb-release ]]; then + # For some versions of Debian/Ubuntu without lsb_release command + # shellcheck disable=SC1091 + source /etc/lsb-release + OS=${DISTRIB_ID} + VER=${DISTRIB_RELEASE} + elif [[ -f /etc/debian_version ]]; then + # Older Debian/Ubuntu/etc. + OS=Debian + VER=$(cat /etc/debian_version) + elif [[ -f /etc/SuSe-release ]]; then + # Older SuSE/etc. + OS=$(cat /etc/SuSe-release) + VER=$(uname -r) + elif [[ -f /etc/redhat-release ]]; then + # Older Red Hat, CentOS, etc. + OS=$(cat /etc/redhat-release) + VER=$(uname -r) + else + # Fall back to uname, e.g. "Linux ", also works for BSD, etc. + OS=$(uname -s) + VER=$(uname -r) + fi + + echo "OS=${OS}" + echo "VER=${VER}" + + for command in cat awk sysctl uname mktemp openssl grep stat file find head ps readlink basename id which wget curl readelf eu-readelf; do + path="$(command -v ${command})" + if [[ -e "${path}" ]]; then + ls -l "${path}" + if [[ -L "${path}" ]]; then + absolutepath=$(readlink -f "${path}") + ls -l "${absolutepath}" + file "${absolutepath}" + else + file "${path}" + fi + else + echo "*** can not find command ${command}" + failed=true + fi + done + + if [[ ${failed} ]]; then + exit 1 + fi +} + +chk_dir () { + if [[ -z "${CHK_DIR}" ]] ; then + printf "\033[31mError: Please provide a valid directory.\033[m\n\n" + exit 1 + fi + # remove trailing slashes + tempdir=$(echo "${CHK_DIR}" | sed -e "s/\/*$//") + if [[ ! -d "${tempdir}" ]] ; then + printf "\033[31mError: The directory '%s' does not exist.\033[m\n\n" "${tempdir}" + exit 1 + fi + if ${extended_checks}; then + echo_message "RELRO STACK CANARY NX PIE SELFRANDO Clang CFI SafeStack RPATH RUNPATH Symbols \tFORTIFY\tFortified\tFortifiable Filename\n" '' "\n" "{ \"dir\": { \"name\":\"$tempdir\" }" + else + echo_message "RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols \tFORTIFY\tFortified\tFortifiable Filename\n" '' "\n" "{ \"dir\": { \"name\":\"$tempdir\" }" + fi + fdircount=0 + fdirtotal=0 + + while read -r N; do + if [[ "${N}" != "[A-Za-z1-0]*" ]]; then + out=$(file "$(readlink -f "${N}")") + if [[ ${out} =~ ELF ]] ; then + (( fdirtotal++ )) + fi + fi + done < <(find "${tempdir}" -type f 2>/dev/null) + if [[ $fdirtotal -gt 0 ]]; then + echo_message "" "" "" "," + fi + while read -r N; do + if [[ "${N}" != "[A-Za-z1-0]*" ]]; then + # read permissions? + if [[ ! -r "${N}" ]]; then + printf "\033[31mError: No read permissions for '%s' (run as root).\033[m\n" ", ${N}" + else + # ELF executable? + out=$(file "$(readlink -f "${N}")") + if [[ ! ${out} =~ ELF ]] ; then + if [[ "${verbose}" = "true" ]] ; then + echo_message "\033[34m*** Not an ELF file: ${tempdir}/" "" "" "" + file "${N}" + echo_message "\033[m" "" "" "" + fi + else + (( fdircount++ )) + echo_message "" "" " " "" + filecheck "${N}" + if [[ "$(find "${N}" \( -perm -004000 -o -perm -002000 \) -type f -print)" ]]; then + echo_message "\033[37;41m${N}\033[m\n" ",${N}\n" " filename='${N}' />\n" ", \"filename\":\"${N}\"}" + else + echo_message "${N}\n" ",${N}\n" " filename='${N}' />\n" ", \"filename\":\"${N}\"}" + fi + if [[ "${fdircount}" == "${fdirtotal}" ]]; then + echo_message "" "" "" "" + else + echo_message "" "" "" "," + fi + fi + fi + fi + done < <(find "${tempdir}" -type f 2>/dev/null) + echo_message "" "" "\n" "}" +} + +chk_file () { + if [[ -z "${CHK_FILE}" ]] ; then + printf "\033[31mError: Please provide a valid file.\033[m\n\n" + exit 1 + fi + + # does the file exist? + if [[ ! -e "${CHK_FILE}" ]] ; then + printf "\033[31mError: The file '%s' does not exist.\033[m\n\n" "${CHK_FILE}" + exit 1 + fi + + # read permissions? + if [[ ! -r "${CHK_FILE}" ]] ; then + printf "\033[31mError: No read permissions for '%s' (run as root).\033[m\n\n" "${CHK_FILE}" + exit 1 + fi + + # ELF executable? + out=$(file "$(readlink -f "${CHK_FILE}")") + if [[ ! ${out} =~ ELF ]] ; then + printf "\033[31mError: Not an ELF file: " + file "${CHK_FILE}" + printf "\033[m\n" + exit 1 + fi + if ${extended_checks}; then + echo_message "RELRO STACK CANARY NX PIE SELFRANDO Clang CFI SafeStack RPATH RUNPATH\tSymbols\t\tFORTIFY\tFortified\tFortifiable\tFILE\n" '' '' '{' + else + echo_message "RELRO STACK CANARY NX PIE RPATH RUNPATH\tSymbols\t\tFORTIFY\tFortified\tFortifiable\tFILE\n" '' '' '{' + fi + filecheck "${CHK_FILE}" + if [[ "$(find "${CHK_FILE}" \( -perm -004000 -o -perm -002000 \) -type f -print)" ]] ; then + echo_message "\033[37;41m${CHK_FILE}\033[m\n" ",${CHK_FILE}\n" " filename='${CHK_FILE}'/>\n" " } }" + else + echo_message "${CHK_FILE}\n" ",${CHK_FILE}\n" " filename='${CHK_FILE}'/>\n" " } }" + fi +} + +chk_proc_all () { + cd /proc || exit + echo_message "* System-wide ASLR" "" "" "" + aslrcheck + echo_message "* Does the CPU support NX: " "" "" "" + nxcheck + echo_message "* Core-Dumps access to all users: " "" "" "" + coredumpcheck + if ${extended_checks}; then + echo_message " COMMAND PID RELRO STACK CANARY Clang CFI SafeStack SECCOMP NX/PaX PIE SELFRANDO FORTIFY\n" "" "" '{' + else + echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE FORTIFY\n" "" "" '{' + fi + lastpid=0 + currpid=0 + for N in [1-9]*; do + if [[ "${N}" != "$$" ]] && readlink -q "${N}"/exe > /dev/null; then + (( lastpid++ )) + fi + done + for N in [1-9]*; do + if [[ "${N}" != "$$" ]] && readlink -q "${N}"/exe > /dev/null; then + (( currpid++ )) + name=$(head -1 "${N}"/status | cut -b 7-) + if [[ $format == "cli" ]]; then + printf "%16s" "${name}" + printf "%7d " "${N}" + else + echo_message "" "${N}," " \n" "" + else + echo_message "\n" "\n" "\n" "," + fi + fi + done + echo_message "" "" "" " }\n" + if [[ ! -e /usr/bin/id ]] ; then + echo_message "\n\033[33mNote: If you are running 'checksec.sh' as an unprivileged user, you\n" "" "" "" + echo_message " will not see all processes. Please run the script as root.\033[m\n\n" "" "" "\n" + else + if ! (root_privs) ; then + echo_message "\n\033[33mNote: You are running 'checksec.sh' as an unprivileged user.\n" "" "" "" + echo_message " Too see all processes, please run the script as root.\033[m\n\n" "" "" "\n" + fi + fi +} + +chk_proc () { + if [[ -z "${CHK_PROC}" ]] ; then + printf "\033[31mError: Please provide a valid process name.\033[m\n\n" + exit 1 + fi + if ! (isString "${CHK_PROC}") ; then + printf "\033[31mError: Please provide a valid process name.\033[m\n\n" + exit 1 + fi + cd /proc || exit + IFS=" " read -r -a fpids <<<"$(pgrep -d ' ' "${CHK_PROC}")" + if [[ ${#fpids} -eq 0 ]]; then + printf "\033[31mError: No process with the given name found.\033[m\n\n" + exit 1 + fi + echo_message "* System-wide ASLR" '' '' '' + aslrcheck + echo_message "* Does the CPU support NX: " '' '' '' + nxcheck + if ${extended_checks}; then + echo_message " COMMAND PID RELRO STACK CANARY Clang CFI SafeStack SECCOMP NX/PaX PIE SELFRANDO FORTIFY\n" "" "" '{' + else + echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE FORTIFY\n" "" "" '{' + fi + pos=$(( ${#fpids[*]} - 1 )) + last=${fpids[$pos]} + for N in "${fpids[@]}"; do + if [[ -d "${N}" ]] ; then + name=$(head -1 "${N}"/status | cut -b 7-) + if [[ $format == "cli" ]]; then + printf "%16s" "${name}" + printf "%7d " "${N}" + else + echo_message "" "${N}," "\n" "" + else + echo_message "\n" "\n" "\n" "," + fi + fi + done + echo_message "\n" "\n" "\n" "}\n" +} + +chk_proc_libs () { + if [[ -z "${CHK_PROC_LIBS}" ]] ; then + printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" + exit 1 + fi + if ! (isNumeric "${CHK_PROC_LIBS}") ; then + printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" + exit 1 + fi + cd /proc || exit + echo_message "* System-wide ASLR" '' '' '' + aslrcheck + echo_message "* Does the CPU support NX: " '' '' '' + nxcheck + echo_message "* Process information:\n\n" "" "" "" + if ${extended_checks}; then + echo_message " COMMAND PID RELRO STACK CANARY Clang CFI SafeStack SECCOMP NX/PaX PIE Fortify Source\n" '' '' '' + else + echo_message " COMMAND PID RELRO STACK CANARY SECCOMP NX/PaX PIE Fortify Source\n" '' '' '' + fi + N=${CHK_PROC_LIBS} + if [[ -d "${N}" ]] ; then + name=$(head -1 "${N}/status" | cut -b 7-) + if [[ "${format}" == "cli" ]]; then + printf "%16s" "${name}" + printf "%7d " "${N}" + else + echo_message "" "${name}," "\n" "} } }" + fi +} + +chk_fortify_file () { + # if first char of pathname is '~' replace it with '${HOME}' + if [[ "${CHK_FORTIFY_FILE:0:1}" = '~' ]] ; then + CHK_FORTIFY_FILE=${HOME}/${CHK_FORTIFY_FILE:1} + fi + + if [[ -z "${CHK_FORTIFY_FILE}" ]] ; then + printf "\033[31mError: Please provide a valid file.\033[m\n\n" + exit 1 + fi + # does the file exist? + if [[ ! -f "${CHK_FORTIFY_FILE}" ]] ; then + printf "\033[31mError: The file '%s' does not exist.\033[m\n\n" "${CHK_FORTIFY_FILE}" + exit 1 + fi + # read permissions? + if [[ ! -r "${CHK_FORTIFY_FILE}" ]] ; then + printf "\033[31mError: No read permissions for '%s' (run as root).\033[m\n\n" "${CHK_FORTIFY_FILE}" + exit 1 + fi + # ELF executable? + out=$(file "$(readlink -f "${CHK_FORTIFY_FILE}")") + if [[ ! ${out} =~ ELF ]] ; then + printf "\033[31mError: Not an ELF file: " + file "${CHK_FORTIFY_FILE}" + printf "\033[m\n" + exit 1 + fi + + if [[ -e /lib/libc.so.6 ]] ; then + FS_libc=/lib/libc.so.6 + elif [[ -e /lib64/libc.so.6 ]] ; then + FS_libc=/lib64/libc.so.6 + elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/i386-linux-gnu/libc.so.6 + elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/x86_64-linux-gnu/libc.so.6 + elif [[ -e /lib/arm-linux-gnueabihf/libc.so.6 ]] ; then + FS_libc=/lib/arm-linux-gnueabihf/libc.so.6 + elif [[ -e /lib/aarch64-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/aarch64-linux-gnu/libc.so.6 + else + printf "\033[31mError: libc not found.\033[m\n\n" + exit 1 + fi + + FS_chk_func_libc=() + FS_functions=() + while IFS='' read -r line; do FS_chk_func_libc+=("$line"); done < <(${readelf} -s ${FS_libc} 2>/dev/null | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') + while IFS='' read -r line; do FS_functions+=("$line"); done < <(${readelf} -s "${CHK_FORTIFY_FILE}" 2>/dev/null | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') + echo_message "" "" "\n" "} }" +} + +chk_fortify_proc () { + if [[ -z "${CHK_FORTIFY_PROC}" ]] ; then + printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" + exit 1 + fi + if ! (isNumeric "${CHK_FORTIFY_PROC}") ; then + printf "\033[31mError: Please provide a valid process ID.\033[m\n\n" + exit 1 + fi + cd /proc || exit + N=${CHK_FORTIFY_PROC} + if [[ -d "${N}" ]] ; then + # read permissions? + if [[ ! -r "${N}/exe" ]] ; then + if ! (root_privs) ; then + printf "\033[31mNo read permissions for '/proc/%s/exe' (run as root).\033[m\n\n" "${N}" + exit 1 + fi + if [[ ! "$(readlink "${N}/exe")" ]] ; then + printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n" + exit 1 + fi + exit 1 + fi + if [[ -e /lib/libc.so.6 ]] ; then + FS_libc=/lib/libc.so.6 + elif [[ -e /lib64/libc.so.6 ]] ; then + FS_libc=/lib64/libc.so.6 + elif [[ -e /lib/i386-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/i386-linux-gnu/libc.so.6 + elif [[ -e /lib/x86_64-linux-gnu/libc.so.6 ]] ; then + FS_libc=/lib/x86_64-linux-gnu/libc.so.6 + else + printf "\033[31mError: libc not found.\033[m\n\n" + exit 1 + fi + name=$(head -1 "${N}/status" | cut -b 7-) + echo_message "* Process name (PID) : ${name} (${N})\n" "" "" "" + + FS_chk_func_libc=() + FS_functions=() + while IFS='' read -r line; do FS_chk_func_libc+=("$line"); done < <(${readelf} -s $FS_libc 2>/dev/null | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') + while IFS='' read -r line; do FS_functions+=("$line"); done < <(${readelf} -s "${CHK_FORTIFY_PROC}/exe" 2>/dev/null | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') + echo_message "" "" "\n" "} }" + fi +} + +chk_kernel () { + if [[ ${CHK_KERNEL} == "kernel" ]]; then + CHK_KERNEL="" + fi + if [[ -e "${CHK_KERNEL}" ]] && [[ ! -d "${CHK_KERNEL}" ]]; then + if [[ -s "$(pwd -P)/${CHK_KERNEL}" ]]; then + configfile=$(pwd -P)/${CHK_KERNEL} + elif [[ -s "${CHK_KERNEL}" ]]; then + configfile=${CHK_KERNEL} + else + "Error: config file specified do not exist" + exit 1 + fi + echo_message "* Kernel protection information for : $configfile \n\n" "" "" "" + cd /proc && kernelcheck "$configfile" || exit + else + cd /proc || exit + echo_message "* Kernel protection information:\n\n" "" "" "" + kernelcheck + fi +} + +optspec=":h-:" +while getopts "${optspec}" optchar; do + case "${optchar}" in + -) + case "${OPTARG}" in + version) + version + exit 0 + ;; + debug) + debug=true + ;; + trace) + export BASH_XTRACEFD=5 + export PS4='(${BASH_SOURCE##*/}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + set -x + ;; + help) + help + exit 0 + ;; + debug_report) + debug_report + exit 0 + ;; + update|upgrade) + # shellcheck disable=SC2119 + upgrade + exit 0 + ;; + format=*|output=*) + output_format=${OPTARG#*=} + format + ;; + verbose) + verbose=true + ;; + extended) + extended_checks=true + ;; + dir=*|dir) + CHK_DIR=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_dir" + ;; + file=*|file) + CHK_FILE=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_file" + ;; + proc-all) + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_proc_all" + ;; + proc=*|proc) + CHK_PROC=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_proc" + ;; + proc-libs=*|proc-libs) + CHK_PROC_LIBS=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_proc_libs" + ;; + fortify-file=*|fortify-file) + CHK_FORTIFY_FILE=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_fortify_file" + ;; + fortify-proc=*|fortify-proc) + CHK_FORTIFY_PROC=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_fortify_proc" + ;; + kernel=*|kernel) + CHK_KERNEL=${OPTARG#*=}; + OPT=$((OPT + 1)) + CHK_FUNCTION="chk_kernel" + ;; + *) + printf "\033[31mError: Unknown option %s.\033[m\n\n" "${OPTARG}" + exit 1 + ;; + esac;; + *) + help + exit 0 + ;; + esac +done + +if [[ "${OPT}" == 0 ]]; then + printf "\033[31mError: No option selected. Please select an option.\033[m\n\n" + exit 1 +elif [[ "${OPT}" != 1 ]]; then + printf "\033[31mError: To many options selected. Please select one at a time.\033[m\n\n" + exit 1 +fi + +for variable in CHK_DIR CHK_FILE CHK_FORTIFY_FILE CHK_FORTIFY_PROC CHK_PROC CHK_PROC_LIBS; do + if [[ -n ${!variable+x} ]]; then + if [[ -z "${!variable}" ]]; then + printf "\033[31mError: Option Required.\033[m\n\n" + help + exit 1 + fi + fi +done + +# call the function +${CHK_FUNCTION} diff --git a/depend/zcash/qa/zcash/create_benchmark_archive.py b/depend/zcash/qa/zcash/create_benchmark_archive.py new file mode 100644 index 000000000..bc8633d42 --- /dev/null +++ b/depend/zcash/qa/zcash/create_benchmark_archive.py @@ -0,0 +1,262 @@ +import binascii +import calendar +import json +import plyvel +import progressbar +import os +import stat +import subprocess +import sys +import tarfile +import time + +ZCASH_CLI = './src/zcash-cli' +USAGE = """ +Requirements: +- find +- xz +- %s (edit ZCASH_CLI in this script to alter the path) +- A running mainnet zcashd using the default datadir with -txindex=1 + +Example usage: + +make -C src/leveldb/ +virtualenv venv +. venv/bin/activate +pip install --global-option=build_ext --global-option="-L$(pwd)/src/leveldb/" --global-option="-I$(pwd)/src/leveldb/include/" plyvel +pip install progressbar2 +LD_LIBRARY_PATH=src/leveldb python qa/zcash/create_benchmark_archive.py +""" % ZCASH_CLI + +def check_deps(): + if subprocess.call(['which', 'find', 'xz', ZCASH_CLI], stdout=subprocess.PIPE): + print(USAGE) + sys.exit() + +def encode_varint(n): + v = bytearray() + l = 0 + while True: + v.append((n & 0x7F) | (0x80 if l else 0x00)) + if (n <= 0x7F): + break + n = (n >> 7) - 1 + l += 1 + return bytes(v)[::-1] + +def decode_varint(v): + n = 0 + for ch in range(len(v)): + n = (n << 7) | (ord(v[ch]) & 0x7F) + if (ord(v[ch]) & 0x80): + n += 1 + else: + return n + +def compress_amount(n): + if n == 0: + return 0 + e = 0 + while (((n % 10) == 0) and e < 9): + n /= 10 + e += 1 + if e < 9: + d = (n % 10) + assert(d >= 1 and d <= 9) + n /= 10 + return 1 + (n*9 + d - 1)*10 + e + else: + return 1 + (n - 1)*10 + 9 + +OP_DUP = 0x76 +OP_EQUAL = 0x87 +OP_EQUALVERIFY = 0x88 +OP_HASH160 = 0xa9 +OP_CHECKSIG = 0xac +def to_key_id(script): + if len(script) == 25 and \ + script[0] == OP_DUP and \ + script[1] == OP_HASH160 and \ + script[2] == 20 and \ + script[23] == OP_EQUALVERIFY and \ + script[24] == OP_CHECKSIG: + return script[3:23] + return bytes() + +def to_script_id(script): + if len(script) == 23 and \ + script[0] == OP_HASH160 and \ + script[1] == 20 and \ + script[22] == OP_EQUAL: + return script[2:22] + return bytes() + +def to_pubkey(script): + if len(script) == 35 and \ + script[0] == 33 and \ + script[34] == OP_CHECKSIG and \ + (script[1] == 0x02 or script[1] == 0x03): + return script[1:34] + if len(script) == 67 and \ + script[0] == 65 and \ + script[66] == OP_CHECKSIG and \ + script[1] == 0x04: + return script[1:66] # assuming is fully valid + return bytes() + +def compress_script(script): + result = bytearray() + + key_id = to_key_id(script) + if key_id: + result.append(0x00) + result.extend(key_id) + return bytes(result) + + script_id = to_script_id(script) + if script_id: + result.append(0x01) + result.extend(script_id) + return bytes(result) + + pubkey = to_pubkey(script) + if pubkey: + result.append(0x00) + result.extend(pubkey[1:33]) + if pubkey[0] == 0x02 or pubkey[0] == 0x03: + result[0] = pubkey[0] + return bytes(result) + elif pubkey[0] == 0x04: + result[0] = 0x04 | (pubkey[64] & 0x01) + return bytes(result) + + size = len(script) + 6 + result.append(encode_varint(size)) + result.extend(script) + return bytes(result) + +def deterministic_filter(tarinfo): + tarinfo.uid = tarinfo.gid = 0 + tarinfo.uname = tarinfo.gname = "root" + tarinfo.mtime = calendar.timegm(time.strptime('2017-05-17', '%Y-%m-%d')) + tarinfo.mode |= stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP + tarinfo.mode &= ~stat.S_IWGRP + if tarinfo.isdir(): + tarinfo.mode |= \ + stat.S_IXUSR | \ + stat.S_IXGRP | \ + stat.S_IXOTH + else: + tarinfo.mode &= \ + ~stat.S_IXUSR & \ + ~stat.S_IXGRP & \ + ~stat.S_IXOTH + return tarinfo + +def create_benchmark_archive(blk_hash): + blk = json.loads(subprocess.check_output([ZCASH_CLI, 'getblock', blk_hash])) + print ('Height: %d' % blk['height']) + print ('Transactions: %d' % len(blk['tx'])) + + os.mkdir('benchmark') + with open('benchmark/block-%d.dat' % blk['height'], 'wb') as f: + f.write(binascii.unhexlify(subprocess.check_output([ZCASH_CLI, 'getblock', blk_hash, 'false']).strip())) + + txs = [json.loads(subprocess.check_output([ZCASH_CLI, 'getrawtransaction', tx, '1']) + ) for tx in blk['tx']] + + js_txs = len([tx for tx in txs if len(tx['vjoinsplit']) > 0]) + if js_txs: + print('Block contains %d JoinSplit-containing transactions' % js_txs) + return + + inputs = [(x['txid'], x['vout']) for tx in txs for x in tx['vin'] if x.has_key('txid')] + print('Total inputs: %d' % len(inputs)) + + unique_inputs = {} + for i in sorted(inputs): + if unique_inputs.has_key(i[0]): + unique_inputs[i[0]].append(i[1]) + else: + unique_inputs[i[0]] = [i[1]] + print('Unique input transactions: %d' % len(unique_inputs)) + + db_path = 'benchmark/block-%d-inputs' % blk['height'] + db = plyvel.DB(db_path, create_if_missing=True) + wb = db.write_batch() + bar = progressbar.ProgressBar(redirect_stdout=True) + print('Collecting input coins for block') + for tx in bar(unique_inputs.keys()): + rawtx = json.loads(subprocess.check_output([ZCASH_CLI, 'getrawtransaction', tx, '1'])) + + mask_size = 0 + mask_code = 0 + b = 0 + while 2+b*8 < len(rawtx['vout']): + zero = True + i = 0 + while i < 8 and 2+b*8+i < len(rawtx['vout']): + if 2+b*8+i in unique_inputs[tx]: + zero = False + i += 1 + if not zero: + mask_size = b + 1 + mask_code += 1 + b += 1 + + coinbase = len(rawtx['vin']) == 1 and 'coinbase' in rawtx['vin'][0] + first = len(rawtx['vout']) > 0 and 0 in unique_inputs[tx] + second = len(rawtx['vout']) > 1 and 1 in unique_inputs[tx] + code = 8*(mask_code - (0 if first or second else 1)) + \ + (1 if coinbase else 0) + \ + (2 if first else 0) + \ + (4 if second else 0) + + coins = bytearray() + # Serialized format: + # - VARINT(nVersion) + coins.extend(encode_varint(rawtx['version'])) + # - VARINT(nCode) + coins.extend(encode_varint(code)) + # - unspentness bitvector, for vout[2] and further; least significant byte first + for b in range(mask_size): + avail = 0 + i = 0 + while i < 8 and 2+b*8+i < len(rawtx['vout']): + if 2+b*8+i in unique_inputs[tx]: + avail |= (1 << i) + i += 1 + coins.append(avail) + # - the non-spent CTxOuts (via CTxOutCompressor) + for i in range(len(rawtx['vout'])): + if i in unique_inputs[tx]: + coins.extend(encode_varint(compress_amount(int(rawtx['vout'][i]['valueZat'])))) + coins.extend(compress_script( + binascii.unhexlify(rawtx['vout'][i]['scriptPubKey']['hex']))) + # - VARINT(nHeight) + coins.extend(encode_varint(json.loads( + subprocess.check_output([ZCASH_CLI, 'getblockheader', rawtx['blockhash']]) + )['height'])) + + db_key = b'c' + bytes(binascii.unhexlify(tx)[::-1]) + db_val = bytes(coins) + wb.put(db_key, db_val) + + wb.write() + db.close() + + # Make reproducible archive + os.remove('%s/LOG' % db_path) + files = subprocess.check_output(['find', 'benchmark']).strip().split('\n') + archive_name = 'block-%d.tar' % blk['height'] + tar = tarfile.open(archive_name, 'w') + for name in sorted(files): + tar.add(name, recursive=False, filter=deterministic_filter) + tar.close() + subprocess.check_call(['xz', '-6', archive_name]) + print('Created archive %s.xz' % archive_name) + subprocess.call(['rm', '-r', 'benchmark']) + +if __name__ == '__main__': + check_deps() + create_benchmark_archive('0000000007cdb809e48e51dd0b530e8f5073e0a9e9bd7ae920fe23e874658c74') diff --git a/depend/zcash/qa/zcash/create_wallet_200k_utxos.py b/depend/zcash/qa/zcash/create_wallet_200k_utxos.py new file mode 100755 index 000000000..08c766e12 --- /dev/null +++ b/depend/zcash/qa/zcash/create_wallet_200k_utxos.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +# +# Create a large wallet +# +# To use: +# - Copy to qa/rpc-tests/wallet_large.py +# - Add wallet_large.py to RPC tests list +# - ./qa/pull-tester/rpc-tests.sh wallet_large --nocleanup +# - Archive the resulting /tmp/test###### directory +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes_bi, + initialize_chain_clean, + start_nodes, +) + +from decimal import Decimal + + +class LargeWalletTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = start_nodes(2, self.options.tmpdir) + connect_nodes_bi(self.nodes, 0, 1) + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[1].generate(103) + self.sync_all() + + inputs = [] + for i in range(200000): + taddr = self.nodes[0].getnewaddress() + inputs.append(self.nodes[1].sendtoaddress(taddr, Decimal("0.001"))) + if i % 1000 == 0: + self.nodes[1].generate(1) + self.sync_all() + + self.nodes[1].generate(1) + self.sync_all() + print('Node 0: %d transactions, %d UTXOs' % + (len(self.nodes[0].listtransactions()), len(self.nodes[0].listunspent()))) + print('Node 1: %d transactions, %d UTXOs' % + (len(self.nodes[1].listtransactions()), len(self.nodes[1].listunspent()))) + assert_equal(len(self.nodes[0].listunspent()), len(inputs)) + +if __name__ == '__main__': + LargeWalletTest().main() diff --git a/depend/zcash/qa/zcash/full_test_suite.py b/depend/zcash/qa/zcash/full_test_suite.py new file mode 100755 index 000000000..fd67a6945 --- /dev/null +++ b/depend/zcash/qa/zcash/full_test_suite.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +# +# Execute all of the automated tests related to Zcash. +# + +import argparse +from glob import glob +import os +import re +import subprocess +import sys + +REPOROOT = os.path.dirname( + os.path.dirname( + os.path.dirname( + os.path.abspath(__file__) + ) + ) +) + +def repofile(filename): + return os.path.join(REPOROOT, filename) + +def get_arch_dir(): + depends_dir = os.path.join(REPOROOT, 'depends') + + arch_dir = os.path.join(depends_dir, 'x86_64-pc-linux-gnu') + if os.path.isdir(arch_dir): + return arch_dir + + # Not Linux, try MacOS + arch_dirs = glob(os.path.join(depends_dir, 'x86_64-apple-darwin*')) + if arch_dirs: + # Just try the first one; there will only be one in CI + return arch_dirs[0] + + print("!!! cannot find architecture dir under depends/ !!!") + return None + + +# +# Custom test runners +# + +RE_RPATH_RUNPATH = re.compile('No RPATH.*No RUNPATH') +RE_FORTIFY_AVAILABLE = re.compile('FORTIFY_SOURCE support available.*Yes') +RE_FORTIFY_USED = re.compile('Binary compiled with FORTIFY_SOURCE support.*Yes') + +CXX_BINARIES = [ + 'src/zcashd', + 'src/zcash-cli', + 'src/zcash-gtest', + 'src/zcash-tx', + 'src/test/test_bitcoin', +] +RUST_BINARIES = [ + 'src/zcashd-wallet-tool', +] + +def test_rpath_runpath(filename): + output = subprocess.check_output( + [repofile('qa/zcash/checksec.sh'), '--file=' + repofile(filename)] + ) + if RE_RPATH_RUNPATH.search(output.decode('utf-8')): + print('PASS: %s has no RPATH or RUNPATH.' % filename) + return True + else: + print('FAIL: %s has an RPATH or a RUNPATH.' % filename) + print(output) + return False + +def test_fortify_source(filename): + proc = subprocess.Popen( + [repofile('qa/zcash/checksec.sh'), '--fortify-file=' + repofile(filename)], + stdout=subprocess.PIPE, + ) + line1 = proc.stdout.readline() + line2 = proc.stdout.readline() + proc.terminate() + if RE_FORTIFY_AVAILABLE.search(line1.decode('utf-8')) and RE_FORTIFY_USED.search(line2.decode('utf-8')): + print('PASS: %s has FORTIFY_SOURCE.' % filename) + return True + else: + print('FAIL: %s is missing FORTIFY_SOURCE.' % filename) + return False + +def check_security_hardening(): + ret = True + + # PIE, RELRO, Canary, and NX are tested by make check-security. + 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: + magic = f.read(4) + if not magic.startswith(b'\x7fELF'): + return ret + + for bin in CXX_BINARIES + RUST_BINARIES: + ret &= test_rpath_runpath(bin) + + # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE + # is enabled for the entire binary. See issue #915. + # FORTIFY_SOURCE is not applicable to Rust binaries. + for bin in CXX_BINARIES: + ret &= test_fortify_source(bin) + + return ret + +def ensure_no_dot_so_in_depends(): + arch_dir = get_arch_dir() + if arch_dir is None: + return False + + exit_code = 0 + + if os.path.isdir(arch_dir): + lib_dir = os.path.join(arch_dir, 'lib') + libraries = os.listdir(lib_dir) + + for lib in libraries: + if lib.find(".so") != -1: + print(lib) + exit_code = 1 + else: + exit_code = 2 + print("arch-specific build dir not present") + print("Did you build the ./depends tree?") + print("Are you on a currently unsupported architecture?") + + if exit_code == 0: + print("PASS.") + else: + print("FAIL.") + + return exit_code == 0 + +def util_test(): + python = [] + if os.path.isfile('/usr/local/bin/python3'): + python = ['/usr/local/bin/python3'] + + return subprocess.call( + python + [repofile('src/test/bitcoin-util-test.py')], + cwd=repofile('src'), + env={'PYTHONPATH': repofile('src/test'), 'srcdir': repofile('src')} + ) == 0 + +def rust_test(): + arch_dir = get_arch_dir() + if arch_dir is None: + return False + + rust_env = os.environ.copy() + rust_env['RUSTC'] = os.path.join(arch_dir, 'native', 'bin', 'rustc') + return subprocess.call([ + os.path.join(arch_dir, 'native', 'bin', 'cargo'), + 'test', + '--manifest-path', + os.path.join(REPOROOT, 'Cargo.toml'), + ], env=rust_env) == 0 + +# +# Tests +# + +STAGES = [ + 'rust-test', + 'btest', + 'gtest', + 'sec-hard', + 'no-dot-so', + 'util-test', + 'secp256k1', + 'univalue', + 'rpc', +] + +STAGE_COMMANDS = { + 'rust-test': rust_test, + 'btest': [repofile('src/test/test_bitcoin'), '-p'], + 'gtest': [repofile('src/zcash-gtest')], + 'sec-hard': check_security_hardening, + 'no-dot-so': ensure_no_dot_so_in_depends, + 'util-test': util_test, + 'secp256k1': ['make', '-C', repofile('src/secp256k1'), 'check'], + 'univalue': ['make', '-C', repofile('src/univalue'), 'check'], + 'rpc': [repofile('qa/pull-tester/rpc-tests.py')], +} + + +# +# Test driver +# + +def run_stage(stage): + print('Running stage %s' % stage) + print('=' * (len(stage) + 14)) + print() + + cmd = STAGE_COMMANDS[stage] + if type(cmd) == type([]): + ret = subprocess.call(cmd) == 0 + else: + ret = cmd() + + print() + print('-' * (len(stage) + 15)) + print('Finished stage %s' % stage) + print() + + return ret + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--list-stages', dest='list', action='store_true') + parser.add_argument('stage', nargs='*', default=STAGES, + help='One of %s'%STAGES) + args = parser.parse_args() + + # Check for list + if args.list: + for s in STAGES: + print(s) + sys.exit(0) + + # Check validity of stages + for s in args.stage: + if s not in STAGES: + print("Invalid stage '%s' (choose from %s)" % (s, STAGES)) + sys.exit(1) + + # Run the stages + all_passed = True + for s in args.stage: + passed = run_stage(s) + if not passed: + print("!!! Stage %s failed !!!" % (s,)) + all_passed &= passed + + if not all_passed: + print("!!! One or more test stages failed !!!") + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/depend/zcash/qa/zcash/performance-measurements.sh b/depend/zcash/qa/zcash/performance-measurements.sh new file mode 100755 index 000000000..34ef268f0 --- /dev/null +++ b/depend/zcash/qa/zcash/performance-measurements.sh @@ -0,0 +1,379 @@ +#!/usr/bin/env bash + +export LC_ALL=C +set -u + + +DATADIR=./benchmark-datadir +SHA256CMD="$(command -v sha256sum || echo shasum)" +SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')" + +function zcash_rpc { + ./src/zcash-cli -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 "$@" +} + +function zcash_rpc_slow { + # Timeout of 1 hour + zcash_rpc -rpcclienttimeout=3600 "$@" +} + +function zcash_rpc_veryslow { + # Timeout of 2.5 hours + zcash_rpc -rpcclienttimeout=9000 "$@" +} + +function zcash_rpc_wait_for_start { + zcash_rpc -rpcwait getinfo > /dev/null +} + +function zcashd_generate { + zcash_rpc generate 101 > /dev/null +} + +function extract_benchmark_datadir { + if [ -f "$1.tar.xz" ]; then + # Check the hash of the archive: + "$SHA256CMD" $SHA256ARGS -c < /dev/null + wait $ZCASHD_PID +} + +function zcashd_massif_start { + case "$1" in + sendtoaddress|loadwallet|listunspent) + case "$2" in + 200k-recv) + use_200k_benchmark 0 + ;; + 200k-send) + use_200k_benchmark 1 + ;; + *) + echo "Bad arguments to zcashd_massif_start." + exit 1 + esac + ;; + *) + rm -rf "$DATADIR" + mkdir -p "$DATADIR/regtest" + touch "$DATADIR/zcash.conf" + esac + rm -f massif.out + valgrind --tool=massif --time-unit=ms --massif-out-file=massif.out ./src/zcashd -regtest -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 -showmetrics=0 & + ZCASHD_PID=$! + zcash_rpc_wait_for_start +} + +function zcashd_massif_stop { + zcash_rpc stop > /dev/null + wait $ZCASHD_PID + ms_print massif.out +} + +function zcashd_valgrind_start { + rm -rf "$DATADIR" + mkdir -p "$DATADIR/regtest" + touch "$DATADIR/zcash.conf" + rm -f valgrind.out + valgrind --leak-check=yes -v --error-limit=no --log-file="valgrind.out" ./src/zcashd -regtest -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 -showmetrics=0 & + ZCASHD_PID=$! + zcash_rpc_wait_for_start +} + +function zcashd_valgrind_stop { + zcash_rpc stop > /dev/null + wait $ZCASHD_PID + cat valgrind.out +} + +function extract_benchmark_data { + if [ -f "block-107134.tar.xz" ]; then + # Check the hash of the archive: + "$SHA256CMD" $SHA256ARGS -c < 0: + results[case] = True + return res + except RpcException as e: + print('ERROR: %s' % str(e)) + if results is not None and len(case) > 0: + results[case] = False + return None + +def wait_for_balance(zcash, zaddr, expected=None): + print('Waiting for funds to %s...' % zaddr) + unconfirmed_balance = Decimal(zcash.z_getbalance(zaddr, 0)).quantize(Decimal('1.00000000')) + print('Expecting: %s; Unconfirmed Balance: %s' % (expected, unconfirmed_balance)) + if expected is not None and unconfirmed_balance != expected: + print('WARNING: Unconfirmed balance does not match expected balance') + + # Default timeout is 15 minutes + ttl = 900 + while True: + balance = Decimal(zcash.z_getbalance(zaddr)).quantize(Decimal('1.00000000')) + if (expected is not None and balance == unconfirmed_balance) or (expected is None and balance > 0): + print('Received %s' % balance) + return balance + + time.sleep(1) + ttl -= 1 + if ttl == 0: + if zcash.automated: + # Reset timeout + ttl = 300 + else: + # Ask user if they want to keep waiting + print() + print('Balance: %s Expected: %s' % (balance, expected)) + ret = input('Do you wish to continue waiting? (Y/n) ') + if ret.lower() == 'n': + print('Address contained %s at timeout' % balance) + return balance + else: + # Wait another 5 minutes before asking again + ttl = 300 + +def wait_and_check_balance(results, case, zcash, addr, expected): + #Wait for async call to finish and persist completely to caller + time.sleep(5) + balance = wait_for_balance(zcash, addr, expected) + if balance != expected and results is not None and len(case) > 0: + results[case] = False + return balance + +def wait_for_txid_operation(zcash, opid, timeout=300): + print('Waiting for async operation %s' % opid) + result = None + for _ in iter(range(timeout)): + results = zcash.z_getoperationresult([opid]) + if len(results) > 0: + result = results[0] + break + time.sleep(1) + + status = result['status'] + if status == 'failed': + print('Operation failed') + print(result['error']['message']) + return None + elif status == 'success': + txid = result['result']['txid'] + print('txid: %s' % txid) + return txid + +def async_txid_cmd(results, case, zcash, name, args=[]): + opid = run_cmd(results, case, zcash, name, args) + # Some async commands return a dictionary containing the opid + if isinstance(opid, dict): + opid = opid['opid'] + if opid is None: + if results is not None and len(case) > 0: + results[case] = False + return None + + txid = wait_for_txid_operation(zcash, opid) + if txid is None: + if results is not None and len(case) > 0: + results[case] = False + return txid + +def z_sendmany(results, case, zcash, from_addr, recipients): + return async_txid_cmd(results, case, zcash, 'z_sendmany', [ + from_addr, + [{ + 'address': to_addr, + 'amount': amount, + } for (to_addr, amount) in recipients] + ]) + +def check_z_sendmany(results, case, zcash, from_addr, recipients): + txid = z_sendmany(results, case, zcash, from_addr, recipients) + if txid is None: + return [Decimal('0')] + return [wait_and_check_balance(results, case, zcash, to_addr, amount) for (to_addr, amount) in recipients] + +def check_z_sendmany_parallel(results, zcash, runs): + # First attempt to create all the transactions + txids = [(run, z_sendmany(results, run[0], zcash, run[1], run[2])) for run in runs] + # Then wait for balance updates caused by successful transactions + return [ + wait_and_check_balance(results, run[0], zcash, to_addr, amount) if txid is not None else Decimal('0') + for (run, txid) in txids + for (to_addr, amount) in run[2]] + +def z_mergetoaddress(results, case, zcash, from_addrs, to_addr): + return async_txid_cmd(results, case, zcash, 'z_mergetoaddress', [from_addrs, to_addr]) + +def check_z_mergetoaddress(results, case, zcash, from_addrs, to_addr, amount): + txid = z_mergetoaddress(results, case, zcash, from_addrs, to_addr) + if txid is None: + return Decimal('0') + return wait_and_check_balance(results, case, zcash, to_addr, amount) + +def check_z_mergetoaddress_parallel(results, zcash, runs): + # First attempt to create all the transactions + txids = [(run, z_mergetoaddress(results, run[0], zcash, run[1], run[2])) for run in runs] + # Then wait for balance updates caused by successful transactions + return [ + wait_and_check_balance(results, run[0], zcash, run[2], run[3]) if txid is not None else Decimal('0') + for (run, txid) in txids] + +def tap_zfaucet(addr): + with requests.Session() as session: + # Get token to request TAZ from faucet with a given zcash address + response = session.get(URL_FAUCET_TAP) + if response.status_code != 200: + print("Error establishing session at:", URL_FAUCET_TAP) + os.sys.exit(1) + csrftoken = response.cookies['csrftoken'] + + # Request TAZ from the faucet + data_params = dict(csrfmiddlewaretoken=csrftoken, address=addr) + response2 = session.post(URL_FAUCET_TAP, data=data_params, headers=dict(Referer=URL_FAUCET_TAP)) + if response2.status_code != 200: + print("Error tapping faucet at:", URL_FAUCET_TAP) + os.sys.exit(1) + +def get_zfaucet_addrs(): + with requests.Session() as session: + response = session.get(URL_FAUCET_DONATION) + if response.status_code != 200: + print("Error establishing session at:", URL_FAUCET_DONATION) + os.sys.exit(1) + data = response.json() + return data + +def get_zfaucet_taddr(): + return get_zfaucet_addrs()["t_address"] + +def get_zfaucet_zsapaddr(): + # At the time of writing this, it appears these(keys) are backwards + return get_zfaucet_addrs()["z_address_legacy"] + +def get_zfaucet_zsproutaddr(): + # At the time of writing this, it appears these(keys) are backwards + return get_zfaucet_addrs()["z_address_sapling"] + +# +# Test runners +# + +def simple_commands(zcash): + results = {} + run_cmd(results, '2a', zcash, 'getinfo'), + run_cmd(results, '2b', zcash, 'help'), + run_cmd(results, '5o', zcash, 'getwalletinfo'), + run_cmd(results, '6a', zcash, 'getpeerinfo'), + run_cmd(results, '6b', zcash, 'getnetworkinfo'), + run_cmd(results, '6c', zcash, 'getdeprecationinfo'), + run_cmd(results, '6d', zcash, 'getconnectioncount'), + run_cmd(results, '6e', zcash, 'getaddednodeinfo', [False]), + run_cmd(results, '7a', zcash, 'getblocksubsidy'), + run_cmd(results, '7c', zcash, 'getmininginfo'), + run_cmd(results, '7d', zcash, 'getnetworkhashps'), + run_cmd(results, '7e', zcash, 'getnetworksolps'), + return results + +def transaction_chain(zcash): + results = {} + + # Generate the various addresses we will use + taddr_1 = run_cmd(results, '3c', zcash, 'getnewaddress') + taddr_2 = run_cmd(results, '3d', zcash, 'getnewaddress') + taddr_3 = run_cmd(results, '3d', zcash, 'getnewaddress') + taddr_4 = run_cmd(results, '3d', zcash, 'getnewaddress') + taddr_5 = run_cmd(results, '3d', zcash, 'getnewaddress') + sapling_zaddr_1 = run_cmd(results, '3e', zcash, 'z_getnewaddress', ['sapling']) + sapling_zaddr_2 = run_cmd(results, '3f', zcash, 'z_getnewaddress', ['sapling']) + sapling_zaddr_3 = run_cmd(results, '3f', zcash, 'z_getnewaddress', ['sapling']) + + # Check that the zaddrs are all listed + zaddrs = run_cmd(results, '5a', zcash, 'z_listaddresses') + if ( sapling_zaddr_1 not in zaddrs or + sapling_zaddr_2 not in zaddrs): + results['5a'] = False + + # Validate the addresses + ret = run_cmd(results, '5c', zcash, 'z_validateaddress', [sapling_zaddr_1]) + if not ret['isvalid'] or ret['type'] != 'sapling': + results['5c'] = False + + # Set up beginning and end of the chain + print('#') + print('# Initialising transaction chain') + print('#') + print() + if zcash.use_faucet: + print('Tapping the testnet faucet for testing funds...') + chain_end = get_zfaucet_taddr() + tap_zfaucet(taddr_1) + print('Done! Leftover funds will be sent back to the faucet.') + else: + chain_end = input('Type or paste transparent address where leftover funds should be sent: ') + if not zcash.validateaddress(chain_end)['isvalid']: + print('Invalid transparent address') + return results + print() + print('Please send at least 0.01 ZEC/TAZ to the following address:') + print(taddr_1) + print() + input('Press Enter once the funds have been sent.') + print() + + # Wait to receive starting balance + taddr_balance = wait_for_balance(zcash, taddr_1) + starting_balance = taddr_balance + + # + # Start the transaction chain! + # + print() + print('#') + print('# Starting transaction chain') + print('#') + print() + try: + # taddr -> Sapling + # Send it all here because z_sendmany pick a new t-addr for change + sapling_balance = check_z_sendmany( + results, '4f', zcash, taddr_1, [(sapling_zaddr_1, taddr_balance - DEFAULT_FEE)])[0] + taddr_balance = Decimal('0') + + # Sapling -> taddr + taddr_balance = check_z_sendmany( + results, '4i', zcash, sapling_zaddr_1, [(taddr_1, (starting_balance / Decimal('10')) * Decimal('3'))])[0] + sapling_balance -= taddr_balance + DEFAULT_FEE + + # + # Intra-pool tests + # + + # Sapling -> same Sapling + sapling_balance = check_z_sendmany( + results, '4g',zcash, sapling_zaddr_1, [(sapling_zaddr_1, sapling_balance - DEFAULT_FEE)])[0] + + # taddr -> different taddr + # Sapling -> different Sapling + (taddr_balance, sapling_balance) = check_z_sendmany_parallel(results, zcash, [ + ('4e', taddr_1, [(taddr_2, taddr_balance - DEFAULT_FEE)]), + ('4h', sapling_zaddr_1, [(sapling_zaddr_2, sapling_balance - DEFAULT_FEE)]), + ]) + + # taddr -> multiple taddr + # Sapling -> multiple Sapling + check_z_sendmany_parallel(results, zcash, [ + ('4p', taddr_2, [ + (taddr_1, starting_balance / Decimal('10')), + (taddr_3, taddr_balance - (starting_balance / Decimal('10')) - DEFAULT_FEE), + ]), + ('4t', sapling_zaddr_2, [ + (sapling_zaddr_1, starting_balance / Decimal('10')), + (sapling_zaddr_3, starting_balance / Decimal('10')), + ]), + ]) + + taddr_balance -= DEFAULT_FEE + sapling_balance -= DEFAULT_FEE + + # multiple Sapling -> Sapling + # multiple taddr -> taddr + check_z_mergetoaddress_parallel(results, zcash, [ + ('4gg', [sapling_zaddr_1, sapling_zaddr_3], sapling_zaddr_2, sapling_balance - DEFAULT_FEE), + ('', [taddr_1, taddr_3], taddr_2, taddr_balance - DEFAULT_FEE), + ]) + sapling_balance -= DEFAULT_FEE + taddr_balance -= DEFAULT_FEE + taddr_2_balance = taddr_balance + + # + # Inter-pool tests + # + + # Sapling -> taddr and Sapling + check_z_sendmany( + results, '4w', zcash, sapling_zaddr_2,[ + (taddr_3, starting_balance / Decimal('10')), + (sapling_zaddr_1, starting_balance / Decimal('10'))])[0] + + sapling_balance -= (starting_balance / Decimal('10')) + DEFAULT_FEE + taddr_balance += starting_balance / Decimal('10') + + # taddr and Sapling -> Sapling + check_z_mergetoaddress(results, '4ee', zcash, [taddr_3, sapling_zaddr_1], sapling_zaddr_2, sapling_balance + (starting_balance / Decimal('10')) - DEFAULT_FEE) + + sapling_balance += (starting_balance / Decimal('10')) - DEFAULT_FEE + taddr_balance -= starting_balance / Decimal('10') + + # Sapling -> multiple taddr + check_z_sendmany(results, '4v', zcash, sapling_zaddr_2, [ + (taddr_4, (starting_balance / Decimal('10'))), + (taddr_5, (starting_balance / Decimal('10')))])[0] + + sapling_balance -= ((starting_balance / Decimal('10')) * Decimal('2')) + DEFAULT_FEE + taddr_balance += (starting_balance / Decimal('10')) * Decimal('2') + + # multiple taddr -> Sapling + check_z_mergetoaddress(results, '4bb',zcash, [taddr_4, taddr_5], sapling_zaddr_2, sapling_balance + ((starting_balance / Decimal('10')) * Decimal('2')) - DEFAULT_FEE) + sapling_balance += ((starting_balance / Decimal('10')) * Decimal('2')) - DEFAULT_FEE + taddr_balance -= (starting_balance / Decimal('10')) * Decimal('2') + + # multiple Sapling -> taddr + check_z_mergetoaddress(None, '', zcash, [sapling_zaddr_1, sapling_zaddr_2, sapling_zaddr_3], taddr_2, taddr_2_balance + sapling_balance - DEFAULT_FEE) + taddr_balance += sapling_balance - DEFAULT_FEE + sapling_balance = Decimal('0') + + # taddr -> multiple Sapling + taddr_2_balance = Decimal(zcash.z_getbalance(taddr_2)).quantize(Decimal('1.00000000')) + check_z_sendmany(results, '4r', zcash, taddr_2, [ + (sapling_zaddr_1, (starting_balance / Decimal('10'))), + (sapling_zaddr_2, taddr_2_balance - (starting_balance / Decimal('10')) - DEFAULT_FEE)])[0] + + sapling_balance = taddr_2_balance - DEFAULT_FEE + taddr_balance -= taddr_2_balance + + # multiple Sapling -> taddr + check_z_mergetoaddress(None, '', zcash, [sapling_zaddr_1, sapling_zaddr_2], taddr_2, sapling_balance - DEFAULT_FEE) + taddr_balance += sapling_balance - DEFAULT_FEE + sapling_balance = Decimal('0') + + # z_mergetoaddress taddr -> Sapling + taddr_2_balance = Decimal(zcash.z_getbalance(taddr_2)).quantize(Decimal('1.00000000')) + check_z_mergetoaddress(results, '4cc', zcash, [taddr_2], sapling_zaddr_1, taddr_2_balance - DEFAULT_FEE) + sapling_balance = taddr_2_balance - DEFAULT_FEE + taddr_balance -= taddr_2_balance + except Exception as e: + print('Error: %s' % e) + traceback.print_exc() + finally: + # + # End the chain by returning the remaining funds + # + print() + print('#') + print('# Finishing transaction chain') + print('#') + all_addrs = [ + taddr_1, taddr_2, taddr_3, taddr_4, taddr_5, + sapling_zaddr_1, sapling_zaddr_2, sapling_zaddr_3, + ] + + print() + print('Waiting for all transactions to be mined') + for addr in all_addrs: + balance = Decimal(zcash.z_getbalance(addr, 0)).quantize(Decimal('1.00000000')) + if balance > 0: + wait_for_balance(zcash, addr, balance) + + print() + print('Returning remaining balance minus fees') + for addr in all_addrs: + balance = Decimal(zcash.z_getbalance(addr)).quantize(Decimal('1.00000000')) + if balance > 0: + z_sendmany(None, '', zcash, addr, [(chain_end, balance - DEFAULT_FEE)]) + + return results + + +# +# Test stages +# + +STAGES = [ + 'simple-commands', + 'transaction-chain' +] + +STAGE_COMMANDS = { + 'simple-commands': simple_commands, + 'transaction-chain': transaction_chain, +} + +def run_stage(stage, zcash): + print('Running stage %s' % stage) + print('=' * (len(stage) + 14)) + print() + + cmd = STAGE_COMMANDS[stage] + if cmd is not None: + ret = cmd(zcash) + else: + print('WARNING: stage not yet implemented, skipping') + ret = {} + + print() + print('-' * (len(stage) + 15)) + print('Finished stage %s' % stage) + print() + + return ret + + +# +# Zcash wrapper +# + +class ZcashNode(object): + def __init__(self, args, zcashd=None, zcash_cli=None): + if zcashd is None: + zcashd = os.getenv('ZCASHD', 'zcashd') + if zcash_cli is None: + zcash_cli = os.getenv('ZCASHCLI', 'zcash-cli') + + self.__datadir = args.datadir + self.__wallet = args.wallet + self.__testnet = not args.mainnet + self.__zcashd = zcashd + self.__zcash_cli = zcash_cli + self.__process = None + self.__proxy = None + + self.automated = args.automate + self.use_faucet = args.faucet + + def start(self, extra_args=None, timewait=None): + if self.__proxy is not None: + raise RuntimeError('Already started') + + rpcuser = 'st' + rpcpassword = 'st' + + args = [ + self.__zcashd, + '-datadir=%s' % self.__datadir, + '-wallet=%s' % self.__wallet, + '-rpcuser=%s' % rpcuser, + '-rpcpassword=%s' % rpcpassword, + '-showmetrics=0', + '-experimentalfeatures', + '-zmergetoaddress', + '-walletrequirebackup=false' + ] + if self.__testnet: + args.append('-testnet=1') + if extra_args is not None: + args.extend(extra_args) + + self.__process = subprocess.Popen(args) + + cli_args = [ + self.__zcash_cli, + '-datadir=%s' % self.__datadir, + '-rpcuser=%s' % rpcuser, + '-rpcpassword=%s' % rpcpassword, + '-rpcwait', + ] + if self.__testnet: + cli_args.append('-testnet=1') + cli_args.append('getblockcount') + + devnull = open('/dev/null', 'w+', encoding='utf8') + if os.getenv('PYTHON_DEBUG', ''): + print('start_node: zcashd started, calling zcash-cli -rpcwait getblockcount') + subprocess.check_call(cli_args, stdout=devnull) + if os.getenv('PYTHON_DEBUG', ''): + print('start_node: calling zcash-cli -rpcwait getblockcount returned') + devnull.close() + + rpcuserpass = '%s:%s' % (rpcuser, rpcpassword) + rpchost = '127.0.0.1' + rpcport = 18232 if self.__testnet else 8232 + + url = 'http://%s@%s:%d' % (rpcuserpass, rpchost, rpcport) + if timewait is not None: + self.__proxy = Proxy(url, timeout=timewait) + else: + self.__proxy = Proxy(url) + + def stop(self): + if self.__proxy is None: + raise RuntimeError('Not running') + + self.__proxy.stop() + self.__process.wait() + self.__proxy = None + self.__process = None + + def __getattr__(self, name): + if self.__proxy is None: + raise RuntimeError('Not running') + + return self.__proxy.__getattr__(name) + + +# +# Test driver +# + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--automate', action='store_true', help='Run the smoke tests without a user present') + parser.add_argument('--list-stages', dest='list', action='store_true') + parser.add_argument('--mainnet', action='store_true', help='Use mainnet instead of testnet') + parser.add_argument('--use-faucet', dest='faucet', action='store_true', help='Use testnet faucet as source of funds') + parser.add_argument('--wallet', default='wallet.dat', help='Wallet file to use (within data directory)') + parser.add_argument('datadir', help='Data directory to use for smoke testing', default=None) + parser.add_argument('stage', nargs='*', default=STAGES, help='One of %s' % STAGES) + args = parser.parse_args() + + # Check for list + if args.list: + for s in STAGES: + print(s) + sys.exit(0) + + # Check validity of stages + for s in args.stage: + if s not in STAGES: + print("Invalid stage '%s' (choose from %s)" % (s, STAGES)) + sys.exit(1) + + # Don't allow using the default wallet.dat in mainnet mode + if args.mainnet and args.wallet == 'wallet.dat': + print('Cannot use wallet.dat as wallet file when running mainnet tests. Keep your funds safe!') + sys.exit(1) + + # Testnet faucet cannot be used in mainnet mode + if args.mainnet and args.faucet: + print('Cannot use testnet faucet when running mainnet tests.') + sys.exit(1) + + # Enforce correctly-configured automatic mode + if args.automate: + if args.mainnet: + print('Cannot yet automate mainnet tests.') + sys.exit(1) + if not args.faucet: + print('--automate requires --use-faucet') + sys.exit(1) + + # Start zcashd + zcash = ZcashNode(args) + print('Start time: %s' % TIME_STARTED) + print('Starting zcashd...') + zcash.start() + print() + + # Run the stages + results = {} + for s in args.stage: + results.update(run_stage(s, zcash)) + + # Stop zcashd + print('Stopping zcashd...') + zcash.stop() + + passed = True + print() + print('========================') + print(' Results') + print('========================') + print('Case | Expected | Actual') + print('========================') + for test_case in SMOKE_TESTS: + case = test_case[0] + expected = test_case[1 if args.mainnet else 2] + if case in results: + actual = results[case] + actual_str = '%s%s' % ( + 'Passed' if actual else 'Failed', + '' if expected == actual else '!!!' + ) + passed &= (expected == actual) + else: + actual_str = ' N/A' + print('%s | %s | %s' % ( + case.ljust(4), + ' Passed ' if expected else ' Failed ', + actual_str + )) + + if not passed: + print() + print("!!! One or more smoke test stages failed !!!") + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/depend/zcash/qa/zcash/test-depends-sources-mirror.py b/depend/zcash/qa/zcash/test-depends-sources-mirror.py new file mode 100755 index 000000000..d83cca1f1 --- /dev/null +++ b/depend/zcash/qa/zcash/test-depends-sources-mirror.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# This script tests that the package mirror at https://download.z.cash/depends-sources/ +# contains all of the packages required to build this version of Zcash. +# +# This script assumes you've just built Zcash, and that as a result of that +# build, all of the dependency packages have been downloaded into the +# depends/sources directory (inside the root of this repository). The script +# checks that all of those files are accessible on the mirror. + +import sys +import os +import requests + +MIRROR_URL_DIR="https://download.z.cash/depends-sources/" +DEPENDS_SOURCES_DIR=os.path.realpath(os.path.join( + os.path.dirname(__file__), + "..", "..", "depends", "sources" +)) + +def get_depends_sources_list(): + return filter( + lambda f: os.path.isfile(os.path.join(DEPENDS_SOURCES_DIR, f)), + os.listdir(DEPENDS_SOURCES_DIR) + ) + +for filename in get_depends_sources_list(): + resp = requests.head(MIRROR_URL_DIR + filename) + + print("Checking [" + filename + "] ...") + + if resp.status_code != 200: + print("FAIL. File not found on server: ", filename) + sys.exit(1) + + expected_size = os.path.getsize(os.path.join(DEPENDS_SOURCES_DIR, filename)) + server_size = int(resp.headers['Content-Length']) + if expected_size != server_size: + print("FAIL. On the server, %s is %d bytes, but locally it is %d bytes." % (filename, server_size, expected_size)) + sys.exit(1) + +print("PASS.") +sys.exit(0) diff --git a/depend/zcash/qa/zcash/updatecheck.py b/depend/zcash/qa/zcash/updatecheck.py new file mode 100755 index 000000000..ba0d79a30 --- /dev/null +++ b/depend/zcash/qa/zcash/updatecheck.py @@ -0,0 +1,414 @@ +#!/usr/bin/env python3 +# +# This script checks for updates to zcashd's dependencies. +# +# The SOURCE_ROOT constant specifies the location of the zcashd codebase to +# check, and the GITHUB_API_* constants specify a personal access token for the +# GitHub API, which need not have any special privileges. +# +# All dependencies must be specified inside the get_dependency_list() function +# below. A dependency is specified by: +# +# (a) A way to fetch a list of current releases. +# +# This is usually regular-expression-based parsing of GitHub tags, but +# might otherwise parse version numbers out of the project's webpage. +# +# GitHub tag regexps can be tested by specifying test cases in the third +# argument to GithubTagReleaseLister's constructor. +# +# (b) A way to fetch the currently-used version out of the source tree. +# +# This is typically parsed out of the depends/packages/*.mk files. +# +# If any dependency is found to be out-of-date, or there are un-accounted-for +# .mk files in depends/packages, this script will exit with +# a nonzero status. The latter case would suggest someone added a new dependency +# without adding a corresponding entry to get_dependency_list() below. +# +# To test the script itself, run it with --functionality-test as the only +# argument. This will exercise the full functionality of the script, but will +# only return a non-zero exit status when there's something wrong with the +# script itself, for example if a new file was added to depends/packages/ but +# wasn't added to this script. + +import requests +import os +import re +import sys +import datetime + +SOURCE_ROOT = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..") + +def get_dependency_list(): + dependencies = [ + Dependency("bdb", + BerkeleyDbReleaseLister(), + DependsVersionGetter("bdb")), + Dependency("boost", + GithubTagReleaseLister("boostorg", "boost", "^boost-(\d+)\.(\d+)\.(\d+)$", + { "boost-1.69.0": (1, 69, 0), "boost-1.69.0-beta1": None }), + DependsVersionGetter("boost")), + Dependency("googletest", + GithubTagReleaseLister("google", "googletest", "^release-(\d+)\.(\d+)\.(\d+)$", + { "release-1.8.1": (1, 8, 1) }), + DependsVersionGetter("googletest")), + # libc++ matches the Clang version + Dependency("libcxx", + GithubTagReleaseLister("llvm", "llvm-project", "^llvmorg-(\d+)\.(\d+).(\d+)$", + { "llvmorg-11.0.0": (11, 0, 0), "llvmorg-9.0.1-rc3": None}), + DependsVersionGetter("native_clang")), + Dependency("libevent", + GithubTagReleaseLister("libevent", "libevent", "^release-(\d+)\.(\d+)\.(\d+)-stable$", + { "release-2.0.22-stable": (2, 0, 22), "release-2.1.9-beta": None }), + DependsVersionGetter("libevent")), + Dependency("libsodium", + GithubTagReleaseLister("jedisct1", "libsodium", "^(\d+)\.(\d+)\.(\d+)$", + { "1.0.17": (1, 0, 17) }), + DependsVersionGetter("libsodium")), + # b2 matches the Boost version + Dependency("native_b2", + GithubTagReleaseLister("boostorg", "boost", "^boost-(\d+)\.(\d+)\.(\d+)$", + { "boost-1.69.0": (1, 69, 0), "boost-1.69.0-beta1": None }), + DependsVersionGetter("boost")), + Dependency("native_ccache", + GithubTagReleaseLister("ccache", "ccache", "^v?(\d+)\.(\d+)(?:\.(\d+))?$", + { "v3.5.1": (3, 5, 1), "v3.6": (3, 6)}), + DependsVersionGetter("native_ccache")), + Dependency("native_clang", + GithubTagReleaseLister("llvm", "llvm-project", "^llvmorg-(\d+)\.(\d+).(\d+)$", + { "llvmorg-11.0.0": (11, 0, 0), "llvmorg-9.0.1-rc3": None}), + DependsVersionGetter("native_clang")), + Dependency("native_rust", + GithubTagReleaseLister("rust-lang", "rust", "^(\d+)\.(\d+)(?:\.(\d+))?$", + { "1.33.0": (1, 33, 0), "0.9": (0, 9) }), + DependsVersionGetter("native_rust")), + Dependency("zeromq", + GithubTagReleaseLister("zeromq", "libzmq", "^v(\d+)\.(\d+)(?:\.(\d+))?$", + { "v4.3.1": (4, 3, 1), "v4.2.0-rc1": None }), + DependsVersionGetter("zeromq")), + Dependency("leveldb", + GithubTagReleaseLister("google", "leveldb", "^v(\d+)\.(\d+)$", + { "v1.13": (1, 13) }), + LevelDbVersionGetter()), + Dependency("univalue", + GithubTagReleaseLister("bitcoin-core", "univalue", "^v(\d+)\.(\d+)\.(\d+)$", + { "v1.0.1": (1, 0, 1) }), + UnivalueVersionGetter()), + Dependency("utfcpp", + GithubTagReleaseLister("nemtrif", "utfcpp", "^v(\d+)\.(\d+)(?:\.(\d+))?$", + { "v3.1": (3, 1), "v3.0.3": (3, 0, 3) }), + DependsVersionGetter("utfcpp")) + ] + + return dependencies + +class GitHubToken: + def __init__(self): + token_path = os.path.join(SOURCE_ROOT, ".updatecheck-token") + try: + with open(token_path, encoding='utf8') as f: + token = f.read().strip() + self._user = token.split(":")[0] + self._password = token.split(":")[1] + except: + print("Please make sure a GitHub API token is in .updatecheck-token in the root of this repository.") + print("The format is username:hex-token.") + sys.exit(1) + + def user(self): + return self.user + + def password(self): + return self.password + +class Version(list): + def __init__(self, version_tuple): + for part in version_tuple: + if part: # skip None's which can come from optional regexp groups + if str(part).isdigit(): + self.append(int(part)) + else: + self.append(part) + + def __str__(self): + return '.'.join(map(str, self)) + + def __hash__(self): + return hash(tuple(self)) + +class Dependency: + def __init__(self, name, release_lister, current_getter): + self.name = name + self.release_lister = release_lister + self.current_getter = current_getter + self.cached_known_releases = None + + def current_version(self): + return self.current_getter.current_version() + + def known_releases(self): + if self.cached_known_releases is None: + self.cached_known_releases = sorted(self.release_lister.known_releases()) + return self.cached_known_releases + + def released_versions_after_current_version(self): + current_version = self.current_version() + releases_after_current = [] + + for release in self.known_releases(): + if release > current_version: + releases_after_current.append(release) + + return releases_after_current + + def is_up_to_date(self): + return len(self.released_versions_after_current_version()) == 0 + +class GithubTagReleaseLister: + def __init__(self, org, repo, regex, testcases={}): + self.org = org + self.repo = repo + self.regex = regex + self.testcases = testcases + self.token = GitHubToken() + + for tag, expected in testcases.items(): + match = re.match(self.regex, tag) + if (expected and not match) or (match and not expected) or (match and Version(match.groups()) != list(expected)): + groups = str(match.groups()) + raise RuntimeError("GitHub tag regex test case [" + tag + "] failed, got [" + groups + "].") + + def known_releases(self): + release_versions = [] + all_tags = self.all_tag_names() + + # sanity check against the test cases + for tag, expected in self.testcases.items(): + if tag not in all_tags: + raise RuntimeError("Didn't find expected tag [" + tag + "].") + + for tag_name in all_tags: + match = re.match(self.regex, tag_name) + if match: + release_versions.append(Version(match.groups())) + + return release_versions + + def all_tag_names(self): + url = "https://api.github.com/repos/" + safe(self.org) + "/" + safe(self.repo) + "/git/refs/tags" + r = requests.get(url, auth=requests.auth.HTTPBasicAuth(self.token.user(), self.token.password())) + if r.status_code != 200: + print("API request failed (error %d)" % (r.status_code,), file=sys.stderr) + print(r.text, file=sys.stderr) + raise RuntimeError("Request to GitHub tag API failed.") + json = r.json() + return list(map(lambda t: t["ref"].split("/")[-1], json)) + +class BerkeleyDbReleaseLister: + def known_releases(self): + url = "https://www.oracle.com/database/technologies/related/berkeleydb-downloads.html" + r = requests.get(url) + if r.status_code != 200: + print("API request failed (error %d)" % (r.status_code,), file=sys.stderr) + print(r.text, file=sys.stderr) + raise RuntimeError("Request to Berkeley DB download directory failed.") + page = r.text + + # We use a set because the search will result in duplicates. + release_versions = set() + for match in re.findall("berkeleydb/html/changelog_(\d+)_(\d+)_(\d+).html", page): + release_versions.add(Version(match)) + + if len(release_versions) == 0: + raise RuntimeError("Missing expected version from Oracle web page.") + + return list(release_versions) + +class DependsVersionGetter: + def __init__(self, name): + self.name = name + + def current_version(self): + mk_file_path = os.path.join(SOURCE_ROOT, "depends", "packages", safe_depends(self.name) + ".mk") + mk_file = open(mk_file_path, 'r', encoding='utf8').read() + + regexp_whitelist = [ + "package\)_version=(\d+)\.(\d+)\.(\d+)$", + "package\)_version=(\d+)\.(\d+)$", + "package\)_version=(\d+)_(\d+)_(\d+)$", + "package\)_version=(\d+)\.(\d+)\.(\d+)([a-z])$", + # Workaround for wasi 0.9.0 preview + "package\)_version=(\d+)\.(\d+)\.(\d+)\+wasi-snapshot-preview1$", + ] + + current_version = None + + for regexp in regexp_whitelist: + match = re.search(regexp, mk_file, re.MULTILINE) + if match: + current_version = Version(match.groups()) + + if not current_version: + raise RuntimeError("Couldn't parse version number from depends .mk file.") + + return current_version + +class LevelDbVersionGetter: + def current_version(self): + header_path = os.path.join(SOURCE_ROOT, "src", "leveldb", "include", "leveldb", "db.h") + header_contents = open(header_path, 'r', encoding='utf8').read() + + match = re.search("kMajorVersion\s*=\s*(\d+);\s*.*kMinorVersion\s*=\s*(\d+);\s*$", header_contents, re.MULTILINE) + if match: + return Version(match.groups()) + else: + raise RuntimeError("Couldn't parse LevelDB's version from db.h") + +class UnivalueVersionGetter: + def current_version(self): + configure_path = os.path.join(SOURCE_ROOT, "src", "univalue", "configure.ac") + configure_contents = open(configure_path, 'r', encoding='utf8').read() + + match = re.search("AC_INIT.*univalue.*\[(\d+)\.(\d+)\.(\d+)\]", configure_contents) + if match: + return Version(match.groups()) + else: + raise RuntimeError("Couldn't parse univalue's version from its configure.ac") + +class PostponedUpdates(): + def __init__(self): + self.postponedlist = dict() + + postponedlist_path = os.path.join( + os.path.dirname(__file__), + "postponed-updates.txt" + ) + + file = open(postponedlist_path, 'r', encoding='utf8') + for line in file.readlines(): + stripped = re.sub('#.*$', '', line).strip() + if stripped != "": + match = re.match('^(\S+)\s+(\S+)\s+(\S+)$', stripped) + if match: + postponed_name = match.groups()[0] + postponed_version = Version(match.groups()[1].split(".")) + postpone_expiration = datetime.datetime.strptime(match.groups()[2], '%Y-%m-%d') + if datetime.datetime.utcnow() < postpone_expiration: + self.postponedlist[(postponed_name, str(postponed_version))] = True + else: + raise RuntimeError("Could not parse line in postponed-updates.txt:" + line) + + + def is_postponed(self, name, version): + return (name, str(version)) in self.postponedlist + +def safe(string): + if re.match('^[a-zA-Z0-9_-]*$', string): + return string + else: + raise RuntimeError("Potentially-dangerous string encountered.") + +def safe_depends(string): + if re.match('^[a-zA-Z0-9._-]*$', string): + return string + else: + raise RuntimeError("Potentially-dangerous string encountered.") + +def print_row(name, status, current_version, known_versions): + COL_FMT_LARGE = "{:<35}" + COL_FMT_SMALL = "{:<18}" + print(COL_FMT_LARGE.format(name) + + COL_FMT_SMALL.format(status) + + COL_FMT_SMALL.format(current_version) + + COL_FMT_SMALL.format(known_versions)) + +def main(): + # Get a list of all depends-system dependencies so we can verify that we're + # checking them all for updates. + unchecked_dependencies = [f[:-3] for f in os.listdir(os.path.join(SOURCE_ROOT, "depends", "packages")) if f.endswith(".mk")] + + untracked = [ + # packages.mk is not a dependency, it just specifies the list of them all. + "packages", + # This package doesn't have conventional version numbers + "native_cctools", + # This package is pinned specifically for Arch. + "native_libtinfo", + ] + + print_row("NAME", "STATUS", "CURRENT VERSION", "NEWER VERSIONS") + + status = 0 + for dep in untracked: + print_row(dep, "skipped", "", "") + if dep in unchecked_dependencies: + unchecked_dependencies.remove(dep) + else: + print("Error: Please remove " + dep + " from the list of unchecked dependencies.") + status = 3 + + # Exit early so the problem is clear from the output. + if status != 0: + sys.exit(status) + + deps = get_dependency_list() + postponed = PostponedUpdates() + for dependency in deps: + if dependency.name in unchecked_dependencies: + unchecked_dependencies.remove(dependency.name) + if dependency.is_up_to_date(): + print_row( + dependency.name, + "up to date", + str(dependency.current_version()), + "") + else: + # The status can either be POSTPONED or OUT OF DATE depending + # on whether or not all the new versions are whitelisted. + status_text = "POSTPONED" + newver_list = "[" + for newver in dependency.released_versions_after_current_version(): + if postponed.is_postponed(dependency.name, newver): + newver_list += str(newver) + " (postponed)," + else: + newver_list += str(newver) + "," + status_text = "OUT OF DATE" + status = 1 + + newver_list = newver_list[:-1] + "]" + + print_row( + dependency.name, + status_text, + str(dependency.current_version()), + newver_list + ) + + if len(unchecked_dependencies) > 0: + unchecked_dependencies.sort() + print("WARNING: The following dependencies are not being checked for updates by this script: " + ', '.join(unchecked_dependencies)) + sys.exit(2) + + if len(sys.argv) == 2 and sys.argv[1] == "--functionality-test": + print("We're only testing this script's functionality. The exit status will only be nonzero if there's a problem with the script itself.") + sys.exit(0) + + if status == 0: + print("All non-Rust dependencies are up-to-date or postponed.") + elif status == 1: + print("Release is BLOCKED. There are new dependency updates that have not been postponed.") + + print(""" +You should also check the Rust dependencies using cargo: + + cargo install cargo-outdated cargo-audit + cargo outdated + cargo audit +""") + if status == 0: + print("After checking those, you'll be ready for release! :-)") + + sys.exit(status) + +main() diff --git a/depend/zcash/rust-toolchain b/depend/zcash/rust-toolchain new file mode 100644 index 000000000..bb120e876 --- /dev/null +++ b/depend/zcash/rust-toolchain @@ -0,0 +1 @@ +1.59.0 diff --git a/depend/zcash/share/genbuild.sh b/depend/zcash/share/genbuild.sh new file mode 100755 index 000000000..6d35faa97 --- /dev/null +++ b/depend/zcash/share/genbuild.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2012-2019 The Bitcoin Core developers +# Copyright (c) 2012-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +export LC_ALL=C +if [ $# -gt 1 ]; then + cd "$2" || exit 1 +fi +if [ $# -gt 0 ]; then + FILE="$1" + shift + if [ -f "$FILE" ]; then + INFO="$(head -n 1 "$FILE")" + fi +else + echo "Usage: $0 " + exit 1 +fi + +DESC="" +SUFFIX="" +LAST_COMMIT_DATE="" +if [ -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ]; then + # clean 'dirty' status of touched files that haven't been modified + git diff >/dev/null 2>/dev/null + + # if latest commit is tagged and not dirty, then override using the tag name + RAWDESC=$(git describe --abbrev=0 2>/dev/null) + if [ "$(git rev-parse HEAD)" = "$(git rev-list -1 $RAWDESC 2>/dev/null)" ]; then + git diff-index --quiet HEAD -- && DESC=$RAWDESC + fi + + # otherwise generate suffix from git, i.e. string like "59887e8-dirty" + SUFFIX=$(git rev-parse --short HEAD) + git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX-dirty" + + # get a string like "2012-04-10 16:27:19 +0200" + LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")" +fi + +if [ -n "$DESC" ]; then + NEWINFO="#define BUILD_DESC \"$DESC\"" +elif [ -n "$SUFFIX" ]; then + NEWINFO="#define BUILD_SUFFIX $SUFFIX" +else + NEWINFO="// No build information available" +fi + +# only update build.h if necessary +if [ "$INFO" != "$NEWINFO" ]; then + echo "$NEWINFO" >"$FILE" + if [ -n "$LAST_COMMIT_DATE" ]; then + echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE" + fi +fi diff --git a/depend/zcash/share/rpcuser/README.md b/depend/zcash/share/rpcuser/README.md new file mode 100644 index 000000000..12a8e6fb0 --- /dev/null +++ b/depend/zcash/share/rpcuser/README.md @@ -0,0 +1,10 @@ +RPC Tools +--------------------- + +### [RPCUser](/share/rpcuser) ### + +Create an RPC user login credential. + +Usage: + + ./rpcuser.py diff --git a/depend/zcash/share/rpcuser/rpcuser.py b/depend/zcash/share/rpcuser/rpcuser.py new file mode 100755 index 000000000..a57508c92 --- /dev/null +++ b/depend/zcash/share/rpcuser/rpcuser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +import hashlib +import sys +import os +from random import SystemRandom +import base64 +import hmac + +if len(sys.argv) < 2: + sys.stderr.write('Please include username as an argument.\n') + sys.exit(0) + +username = sys.argv[1] + +#This uses os.urandom() underneath +cryptogen = SystemRandom() + +#Create 16 byte hex salt +salt_sequence = [cryptogen.randrange(256) for i in range(16)] +hexseq = list(map(hex, salt_sequence)) +salt = "".join([x[2:] for x in hexseq]) + +#Create 32 byte b64 password +password = base64.urlsafe_b64encode(os.urandom(32)) + +digestmod = hashlib.sha256 + +if sys.version_info.major >= 3: + password = password.decode('utf-8') + digestmod = 'SHA256' + +m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), digestmod) +result = m.hexdigest() + +print("String to be appended to zcash.conf:") +print("rpcauth="+username+":"+salt+"$"+result) +print("Your password:\n"+password) diff --git a/depend/zcash/src/.clang-format b/depend/zcash/src/.clang-format new file mode 100644 index 000000000..401a4272e --- /dev/null +++ b/depend/zcash/src/.clang-format @@ -0,0 +1,50 @@ +AccessModifierOffset: -4 +AlignEscapedNewlinesLeft: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackParameters: false +BreakBeforeBinaryOperators: false +BreakBeforeBraces: Linux +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +IndentCaseLabels: false +IndentFunctionDeclarationAfterType: false +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never diff --git a/depend/zcash/src/Makefile.am b/depend/zcash/src/Makefile.am new file mode 100644 index 000000000..efeb9f0f3 --- /dev/null +++ b/depend/zcash/src/Makefile.am @@ -0,0 +1,670 @@ +# Copyright (c) 2016-2019 The Zcash developers +# Copyright (c) 2013-2019 The Bitcoin Core developers +# Copyright (c) 2013-2019 Bitcoin Developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or https://www.opensource.org/licenses/mit-license.php . + +DIST_SUBDIRS = secp256k1 univalue + +AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) +AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) +AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS) +EXTRA_LIBRARIES = + +BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config +BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) + +BITCOIN_CONFIG_INCLUDES += -I$(srcdir)/rust/include +BITCOIN_INCLUDES += -I$(srcdir)/rust/include +BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include +BITCOIN_INCLUDES += -I$(srcdir)/univalue/include + +LIBBITCOIN_SERVER=libbitcoin_server.a +LIBBITCOIN_COMMON=libbitcoin_common.a +LIBBITCOIN_CLI=libbitcoin_cli.a +LIBBITCOIN_UTIL=libbitcoin_util.a +LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a +LIBRUSTZCASH=$(top_builddir)/target/$(RUST_TARGET)/release/librustzcash.a +LIBSECP256K1=secp256k1/libsecp256k1.la +LIBUNIVALUE=univalue/libunivalue.la +LIBZCASH=libzcash.a + +WALLET_TOOL_BIN=zcashd-wallet-tool$(EXEEXT) +WALLET_TOOL_BUILD=$(top_builddir)/target/$(RUST_TARGET)/release/zcashd-wallet-tool$(EXEEXT) + +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a +endif +if BUILD_BITCOIN_LIBS +LIBZCASH_SCRIPT=libzcash_script.la +endif +if ENABLE_WALLET +LIBBITCOIN_WALLET=libbitcoin_wallet.a +endif + +# We depend on the secp256k1 crate for some logic on the Rust side of the FFI. This crate +# is a wrapper around libsecp256k1, which we already vendor in our code; the crate vendors +# its own copy with non-colliding symbols. To ensure that we only use a single version of +# libsecp256k1, we disable symbol renaming in the secp256k1-sys crate so it links to the +# same library as the C++ code. +# - Note that this does not prevent the secp256k1-sys vendored code from being built; this +# requires https://github.com/rust-bitcoin/rust-secp256k1/issues/380 to be addressed. +RUST_ENV_VARS = RUSTC="$(RUSTC)" TERM=dumb RUSTFLAGS="--cfg=rust_secp_no_symbol_renaming" +RUST_BUILD_OPTS = --release --target $(RUST_TARGET) --manifest-path $(top_srcdir)/Cargo.toml + +rust_verbose = $(rust_verbose_@AM_V@) +rust_verbose_ = $(rust_verbose_@AM_DEFAULT_V@) +rust_verbose_1 = --verbose + +if ENABLE_ONLINE_RUST +# Ensure that .cargo/config does not exist +CARGO_CONFIGURED = $(top_srcdir)/.cargo/.configured-for-online +$(CARGO_CONFIGURED): + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-offline $(top_srcdir)/.cargo/config + $(AM_V_at)touch $@ + +else +# Enable dependency vendoring +RUST_BUILD_OPTS += --locked --offline + +CARGO_CONFIGURED = $(top_srcdir)/.cargo/.configured-for-offline +$(CARGO_CONFIGURED): $(top_srcdir)/.cargo/config.offline + $(AM_V_at)rm -f $(top_srcdir)/.cargo/.configured-for-online + $(AM_V_at)cp $< $(top_srcdir)/.cargo/config + $(AM_V_at)echo "directory = \"$(RUST_VENDORED_SOURCES)\"" >>$(top_srcdir)/.cargo/config + $(AM_V_at)touch $@ +endif + +cargo-build-lib: $(CARGO_CONFIGURED) + $(RUST_ENV_VARS) $(CARGO) build --lib $(RUST_BUILD_OPTS) $(rust_verbose) + +cargo-build-bins: $(CARGO_CONFIGURED) + $(RUST_ENV_VARS) $(CARGO) build --bins $(RUST_BUILD_OPTS) $(rust_verbose) + +$(WALLET_TOOL_BIN): cargo-build-bins + $(AM_V_at)cp $(WALLET_TOOL_BUILD) $@ + +$(LIBRUSTZCASH): cargo-build-lib + +$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) + +$(LIBUNIVALUE): $(wildcard univalue/lib/*) $(wildcard univalue/include/*) + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) + +# 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: +EXTRA_LIBRARIES += \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_CLI) \ + $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_ZMQ) \ + $(LIBZCASH) + +lib_LTLIBRARIES = $(LIBZCASH_SCRIPT) + +bin_PROGRAMS = +noinst_PROGRAMS = +bin_SCRIPTS = +TESTS = +BENCHMARKS = + +if BUILD_BITCOIND + bin_PROGRAMS += zcashd +endif + +if BUILD_BITCOIN_UTILS + bin_PROGRAMS += zcash-cli zcash-tx + bin_SCRIPTS += $(WALLET_TOOL_BIN) +endif + +LIBZCASH_H = \ + zcash/IncrementalMerkleTree.hpp \ + zcash/NoteEncryption.hpp \ + zcash/Address.hpp \ + zcash/address/transparent.h \ + zcash/address/mnemonic.h \ + zcash/address/orchard.hpp \ + zcash/address/sapling.hpp \ + zcash/address/sprout.hpp \ + zcash/address/unified.h \ + zcash/address/zip32.h \ + zcash/History.hpp \ + zcash/JoinSplit.hpp \ + zcash/Note.hpp \ + zcash/prf.h \ + zcash/Proof.hpp \ + zcash/util.h \ + zcash/Zcash.h + +.PHONY: FORCE cargo-build-lib cargo-build-bins check-symbols check-security +# bitcoin core # +BITCOIN_CORE_H = \ + addrdb.h \ + addressindex.h \ + addrman.h \ + alert.h \ + amount.h \ + arith_uint256.h \ + asyncrpcoperation.h \ + asyncrpcqueue.h \ + base58.h \ + bech32.h \ + bloom.h \ + chain.h \ + chainparams.h \ + chainparamsbase.h \ + chainparamsseeds.h \ + checkpoints.h \ + checkqueue.h \ + clientversion.h \ + coincontrol.h \ + coins.h \ + compat.h \ + compat/byteswap.h \ + compat/endian.h \ + compat/sanity.h \ + compressor.h \ + consensus/consensus.h \ + consensus/funding.h \ + consensus/params.h \ + consensus/upgrades.h \ + consensus/validation.h \ + core_io.h \ + core_memusage.h \ + deprecation.h \ + experimental_features.h \ + fs.h \ + hash.h \ + httprpc.h \ + httpserver.h \ + init.h \ + key.h \ + key_constants.h \ + key_io.h \ + keystore.h \ + dbwrapper.h \ + limitedmap.h \ + logging.h \ + main.h \ + memusage.h \ + merkleblock.h \ + metrics.h \ + miner.h \ + net.h \ + netbase.h \ + noui.h \ + policy/fees.h \ + policy/policy.h \ + pow.h \ + prevector.h \ + primitives/block.h \ + primitives/orchard.h \ + primitives/transaction.h \ + proof_verifier.h \ + protocol.h \ + pubkey.h \ + random.h \ + reverse_iterator.h \ + reverselock.h \ + rpc/client.h \ + rpc/protocol.h \ + rpc/server.h \ + rpc/register.h \ + scheduler.h \ + script/interpreter.h \ + script/script.h \ + script/script_error.h \ + script/sigcache.h \ + script/sign.h \ + script/standard.h \ + script/ismine.h \ + serialize.h \ + spentindex.h \ + streams.h \ + support/allocators/secure.h \ + support/allocators/zeroafterfree.h \ + support/cleanse.h \ + support/events.h \ + support/lockedpool.h \ + sync.h \ + threadsafety.h \ + timedata.h \ + timestampindex.h \ + tinyformat.h \ + torcontrol.h \ + transaction_builder.h \ + txdb.h \ + mempool_limit.h \ + txmempool.h \ + ui_interface.h \ + uint256.h \ + uint252.h \ + undo.h \ + util.h \ + util/match.h \ + utilmoneystr.h \ + utilstrencodings.h \ + utiltest.h \ + utiltime.h \ + validationinterface.h \ + version.h \ + wallet/asyncrpcoperation_common.h \ + wallet/asyncrpcoperation_mergetoaddress.h \ + wallet/asyncrpcoperation_saplingmigration.h \ + wallet/asyncrpcoperation_sendmany.h \ + wallet/asyncrpcoperation_shieldcoinbase.h \ + wallet/crypter.h \ + wallet/db.h \ + wallet/orchard.h \ + wallet/paymentdisclosure.h \ + wallet/paymentdisclosuredb.h \ + wallet/rpcwallet.h \ + wallet/wallet.h \ + wallet/walletdb.h \ + warnings.h \ + zmq/zmqabstractnotifier.h \ + zmq/zmqconfig.h\ + zmq/zmqnotificationinterface.h \ + zmq/zmqpublishnotifier.h + + +obj/build.h: FORCE + @$(MKDIR_P) $(builddir)/obj + @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ + $(abs_top_srcdir) +libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h + +# server: zcashd +libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_server_a_SOURCES = \ + sendalert.cpp \ + addrman.cpp \ + addrdb.cpp \ + alert.cpp \ + alertkeys.h \ + asyncrpcoperation.cpp \ + asyncrpcqueue.cpp \ + bloom.cpp \ + chain.cpp \ + checkpoints.cpp \ + deprecation.cpp \ + experimental_features.cpp \ + httprpc.cpp \ + httpserver.cpp \ + init.cpp \ + dbwrapper.cpp \ + main.cpp \ + merkleblock.cpp \ + metrics.cpp \ + miner.cpp \ + net.cpp \ + noui.cpp \ + policy/fees.cpp \ + policy/policy.cpp \ + pow.cpp \ + rest.cpp \ + rpc/blockchain.cpp \ + rpc/mining.cpp \ + rpc/misc.cpp \ + rpc/net.cpp \ + rpc/rawtransaction.cpp \ + rpc/server.cpp \ + script/sigcache.cpp \ + script/ismine.cpp \ + timedata.cpp \ + torcontrol.cpp \ + txdb.cpp \ + mempool_limit.cpp \ + txmempool.cpp \ + validationinterface.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) + +if ENABLE_ZMQ +libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) +libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_zmq_a_SOURCES = \ + zmq/zmqabstractnotifier.cpp \ + zmq/zmqnotificationinterface.cpp \ + zmq/zmqpublishnotifier.cpp +endif + +# wallet: zcashd, 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 = \ + zcbenchmarks.cpp \ + zcbenchmarks.h \ + wallet/asyncrpcoperation_common.cpp \ + wallet/asyncrpcoperation_mergetoaddress.cpp \ + wallet/asyncrpcoperation_saplingmigration.cpp \ + wallet/asyncrpcoperation_sendmany.cpp \ + wallet/asyncrpcoperation_shieldcoinbase.cpp \ + wallet/crypter.cpp \ + wallet/db.cpp \ + wallet/orchard.cpp \ + wallet/paymentdisclosure.cpp \ + wallet/paymentdisclosuredb.cpp \ + wallet/rpcdisclosure.cpp \ + wallet/rpcdump.cpp \ + wallet/rpcwallet.cpp \ + wallet/wallet.cpp \ + wallet/walletdb.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) + +# crypto primitives library +crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES) +crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +crypto_libbitcoin_crypto_a_SOURCES = \ + crypto/aes.cpp \ + crypto/aes.h \ + crypto/chacha20.h \ + crypto/chacha20.cpp \ + crypto/common.h \ + crypto/equihash.cpp \ + crypto/equihash.h \ + crypto/equihash.tcc \ + crypto/hmac_sha256.cpp \ + crypto/hmac_sha256.h \ + crypto/hmac_sha512.cpp \ + crypto/hmac_sha512.h \ + crypto/ripemd160.cpp \ + crypto/ripemd160.h \ + crypto/sha1.cpp \ + crypto/sha1.h \ + crypto/sha256.cpp \ + crypto/sha256.h \ + crypto/sha512.cpp \ + crypto/sha512.h + +if ENABLE_MINING +EQUIHASH_TROMP_SOURCES = \ + pow/tromp/equi_miner.h \ + pow/tromp/equi.h \ + pow/tromp/osx_barrier.h + +crypto_libbitcoin_crypto_a_CPPFLAGS += \ + -DEQUIHASH_TROMP_ATOMIC +crypto_libbitcoin_crypto_a_SOURCES += \ + ${EQUIHASH_TROMP_SOURCES} +endif + +# common: shared between zcashd and non-server tools +libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_common_a_SOURCES = \ + amount.cpp \ + arith_uint256.cpp \ + base58.cpp \ + bech32.cpp \ + chainparams.cpp \ + coins.cpp \ + compressor.cpp \ + consensus/funding.cpp \ + consensus/params.cpp \ + consensus/upgrades.cpp \ + core_read.cpp \ + core_write.cpp \ + hash.cpp \ + key.cpp \ + key_io.cpp \ + keystore.cpp \ + netbase.cpp \ + primitives/block.cpp \ + primitives/transaction.cpp \ + primitives/tx_version_info.cpp \ + proof_verifier.cpp \ + protocol.cpp \ + pubkey.cpp \ + scheduler.cpp \ + script/interpreter.cpp \ + script/script.cpp \ + script/script_error.cpp \ + script/sign.cpp \ + script/standard.cpp \ + transaction_builder.cpp \ + utiltest.cpp \ + warnings.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) + +# util: shared between all executables. +# This library *must* be included to make sure that the glibc +# backward-compatibility objects and their sanity checks are linked. +libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_util_a_SOURCES = \ + support/lockedpool.cpp \ + chainparamsbase.cpp \ + clientversion.cpp \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ + compat/strnlen.cpp \ + fs.cpp \ + logging.cpp \ + random.cpp \ + rpc/protocol.cpp \ + support/cleanse.cpp \ + sync.cpp \ + uint256.cpp \ + util.cpp \ + utilmoneystr.cpp \ + utilstrencodings.cpp \ + utiltime.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) + +if GLIBC_BACK_COMPAT +libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp +endif + +# cli: zcash-cli +libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_cli_a_SOURCES = \ + rpc/client.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) + +nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h +# + +# bitcoind binary # +zcashd_SOURCES = bitcoind.cpp +zcashd_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +zcashd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +zcashd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +zcashd_SOURCES += bitcoind-res.rc +endif + +zcashd_LDADD = \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_WALLET) \ + $(LIBBITCOIN_COMMON) \ + $(LIBUNIVALUE) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_ZMQ) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBZCASH) \ + $(LIBRUSTZCASH) \ + $(LIBLEVELDB) \ + $(LIBLEVELDB_SSE42) \ + $(LIBMEMENV) \ + $(LIBSECP256K1) + +zcashd_LDADD += \ + $(BOOST_LIBS) \ + $(BDB_LIBS) \ + $(EVENT_PTHREADS_LIBS) \ + $(EVENT_LIBS) \ + $(ZMQ_LIBS) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBZCASH_LIBS) + +# bitcoin-cli binary # +zcash_cli_SOURCES = bitcoin-cli.cpp +zcash_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +zcash_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +zcash_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +zcash_cli_SOURCES += bitcoin-cli-res.rc +endif + +zcash_cli_LDADD = \ + $(LIBBITCOIN_CLI) \ + $(LIBUNIVALUE) \ + $(LIBBITCOIN_UTIL) \ + $(BOOST_LIBS) \ + $(EVENT_LIBS) \ + $(LIBZCASH) \ + $(LIBRUSTZCASH) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBSECP256K1) \ + $(LIBZCASH_LIBS) +# + +# zcash-tx binary # +zcash_tx_SOURCES = bitcoin-tx.cpp +zcash_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +zcash_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +zcash_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if TARGET_WINDOWS +zcash_tx_SOURCES += bitcoin-tx-res.rc +endif + +# FIXME: Is libzcash needed for zcash_tx? +zcash_tx_LDADD = \ + $(LIBUNIVALUE) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_UTIL) \ + $(LIBSECP256K1) \ + $(LIBZCASH) \ + $(LIBRUSTZCASH) \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBZCASH_LIBS) + +zcash_tx_LDADD += $(BOOST_LIBS) +# + +# zcash protocol primitives # +libzcash_a_SOURCES = \ + zcash/IncrementalMerkleTree.cpp \ + zcash/NoteEncryption.cpp \ + zcash/Address.cpp \ + zcash/address/transparent.cpp \ + zcash/address/mnemonic.cpp \ + zcash/address/orchard.cpp \ + zcash/address/sapling.cpp \ + zcash/address/sprout.cpp \ + zcash/address/unified.cpp \ + zcash/address/zip32.cpp \ + zcash/History.cpp \ + zcash/JoinSplit.cpp \ + zcash/Note.cpp \ + zcash/prf.cpp \ + zcash/util.cpp + +libzcash_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIC_FLAGS) $(BITCOIN_INCLUDES) +libzcash_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libzcash_a_LDFLAGS = $(AM_LDFLAGS) + +# zcash_script library # +if BUILD_BITCOIN_LIBS +include_HEADERS = script/zcash_script.h +libzcash_script_la_SOURCES = \ + crypto/hmac_sha512.cpp \ + crypto/ripemd160.cpp \ + crypto/sha1.cpp \ + crypto/sha256.cpp \ + crypto/sha512.cpp \ + hash.cpp \ + primitives/transaction.cpp \ + primitives/tx_version_info.cpp \ + pubkey.cpp \ + script/zcash_script.cpp \ + script/interpreter.cpp \ + script/script.cpp \ + uint256.cpp \ + utilstrencodings.cpp + +if GLIBC_BACK_COMPAT + libzcash_script_la_SOURCES += compat/glibc_compat.cpp +endif + +libzcash_script_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) +libzcash_script_la_LIBADD = $(LIBSECP256K1) +libzcash_script_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/rust/include -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL +libzcash_script_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) + +endif +# + +CTAES_DIST = crypto/ctaes/bench.c +CTAES_DIST += crypto/ctaes/ctaes.c +CTAES_DIST += crypto/ctaes/ctaes.h +CTAES_DIST += crypto/ctaes/README.md +CTAES_DIST += crypto/ctaes/test.c + +CLEANFILES = *.gcda *.gcno */*.gcno wallet/*/*.gcno $(bin_SCRIPTS) + +DISTCLEANFILES = obj/build.h + +EXTRA_DIST = $(CTAES_DIST) rust + +clean-local: + rm -f $(top_srcdir)/.cargo/config $(top_srcdir)/.cargo/.configured-for-* + -$(MAKE) -C secp256k1 clean + -$(MAKE) -C univalue clean + rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno + rm -f fuzz.cpp + rm -rf fuzzing/*/output + -rm -f config.h + -rm -f *.lib bench/*.lib test/*.lib + +.rc.o: + @test -f $(WINDRES) + $(AM_V_GEN) $(WINDRES) -DWINDRES_PREPROC -i $< -o $@ + +.mm.o: + $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CXXFLAGS) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< + +check-symbols: $(bin_PROGRAMS) $(bin_SCRIPTS) +if GLIBC_BACK_COMPAT + @echo "Checking glibc back compat of [$(bin_PROGRAMS) $(bin_SCRIPTS)]..." + $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) $(bin_SCRIPTS) +endif + +check-security: $(bin_PROGRAMS) $(bin_SCRIPTS) +if HARDEN + @echo "Checking binary security of [$(bin_PROGRAMS) $(bin_SCRIPTS)]..." + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS) + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py --allow-no-canary $(bin_SCRIPTS) +endif + +%.pb.cc %.pb.h: %.proto + @test -f $(PROTOC) + $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$(abspath $( $*.log 2>&1 || (cat $*.log && false) + +parallel_btests: $(SUITES) + +%.json.h: %.json + @$(MKDIR_P) $(@D) + @echo "namespace json_tests{" > $@ + @echo "static unsigned const char $(*F)[] = {" >> $@ + @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@ + @echo "};};" >> $@ + @echo "Generated $@" + +%.raw.h: %.raw + @$(MKDIR_P) $(@D) + @echo "namespace alert_tests{" > $@ + @echo "static unsigned const char $(*F)[] = {" >> $@ + @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $< | $(SED) -e 's/0x ,//g' >> $@ + @echo "};};" >> $@ + @echo "Generated $@" diff --git a/depend/zcash/src/addrdb.cpp b/depend/zcash/src/addrdb.cpp new file mode 100644 index 000000000..81d011dbd --- /dev/null +++ b/depend/zcash/src/addrdb.cpp @@ -0,0 +1,218 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 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 "addrdb.h" + +#include "addrman.h" +#include "chainparams.h" +#include "clientversion.h" +#include "hash.h" +#include "random.h" +#include "streams.h" +#include "tinyformat.h" +#include "util.h" + +#include + +CBanDB::CBanDB() +{ + pathBanlist = GetDataDir() / "banlist.dat"; +} + +bool CBanDB::Write(const banmap_t& banSet) +{ + // Generate random temporary filename + unsigned short randv = 0; + GetRandBytes((unsigned char*)&randv, sizeof(randv)); + std::string tmpfn = strprintf("banlist.dat.%04x", randv); + + // serialize banlist, checksum data up to that point, then append csum + CDataStream ssBanlist(SER_DISK, CLIENT_VERSION); + ssBanlist << FLATDATA(Params().MessageStart()); + ssBanlist << banSet; + uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end()); + ssBanlist << hash; + + // open temp output file, and associate with CAutoFile + fs::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s: Failed to open file %s", __func__, pathTmp.string()); + + // Write and commit header, data + try { + fileout << ssBanlist; + } + catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + FileCommit(fileout.Get()); + fileout.fclose(); + + // replace existing banlist.dat, if any, with new banlist.dat.XXXX + if (!RenameOver(pathTmp, pathBanlist)) + return error("%s: Rename-into-place failed", __func__); + + return true; +} + +bool CBanDB::Read(banmap_t& banSet) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathBanlist.string().c_str(), "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, pathBanlist.string()); + + // use file size to size memory buffer + uint64_t fileSize = fs::file_size(pathBanlist); + uint64_t dataSize = 0; + // Don't try to resize to a negative number if file is small + if (fileSize >= sizeof(uint256)) + dataSize = fileSize - sizeof(uint256); + std::vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + filein.fclose(); + + CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end()); + if (hashIn != hashTmp) + return error("%s: Checksum mismatch, data corrupted", __func__); + + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (network specific magic number) and .. + ssBanlist >> FLATDATA(pchMsgTmp); + + // ... verify the network matches ours + if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) + return error("%s: Invalid network magic number", __func__); + + // de-serialize address data into one CAddrMan object + ssBanlist >> banSet; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + + return true; +} + +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} + +bool CAddrDB::Write(const CAddrMan& addr) +{ + // Generate random temporary filename + unsigned short randv = 0; + GetRandBytes((unsigned char*)&randv, sizeof(randv)); + std::string tmpfn = strprintf("peers.dat.%04x", randv); + + // serialize addresses, checksum data up to that point, then append csum + CDataStream ssPeers(SER_DISK, CLIENT_VERSION); + ssPeers << FLATDATA(Params().MessageStart()); + ssPeers << addr; + uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); + ssPeers << hash; + + // open temp output file, and associate with CAutoFile + fs::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fsbridge::fopen(pathTmp, "wb"); + CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s: Failed to open file %s", __func__, pathTmp.string()); + + // Write and commit header, data + try { + fileout << ssPeers; + } + catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + FileCommit(fileout.Get()); + fileout.fclose(); + + // replace existing peers.dat, if any, with new peers.dat.XXXX + if (!RenameOver(pathTmp, pathAddr)) + return error("%s: Rename-into-place failed", __func__); + + return true; +} + +bool CAddrDB::Read(CAddrMan& addr) +{ + // open input file, and associate with CAutoFile + FILE *file = fsbridge::fopen(pathAddr, "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, pathAddr.string()); + + // use file size to size memory buffer + uint64_t fileSize = fs::file_size(pathAddr); + uint64_t dataSize = 0; + // Don't try to resize to a negative number if file is small + if (fileSize >= sizeof(uint256)) + dataSize = fileSize - sizeof(uint256); + std::vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + filein.fclose(); + + CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + if (hashIn != hashTmp) + return error("%s: Checksum mismatch, data corrupted", __func__); + + return Read(addr, ssPeers); +} + +bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers) +{ + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (network specific magic number) and .. + ssPeers >> FLATDATA(pchMsgTmp); + + // ... verify the network matches ours + if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) + return error("%s: Invalid network magic number", __func__); + + // de-serialize address data into one CAddrMan object + ssPeers >> addr; + } + catch (const std::exception& e) { + // de-serialization has failed, ensure addrman is left in a clean state + addr.Clear(); + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + + return true; +} diff --git a/depend/zcash/src/addrdb.h b/depend/zcash/src/addrdb.h new file mode 100644 index 000000000..46eed7db1 --- /dev/null +++ b/depend/zcash/src/addrdb.h @@ -0,0 +1,102 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 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_ADDRDB_H +#define BITCOIN_ADDRDB_H + +#include "fs.h" +#include "serialize.h" +#include "streams.h" + +#include +#include + +class CSubNet; +class CAddrMan; + +typedef enum BanReason +{ + BanReasonUnknown = 0, + BanReasonNodeMisbehaving = 1, + BanReasonManuallyAdded = 2 +} BanReason; + +class CBanEntry +{ +public: + static const int CURRENT_VERSION=1; + int nVersion; + int64_t nCreateTime; + int64_t nBanUntil; + uint8_t banReason; + + CBanEntry() + { + SetNull(); + } + + CBanEntry(int64_t nCreateTimeIn) + { + SetNull(); + nCreateTime = nCreateTimeIn; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(this->nVersion); + READWRITE(nCreateTime); + READWRITE(nBanUntil); + READWRITE(banReason); + } + + void SetNull() + { + nVersion = CBanEntry::CURRENT_VERSION; + nCreateTime = 0; + nBanUntil = 0; + banReason = BanReasonUnknown; + } + + std::string banReasonToString() + { + switch (banReason) { + case BanReasonNodeMisbehaving: + return "node misbehaving"; + case BanReasonManuallyAdded: + return "manually added"; + default: + return "unknown"; + } + } +}; + +typedef std::map banmap_t; + +/** Access to the (IP) address database (peers.dat) */ +class CAddrDB +{ +private: + fs::path pathAddr; +public: + CAddrDB(); + bool Write(const CAddrMan& addr); + bool Read(CAddrMan& addr); + bool Read(CAddrMan& addr, CDataStream& ssPeers); +}; + +/** Access to the banlist database (banlist.dat) */ +class CBanDB +{ +private: + fs::path pathBanlist; +public: + CBanDB(); + bool Write(const banmap_t& banSet); + bool Read(banmap_t& banSet); +}; + +#endif // BITCOIN_ADDRDB_H diff --git a/depend/zcash/src/addressindex.h b/depend/zcash/src/addressindex.h new file mode 100644 index 000000000..1cbd30001 --- /dev/null +++ b/depend/zcash/src/addressindex.h @@ -0,0 +1,287 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_ADDRESSINDEX_H +#define BITCOIN_ADDRESSINDEX_H + +#include "uint256.h" +#include "amount.h" +#include "script/script.h" + +struct CAddressUnspentKey { + unsigned int type; + uint160 hashBytes; + uint256 txhash; + size_t index; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 57; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + txhash.Serialize(s); + ser_writedata32(s, index); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + txhash.Unserialize(s); + index = ser_readdata32(s); + } + + CAddressUnspentKey(unsigned int addressType, uint160 addressHash, uint256 txid, size_t indexValue) { + type = addressType; + hashBytes = addressHash; + txhash = txid; + index = indexValue; + } + + CAddressUnspentKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + txhash.SetNull(); + index = 0; + } +}; + +struct CAddressUnspentValue { + CAmount satoshis; + CScript script; + int blockHeight; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(satoshis); + READWRITE(*(CScriptBase*)(&script)); + READWRITE(blockHeight); + } + + CAddressUnspentValue(CAmount sats, CScript scriptPubKey, int height) { + satoshis = sats; + script = scriptPubKey; + blockHeight = height; + } + + CAddressUnspentValue() { + SetNull(); + } + + void SetNull() { + satoshis = -1; + script.clear(); + blockHeight = 0; + } + + bool IsNull() const { + return (satoshis == -1); + } +}; + +struct CAddressIndexKey { + unsigned int type; + uint160 hashBytes; + int blockHeight; + unsigned int txindex; + uint256 txhash; + size_t index; + bool spending; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 66; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + // Heights are stored big-endian for key sorting in LevelDB + ser_writedata32be(s, blockHeight); + ser_writedata32be(s, txindex); + txhash.Serialize(s); + ser_writedata32(s, index); + char f = spending; + ser_writedata8(s, f); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + blockHeight = ser_readdata32be(s); + txindex = ser_readdata32be(s); + txhash.Unserialize(s); + index = ser_readdata32(s); + char f = ser_readdata8(s); + spending = f; + } + + CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex, + uint256 txid, size_t indexValue, bool isSpending) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + txindex = blockindex; + txhash = txid; + index = indexValue; + spending = isSpending; + } + + CAddressIndexKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + txindex = 0; + txhash.SetNull(); + index = 0; + spending = false; + } + +}; + +struct CAddressIndexIteratorKey { + unsigned int type; + uint160 hashBytes; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 21; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + } + + CAddressIndexIteratorKey(unsigned int addressType, uint160 addressHash) { + type = addressType; + hashBytes = addressHash; + } + + CAddressIndexIteratorKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + } +}; + +struct CAddressIndexIteratorHeightKey { + unsigned int type; + uint160 hashBytes; + int blockHeight; + + size_t GetSerializeSize(int nType, int nVersion) const { + return 25; + } + template + void Serialize(Stream& s) const { + ser_writedata8(s, type); + hashBytes.Serialize(s); + ser_writedata32be(s, blockHeight); + } + template + void Unserialize(Stream& s) { + type = ser_readdata8(s); + hashBytes.Unserialize(s); + blockHeight = ser_readdata32be(s); + } + + CAddressIndexIteratorHeightKey(unsigned int addressType, uint160 addressHash, int height) { + type = addressType; + hashBytes = addressHash; + blockHeight = height; + } + + CAddressIndexIteratorHeightKey() { + SetNull(); + } + + void SetNull() { + type = 0; + hashBytes.SetNull(); + blockHeight = 0; + } +}; + +struct CMempoolAddressDelta +{ + int64_t time; + CAmount amount; + uint256 prevhash; + unsigned int prevout; + + CMempoolAddressDelta(int64_t t, CAmount a, uint256 hash, unsigned int out) { + time = t; + amount = a; + prevhash = hash; + prevout = out; + } + + CMempoolAddressDelta(int64_t t, CAmount a) { + time = t; + amount = a; + prevhash.SetNull(); + prevout = 0; + } +}; + +struct CMempoolAddressDeltaKey +{ + int type; + uint160 addressBytes; + uint256 txhash; + unsigned int index; + int spending; + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash, uint256 hash, unsigned int i, int s) { + type = addressType; + addressBytes = addressHash; + txhash = hash; + index = i; + spending = s; + } + + CMempoolAddressDeltaKey(int addressType, uint160 addressHash) { + type = addressType; + addressBytes = addressHash; + txhash.SetNull(); + index = 0; + spending = 0; + } +}; + +struct CMempoolAddressDeltaKeyCompare +{ + bool operator()(const CMempoolAddressDeltaKey& a, const CMempoolAddressDeltaKey& b) const { + if (a.type != b.type) + return a.type < b.type; + if (a.addressBytes != b.addressBytes) + return a.addressBytes < b.addressBytes; + if (a.txhash != b.txhash) + return a.txhash < b.txhash; + if (a.index != b.index) + return a.index < b.index; + return a.spending < b.spending; + } +}; + +#endif // BITCOIN_ADDRESSINDEX_H diff --git a/depend/zcash/src/addrman.cpp b/depend/zcash/src/addrman.cpp new file mode 100644 index 000000000..4557b990a --- /dev/null +++ b/depend/zcash/src/addrman.cpp @@ -0,0 +1,517 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "addrman.h" + +#include "hash.h" +#include "serialize.h" +#include "streams.h" + +int CAddrInfo::GetTriedBucket(const uint256& nKey) const +{ + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetKey()).GetHash().GetCheapHash(); + uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << (hash1 % ADDRMAN_TRIED_BUCKETS_PER_GROUP)).GetHash().GetCheapHash(); + return hash2 % ADDRMAN_TRIED_BUCKET_COUNT; +} + +int CAddrInfo::GetNewBucket(const uint256& nKey, const CNetAddr& src) const +{ + std::vector vchSourceGroupKey = src.GetGroup(); + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup() << vchSourceGroupKey).GetHash().GetCheapHash(); + uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetHash().GetCheapHash(); + return hash2 % ADDRMAN_NEW_BUCKET_COUNT; +} + +int CAddrInfo::GetBucketPosition(const uint256 &nKey, bool fNew, int nBucket) const +{ + uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << (fNew ? 'N' : 'K') << nBucket << GetKey()).GetHash().GetCheapHash(); + return hash1 % ADDRMAN_BUCKET_SIZE; +} + +bool CAddrInfo::IsTerrible(int64_t nNow) const +{ + if (nLastTry && nLastTry >= nNow - 60) // never remove things tried in the last minute + return false; + + if (nTime > nNow + 10 * 60) // came in a flying DeLorean + return true; + + if (nTime == 0 || nNow - nTime > ADDRMAN_HORIZON_DAYS * 24 * 60 * 60) // not seen in recent history + return true; + + if (nLastSuccess == 0 && nAttempts >= ADDRMAN_RETRIES) // tried N times and never a success + return true; + + if (nNow - nLastSuccess > ADDRMAN_MIN_FAIL_DAYS * 24 * 60 * 60 && nAttempts >= ADDRMAN_MAX_FAILURES) // N successive failures in the last week + return true; + + return false; +} + +double CAddrInfo::GetChance(int64_t nNow) const +{ + double fChance = 1.0; + + int64_t nSinceLastSeen = nNow - nTime; + int64_t nSinceLastTry = nNow - nLastTry; + + if (nSinceLastSeen < 0) + nSinceLastSeen = 0; + if (nSinceLastTry < 0) + nSinceLastTry = 0; + + // deprioritize very recent attempts away + if (nSinceLastTry < 60 * 10) + fChance *= 0.01; + + // deprioritize 66% after each failed attempt, but at most 1/28th to avoid the search taking forever or overly penalizing outages. + fChance *= pow(0.66, std::min(nAttempts, 8)); + + return fChance; +} + +CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int* pnId) +{ + std::map::iterator it = mapAddr.find(addr); + if (it == mapAddr.end()) + return NULL; + if (pnId) + *pnId = (*it).second; + std::map::iterator it2 = mapInfo.find((*it).second); + if (it2 != mapInfo.end()) + return &(*it2).second; + return NULL; +} + +CAddrInfo* CAddrMan::Create(const CAddress& addr, const CNetAddr& addrSource, int* pnId) +{ + int nId = nIdCount++; + mapInfo[nId] = CAddrInfo(addr, addrSource); + mapAddr[addr] = nId; + mapInfo[nId].nRandomPos = vRandom.size(); + vRandom.push_back(nId); + if (pnId) + *pnId = nId; + return &mapInfo[nId]; +} + +void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2) +{ + if (nRndPos1 == nRndPos2) + return; + + assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size()); + + int nId1 = vRandom[nRndPos1]; + int nId2 = vRandom[nRndPos2]; + + assert(mapInfo.count(nId1) == 1); + assert(mapInfo.count(nId2) == 1); + + mapInfo[nId1].nRandomPos = nRndPos2; + mapInfo[nId2].nRandomPos = nRndPos1; + + vRandom[nRndPos1] = nId2; + vRandom[nRndPos2] = nId1; +} + +void CAddrMan::Delete(int nId) +{ + assert(mapInfo.count(nId) != 0); + CAddrInfo& info = mapInfo[nId]; + assert(!info.fInTried); + assert(info.nRefCount == 0); + + SwapRandom(info.nRandomPos, vRandom.size() - 1); + vRandom.pop_back(); + mapAddr.erase(info); + mapInfo.erase(nId); + nNew--; +} + +void CAddrMan::ClearNew(int nUBucket, int nUBucketPos) +{ + // if there is an entry in the specified bucket, delete it. + if (vvNew[nUBucket][nUBucketPos] != -1) { + int nIdDelete = vvNew[nUBucket][nUBucketPos]; + CAddrInfo& infoDelete = mapInfo[nIdDelete]; + assert(infoDelete.nRefCount > 0); + infoDelete.nRefCount--; + vvNew[nUBucket][nUBucketPos] = -1; + if (infoDelete.nRefCount == 0) { + Delete(nIdDelete); + } + } +} + +void CAddrMan::MakeTried(CAddrInfo& info, int nId) +{ + // remove the entry from all new buckets + for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + int pos = info.GetBucketPosition(nKey, true, bucket); + if (vvNew[bucket][pos] == nId) { + vvNew[bucket][pos] = -1; + info.nRefCount--; + } + } + nNew--; + + assert(info.nRefCount == 0); + + // which tried bucket to move the entry to + int nKBucket = info.GetTriedBucket(nKey); + int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket); + + // first make space to add it (the existing tried entry there is moved to new, deleting whatever is there). + if (vvTried[nKBucket][nKBucketPos] != -1) { + // find an item to evict + int nIdEvict = vvTried[nKBucket][nKBucketPos]; + assert(mapInfo.count(nIdEvict) == 1); + CAddrInfo& infoOld = mapInfo[nIdEvict]; + + // Remove the to-be-evicted item from the tried set. + infoOld.fInTried = false; + vvTried[nKBucket][nKBucketPos] = -1; + nTried--; + + // find which new bucket it belongs to + int nUBucket = infoOld.GetNewBucket(nKey); + int nUBucketPos = infoOld.GetBucketPosition(nKey, true, nUBucket); + ClearNew(nUBucket, nUBucketPos); + assert(vvNew[nUBucket][nUBucketPos] == -1); + + // Enter it into the new set again. + infoOld.nRefCount = 1; + vvNew[nUBucket][nUBucketPos] = nIdEvict; + nNew++; + } + assert(vvTried[nKBucket][nKBucketPos] == -1); + + vvTried[nKBucket][nKBucketPos] = nId; + nTried++; + info.fInTried = true; +} + +void CAddrMan::Good_(const CService& addr, int64_t nTime) +{ + int nId; + CAddrInfo* pinfo = Find(addr, &nId); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastSuccess = nTime; + info.nLastTry = nTime; + info.nAttempts = 0; + // nTime is not updated here, to avoid leaking information about + // currently-connected peers. + + // if it is already in the tried set, don't do anything else + if (info.fInTried) + return; + + // find a bucket it is in now + int nRnd = RandomInt(ADDRMAN_NEW_BUCKET_COUNT); + int nUBucket = -1; + for (unsigned int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) { + int nB = (n + nRnd) % ADDRMAN_NEW_BUCKET_COUNT; + int nBpos = info.GetBucketPosition(nKey, true, nB); + if (vvNew[nB][nBpos] == nId) { + nUBucket = nB; + break; + } + } + + // if no bucket is found, something bad happened; + // TODO: maybe re-add the node, but for now, just bail out + if (nUBucket == -1) + return; + + LogPrint("addrman", "Moving %s to tried\n", addr.ToString()); + + // move nId to the tried tables + MakeTried(info, nId); +} + +bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimePenalty) +{ + if (!addr.IsRoutable()) + return false; + + bool fNew = false; + int nId; + CAddrInfo* pinfo = Find(addr, &nId); + + if (pinfo) { + // periodically update nTime + 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); + + // add services + pinfo->nServices |= addr.nServices; + + // do not update if no new information is present + if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime)) + return false; + + // do not update if the entry was already in the "tried" table + if (pinfo->fInTried) + return false; + + // do not update if the max reference count is reached + if (pinfo->nRefCount == ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + return false; + + // stochastic test: previous nRefCount == N: 2^N times harder to increase it + int nFactor = 1; + for (int n = 0; n < pinfo->nRefCount; n++) + nFactor *= 2; + if (nFactor > 1 && (RandomInt(nFactor) != 0)) + return false; + } else { + pinfo = Create(addr, source, &nId); + pinfo->nTime = std::max((int64_t)0, (int64_t)pinfo->nTime - nTimePenalty); + nNew++; + fNew = true; + } + + int nUBucket = pinfo->GetNewBucket(nKey, source); + int nUBucketPos = pinfo->GetBucketPosition(nKey, true, nUBucket); + if (vvNew[nUBucket][nUBucketPos] != nId) { + bool fInsert = vvNew[nUBucket][nUBucketPos] == -1; + if (!fInsert) { + CAddrInfo& infoExisting = mapInfo[vvNew[nUBucket][nUBucketPos]]; + if (infoExisting.IsTerrible() || (infoExisting.nRefCount > 1 && pinfo->nRefCount == 0)) { + // Overwrite the existing new table entry. + fInsert = true; + } + } + if (fInsert) { + ClearNew(nUBucket, nUBucketPos); + pinfo->nRefCount++; + vvNew[nUBucket][nUBucketPos] = nId; + } else { + if (pinfo->nRefCount == 0) { + Delete(nId); + } + } + } + return fNew; +} + +void CAddrMan::Attempt_(const CService& addr, int64_t nTime) +{ + CAddrInfo* pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + info.nLastTry = nTime; + info.nAttempts++; +} + +CAddrInfo CAddrMan::Select_(bool newOnly) +{ + if (size() == 0) + return CAddrInfo(); + + // Track number of attempts to find a table entry, before giving up to avoid infinite loop + const int kMaxRetries = 200000; // magic number so unit tests can pass + const int kRetriesBetweenSleep = 1000; + const int kRetrySleepInterval = 100; // milliseconds + + if (newOnly && nNew == 0) + return CAddrInfo(); + + // Use a 50% chance for choosing between tried and new table entries. + if (!newOnly && + (nTried > 0 && (nNew == 0 || RandomInt(2) == 0))) { + // use a tried node + double fChanceFactor = 1.0; + while (1) { + int i = 0; + int nKBucket = RandomInt(ADDRMAN_TRIED_BUCKET_COUNT); + int nKBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); + while (vvTried[nKBucket][nKBucketPos] == -1) { + nKBucket = (nKBucket + insecure_rand.randbits(ADDRMAN_TRIED_BUCKET_COUNT_LOG2)) % ADDRMAN_TRIED_BUCKET_COUNT; + nKBucketPos = (nKBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE; + if (i++ > kMaxRetries) + return CAddrInfo(); + if (i % kRetriesBetweenSleep == 0 && !nKey.IsNull()) + MilliSleep(kRetrySleepInterval); + } + int nId = vvTried[nKBucket][nKBucketPos]; + assert(mapInfo.count(nId) == 1); + CAddrInfo& info = mapInfo[nId]; + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + return info; + fChanceFactor *= 1.2; + } + } else { + // use a new node + double fChanceFactor = 1.0; + while (1) { + int i = 0; + int nUBucket = RandomInt(ADDRMAN_NEW_BUCKET_COUNT); + int nUBucketPos = RandomInt(ADDRMAN_BUCKET_SIZE); + while (vvNew[nUBucket][nUBucketPos] == -1) { + nUBucket = (nUBucket + insecure_rand.randbits(ADDRMAN_NEW_BUCKET_COUNT_LOG2)) % ADDRMAN_NEW_BUCKET_COUNT; + nUBucketPos = (nUBucketPos + insecure_rand.randbits(ADDRMAN_BUCKET_SIZE_LOG2)) % ADDRMAN_BUCKET_SIZE; + if (i++ > kMaxRetries) + return CAddrInfo(); + if (i % kRetriesBetweenSleep == 0 && !nKey.IsNull()) + MilliSleep(kRetrySleepInterval); + } + int nId = vvNew[nUBucket][nUBucketPos]; + assert(mapInfo.count(nId) == 1); + CAddrInfo& info = mapInfo[nId]; + if (RandomInt(1 << 30) < fChanceFactor * info.GetChance() * (1 << 30)) + return info; + fChanceFactor *= 1.2; + } + } + + return CAddrInfo(); +} + +#ifdef DEBUG_ADDRMAN +int CAddrMan::Check_() +{ + std::set setTried; + std::map mapNew; + + if (vRandom.size() != nTried + nNew) + return -7; + + for (std::map::iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { + int n = (*it).first; + CAddrInfo& info = (*it).second; + if (info.fInTried) { + if (!info.nLastSuccess) + return -1; + if (info.nRefCount) + return -2; + setTried.insert(n); + } else { + if (info.nRefCount < 0 || info.nRefCount > ADDRMAN_NEW_BUCKETS_PER_ADDRESS) + return -3; + if (!info.nRefCount) + return -4; + mapNew[n] = info.nRefCount; + } + if (mapAddr[info] != n) + return -5; + if (info.nRandomPos < 0 || info.nRandomPos >= vRandom.size() || vRandom[info.nRandomPos] != n) + return -14; + if (info.nLastTry < 0) + return -6; + if (info.nLastSuccess < 0) + return -8; + } + + if (setTried.size() != nTried) + return -9; + if (mapNew.size() != nNew) + return -10; + + for (int n = 0; n < ADDRMAN_TRIED_BUCKET_COUNT; n++) { + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvTried[n][i] != -1) { + if (!setTried.count(vvTried[n][i])) + return -11; + if (mapInfo[vvTried[n][i]].GetTriedBucket(nKey) != n) + return -17; + if (mapInfo[vvTried[n][i]].GetBucketPosition(nKey, false, n) != i) + return -18; + setTried.erase(vvTried[n][i]); + } + } + } + + for (int n = 0; n < ADDRMAN_NEW_BUCKET_COUNT; n++) { + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[n][i] != -1) { + if (!mapNew.count(vvNew[n][i])) + return -12; + if (mapInfo[vvNew[n][i]].GetBucketPosition(nKey, true, n) != i) + return -19; + if (--mapNew[vvNew[n][i]] == 0) + mapNew.erase(vvNew[n][i]); + } + } + } + + if (setTried.size()) + return -13; + if (mapNew.size()) + return -15; + if (nKey.IsNull()) + return -16; + + return 0; +} +#endif + +void CAddrMan::GetAddr_(std::vector& vAddr) +{ + unsigned int nNodes = ADDRMAN_GETADDR_MAX_PCT * vRandom.size() / 100; + if (nNodes > ADDRMAN_GETADDR_MAX) + nNodes = ADDRMAN_GETADDR_MAX; + + // gather a list of random nodes, skipping those of low quality + for (unsigned int n = 0; n < vRandom.size(); n++) { + if (vAddr.size() >= nNodes) + break; + + int nRndPos = RandomInt(vRandom.size() - n) + n; + SwapRandom(n, nRndPos); + assert(mapInfo.count(vRandom[n]) == 1); + + const CAddrInfo& ai = mapInfo[vRandom[n]]; + if (!ai.IsTerrible()) + vAddr.push_back(ai); + } +} + +void CAddrMan::Connected_(const CService& addr, int64_t nTime) +{ + CAddrInfo* pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return; + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return; + + // update info + int64_t nUpdateInterval = 20 * 60; + if (nTime - info.nTime > nUpdateInterval) + info.nTime = nTime; +} + +int CAddrMan::RandomInt(int nMax){ + return GetRandInt(nMax); +} diff --git a/depend/zcash/src/addrman.h b/depend/zcash/src/addrman.h new file mode 100644 index 000000000..8b287edbd --- /dev/null +++ b/depend/zcash/src/addrman.h @@ -0,0 +1,580 @@ +// Copyright (c) 2012 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_ADDRMAN_H +#define BITCOIN_ADDRMAN_H + +#include "netbase.h" +#include "protocol.h" +#include "random.h" +#include "sync.h" +#include "timedata.h" +#include "util.h" + +#include +#include +#include +#include + +/** + * Extended statistics about a CAddress + */ +class CAddrInfo : public CAddress +{ + + +public: + //! last try whatsoever by us (memory only) + int64_t nLastTry; + +private: + //! where knowledge about this address first came from + CNetAddr source; + + //! last successful connection by us + int64_t nLastSuccess; + + //! connection attempts since last successful attempt + int nAttempts; + + //! reference count in new sets (memory only) + int nRefCount; + + //! in tried set? (memory only) + bool fInTried; + + //! position in vRandom + int nRandomPos; + + friend class CAddrMan; + +public: + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(*(CAddress*)this); + READWRITE(source); + READWRITE(nLastSuccess); + READWRITE(nAttempts); + } + + void Init() + { + nLastSuccess = 0; + nLastTry = 0; + nAttempts = 0; + nRefCount = 0; + fInTried = false; + nRandomPos = -1; + } + + CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource) + { + Init(); + } + + CAddrInfo() : CAddress(), source() + { + Init(); + } + + //! Calculate in which "tried" bucket this entry belongs + int GetTriedBucket(const uint256 &nKey) const; + + //! Calculate in which "new" bucket this entry belongs, given a certain source + int GetNewBucket(const uint256 &nKey, const CNetAddr& src) const; + + //! Calculate in which "new" bucket this entry belongs, using its default source + int GetNewBucket(const uint256 &nKey) const + { + return GetNewBucket(nKey, source); + } + + //! Calculate in which position of a bucket to store this entry. + 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 = GetTime()) const; + + //! Calculate the relative chance this entry should be given when selecting nodes to connect to + double GetChance(int64_t nNow = GetTime()) const; + +}; + +/** Stochastic address manager + * + * Design goals: + * * Keep the address tables in-memory, and asynchronously dump the entire table to peers.dat. + * * Make sure no (localized) attacker can fill the entire table with his nodes/addresses. + * + * To that end: + * * Addresses are organized into buckets. + * * Addresses that have not yet been tried go into 1024 "new" buckets. + * * Based on the address range (/16 for IPv4) of the source of information, 64 buckets are selected at random. + * * The actual bucket is chosen from one of these, based on the range in which the address itself is located. + * * One single address can occur in up to 8 different buckets to increase selection chances for addresses that + * are seen frequently. The chance for increasing this multiplicity decreases exponentially. + * * When adding a new address to a full bucket, a randomly chosen entry (with a bias favoring less recently seen + * ones) is removed from it first. + * * Addresses of nodes that are known to be accessible go into 256 "tried" buckets. + * * Each address range selects at random 8 of these buckets. + * * The actual bucket is chosen from one of these, based on the full address. + * * When adding a new good address to a full bucket, a randomly chosen entry (with a bias favoring less recently + * tried ones) is evicted from it, back to the "new" buckets. + * * Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not + * be observable by adversaries. + * * Several indexes are kept for high performance. Defining DEBUG_ADDRMAN will introduce frequent (and expensive) + * consistency checks for the entire data structure. + */ + +//! total number of buckets for tried addresses +#define ADDRMAN_TRIED_BUCKET_COUNT_LOG2 8 + +//! total number of buckets for new addresses +#define ADDRMAN_NEW_BUCKET_COUNT_LOG2 10 + +//! maximum allowed number of entries in buckets for new and tried addresses +#define ADDRMAN_BUCKET_SIZE_LOG2 6 + +//! over how many buckets entries with tried addresses from a single group (/16 for IPv4) are spread +#define ADDRMAN_TRIED_BUCKETS_PER_GROUP 8 + +//! over how many buckets entries with new addresses originating from a single group are spread +#define ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP 64 + +//! in how many buckets for entries with new addresses a single address may occur +#define ADDRMAN_NEW_BUCKETS_PER_ADDRESS 8 + +//! how old addresses can maximally be +#define ADDRMAN_HORIZON_DAYS 30 + +//! after how many failed attempts we give up on a new node +#define ADDRMAN_RETRIES 3 + +//! how many successive failures are allowed ... +#define ADDRMAN_MAX_FAILURES 10 + +//! ... in at least this many days +#define ADDRMAN_MIN_FAIL_DAYS 7 + +//! the maximum percentage of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX_PCT 23 + +//! the maximum number of nodes to return in a getaddr call +#define ADDRMAN_GETADDR_MAX 2500 + +//! Convenience +#define ADDRMAN_TRIED_BUCKET_COUNT (1 << ADDRMAN_TRIED_BUCKET_COUNT_LOG2) +#define ADDRMAN_NEW_BUCKET_COUNT (1 << ADDRMAN_NEW_BUCKET_COUNT_LOG2) +#define ADDRMAN_BUCKET_SIZE (1 << ADDRMAN_BUCKET_SIZE_LOG2) + +/** + * Stochastical (IP) address manager + */ +class CAddrMan +{ +private: + //! critical section to protect the inner data structures + mutable CCriticalSection cs; + + //! last used nId + int nIdCount; + + //! table with information about all nIds + std::map mapInfo; + + //! find an nId based on its network address + std::map mapAddr; + + //! randomly-ordered vector of all nIds + std::vector vRandom; + + // number of "tried" entries + int nTried; + + //! list of "tried" buckets + int vvTried[ADDRMAN_TRIED_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; + + //! number of (unique) "new" entries + int nNew; + + //! list of "new" buckets + int vvNew[ADDRMAN_NEW_BUCKET_COUNT][ADDRMAN_BUCKET_SIZE]; + +protected: + //! secret key to randomize bucket select with + uint256 nKey; + + //! Source of random numbers for randomization in inner loops + FastRandomContext insecure_rand; + + //! Find an entry. + CAddrInfo* Find(const CNetAddr& addr, int *pnId = NULL); + + //! find an entry, creating it if necessary. + //! nTime and nServices of the found node are updated, if necessary. + CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL); + + //! Swap two elements in vRandom. + void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2); + + //! Move an entry from the "new" table(s) to the "tried" table + void MakeTried(CAddrInfo& info, int nId); + + //! Delete an entry. It must not be in tried, and have refcount 0. + void Delete(int nId); + + //! Clear a position in a "new" table. This is the only place where entries are actually deleted. + void ClearNew(int nUBucket, int nUBucketPos); + + //! Mark an entry "good", possibly moving it from "new" to "tried". + void Good_(const CService &addr, int64_t nTime); + + //! Add an entry to the "new" table. + bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty); + + //! Mark an entry as attempted to connect. + void Attempt_(const CService &addr, int64_t nTime); + + //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. + CAddrInfo Select_(bool newOnly); + + //! Wraps GetRandInt to allow tests to override RandomInt and make it deterministic. + virtual int RandomInt(int nMax); + +#ifdef DEBUG_ADDRMAN + //! Perform consistency check. Returns an error code or zero. + int Check_(); +#endif + + //! Select several addresses at once. + void GetAddr_(std::vector &vAddr); + + //! Mark an entry as currently-connected-to. + void Connected_(const CService &addr, int64_t nTime); + +public: + /** + * serialized format: + * * version byte (currently 1) + * * 0x20 + nKey (serialized as if it were a vector, for backward compatibility) + * * nNew + * * nTried + * * number of "new" buckets XOR 2**30 + * * all nNew addrinfos in vvNew + * * all nTried addrinfos in vvTried + * * for each bucket: + * * number of elements + * * for each element: index + * + * 2**30 is xorred with the number of buckets to make addrman deserializer v0 detect it + * as incompatible. This is necessary because it did not check the version number on + * deserialization. + * + * Notice that vvTried, mapAddr and vVector are never encoded explicitly; + * they are instead reconstructed from the other information. + * + * vvNew is serialized, but only used if ADDRMAN_UNKNOWN_BUCKET_COUNT didn't change, + * otherwise it is reconstructed as well. + * + * This format is more complex, but significantly smaller (at most 1.5 MiB), and supports + * changes to the ADDRMAN_ parameters without breaking the on-disk structure. + * + * We don't use ADD_SERIALIZE_METHODS since the serialization and deserialization code has + * very little in common. + */ + template + void Serialize(Stream &s) const + { + LOCK(cs); + + unsigned char nVersion = 1; + s << nVersion; + s << ((unsigned char)32); + s << nKey; + s << nNew; + s << nTried; + + int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30); + s << nUBuckets; + std::map mapUnkIds; + int nIds = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { + mapUnkIds[(*it).first] = nIds; + const CAddrInfo &info = (*it).second; + if (info.nRefCount) { + assert(nIds != nNew); // this means nNew was wrong, oh ow + s << info; + nIds++; + } + } + nIds = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); it++) { + const CAddrInfo &info = (*it).second; + if (info.fInTried) { + assert(nIds != nTried); // this means nTried was wrong, oh ow + s << info; + nIds++; + } + } + for (int bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + int nSize = 0; + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[bucket][i] != -1) + nSize++; + } + s << nSize; + for (int i = 0; i < ADDRMAN_BUCKET_SIZE; i++) { + if (vvNew[bucket][i] != -1) { + int nIndex = mapUnkIds[vvNew[bucket][i]]; + s << nIndex; + } + } + } + } + + template + void Unserialize(Stream& s) + { + LOCK(cs); + + Clear(); + + unsigned char nVersion; + s >> nVersion; + unsigned char nKeySize; + s >> nKeySize; + if (nKeySize != 32) throw std::ios_base::failure("Incorrect keysize in addrman deserialization"); + s >> nKey; + s >> nNew; + s >> nTried; + int nUBuckets = 0; + s >> nUBuckets; + if (nVersion != 0) { + nUBuckets ^= (1 << 30); + } + + if (nNew > ADDRMAN_NEW_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) { + throw std::ios_base::failure("Corrupt CAddrMan serialization, nNew exceeds limit."); + } + + if (nTried > ADDRMAN_TRIED_BUCKET_COUNT * ADDRMAN_BUCKET_SIZE) { + throw std::ios_base::failure("Corrupt CAddrMan serialization, nTried exceeds limit."); + } + + // Deserialize entries from the new table. + for (int n = 0; n < nNew; n++) { + CAddrInfo &info = mapInfo[n]; + s >> info; + mapAddr[info] = n; + info.nRandomPos = vRandom.size(); + vRandom.push_back(n); + if (nVersion != 1 || nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) { + // In case the new table data cannot be used (nVersion unknown, or bucket count wrong), + // immediately try to give them a reference based on their primary source address. + int nUBucket = info.GetNewBucket(nKey); + int nUBucketPos = info.GetBucketPosition(nKey, true, nUBucket); + if (vvNew[nUBucket][nUBucketPos] == -1) { + vvNew[nUBucket][nUBucketPos] = n; + info.nRefCount++; + } + } + } + nIdCount = nNew; + + // Deserialize entries from the tried table. + int nLost = 0; + for (int n = 0; n < nTried; n++) { + CAddrInfo info; + s >> info; + int nKBucket = info.GetTriedBucket(nKey); + int nKBucketPos = info.GetBucketPosition(nKey, false, nKBucket); + if (vvTried[nKBucket][nKBucketPos] == -1) { + info.nRandomPos = vRandom.size(); + info.fInTried = true; + vRandom.push_back(nIdCount); + mapInfo[nIdCount] = info; + mapAddr[info] = nIdCount; + vvTried[nKBucket][nKBucketPos] = nIdCount; + nIdCount++; + } else { + nLost++; + } + } + nTried -= nLost; + + // Deserialize positions in the new table (if possible). + for (int bucket = 0; bucket < nUBuckets; bucket++) { + int nSize = 0; + s >> nSize; + for (int n = 0; n < nSize; n++) { + int nIndex = 0; + s >> nIndex; + if (nIndex >= 0 && nIndex < nNew) { + CAddrInfo &info = mapInfo[nIndex]; + int nUBucketPos = info.GetBucketPosition(nKey, true, bucket); + if (nVersion == 1 && nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && vvNew[bucket][nUBucketPos] == -1 && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) { + info.nRefCount++; + vvNew[bucket][nUBucketPos] = nIndex; + } + } + } + } + + // Prune new entries with refcount 0 (as a result of collisions). + int nLostUnk = 0; + for (std::map::const_iterator it = mapInfo.begin(); it != mapInfo.end(); ) { + if (it->second.fInTried == false && it->second.nRefCount == 0) { + std::map::const_iterator itCopy = it++; + Delete(itCopy->first); + nLostUnk++; + } else { + it++; + } + } + if (nLost + nLostUnk > 0) { + LogPrint("addrman", "addrman lost %i new and %i tried addresses due to collisions\n", nLostUnk, nLost); + } + + Check(); + } + + void Clear() + { + LOCK(cs); + std::vector().swap(vRandom); + nKey = GetRandHash(); + for (size_t bucket = 0; bucket < ADDRMAN_NEW_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvNew[bucket][entry] = -1; + } + } + for (size_t bucket = 0; bucket < ADDRMAN_TRIED_BUCKET_COUNT; bucket++) { + for (size_t entry = 0; entry < ADDRMAN_BUCKET_SIZE; entry++) { + vvTried[bucket][entry] = -1; + } + } + + nIdCount = 0; + nTried = 0; + nNew = 0; + } + + CAddrMan() + { + Clear(); + } + + ~CAddrMan() + { + nKey.SetNull(); + } + + //! Return the number of (unique) addresses in all tables. + size_t size() const + { + LOCK(cs); // TODO: Cache this in an atomic to avoid this overhead + return vRandom.size(); + } + + //! Consistency check + void Check() + { +#ifdef DEBUG_ADDRMAN + { + LOCK(cs); + int err; + if ((err=Check_())) + LogPrintf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err); + } +#endif + } + + //! Add a single address. + bool Add(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty = 0) + { + LOCK(cs); + bool fRet = false; + Check(); + fRet |= Add_(addr, source, nTimePenalty); + Check(); + if (fRet) + LogPrint("addrman", "Added %s from %s: %i tried, %i new\n", addr.ToStringIPPort(), source.ToString(), nTried, nNew); + return fRet; + } + + //! Add multiple addresses. + bool Add(const std::vector &vAddr, const CNetAddr& source, int64_t nTimePenalty = 0) + { + LOCK(cs); + int nAdd = 0; + Check(); + for (std::vector::const_iterator it = vAddr.begin(); it != vAddr.end(); it++) + nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0; + Check(); + if (nAdd) + LogPrint("addrman", "Added %i addresses from %s: %i tried, %i new\n", nAdd, source.ToString(), nTried, nNew); + return nAdd > 0; + } + + //! Mark an entry as accessible. + void Good(const CService &addr, int64_t nTime = GetTime()) + { + LOCK(cs); + Check(); + Good_(addr, nTime); + Check(); + } + + //! Mark an entry as connection attempted to. + void Attempt(const CService &addr, int64_t nTime = GetTime()) + { + LOCK(cs); + Check(); + Attempt_(addr, nTime); + Check(); + } + + /** + * Choose an address to connect to. + */ + CAddrInfo Select(bool newOnly = false) + { + CAddrInfo addrRet; + { + LOCK(cs); + Check(); + addrRet = Select_(newOnly); + Check(); + } + return addrRet; + } + + //! Return a bunch of addresses, selected at random. + std::vector GetAddr() + { + Check(); + std::vector vAddr; + { + LOCK(cs); + GetAddr_(vAddr); + } + Check(); + return vAddr; + } + + //! Mark an entry as currently-connected-to. + void Connected(const CService &addr, int64_t nTime = GetTime()) + { + LOCK(cs); + Check(); + Connected_(addr, nTime); + Check(); + } + +}; + +#endif // BITCOIN_ADDRMAN_H diff --git a/depend/zcash/src/alert.cpp b/depend/zcash/src/alert.cpp new file mode 100644 index 000000000..c9fd9ee2e --- /dev/null +++ b/depend/zcash/src/alert.cpp @@ -0,0 +1,284 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#include "alert.h" + +#include "clientversion.h" +#include "net.h" +#include "pubkey.h" +#include "timedata.h" +#include "ui_interface.h" +#include "util.h" + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +map mapAlerts; +CCriticalSection cs_mapAlerts; + +void CUnsignedAlert::SetNull() +{ + nVersion = 1; + nRelayUntil = 0; + nExpiration = 0; + nID = 0; + nCancel = 0; + setCancel.clear(); + nMinVer = 0; + nMaxVer = 0; + setSubVer.clear(); + nPriority = 0; + + strComment.clear(); + strStatusBar.clear(); + strRPCError.clear(); +} + +std::string CUnsignedAlert::ToString() const +{ + std::string strSetCancel; + for (int n : setCancel) + strSetCancel += strprintf("%d ", n); + std::string strSetSubVer; + for (const std::string& str : setSubVer) + strSetSubVer += "\"" + str + "\" "; + return strprintf( + "CAlert(\n" + " nVersion = %d\n" + " nRelayUntil = %d\n" + " nExpiration = %d\n" + " nID = %d\n" + " nCancel = %d\n" + " setCancel = %s\n" + " nMinVer = %d\n" + " nMaxVer = %d\n" + " setSubVer = %s\n" + " nPriority = %d\n" + " strComment = \"%s\"\n" + " strStatusBar = \"%s\"\n" + " strRPCError = \"%s\"\n" + ")\n", + nVersion, + nRelayUntil, + nExpiration, + nID, + nCancel, + strSetCancel, + nMinVer, + nMaxVer, + strSetSubVer, + nPriority, + strComment, + strStatusBar, + strRPCError); +} + +void CAlert::SetNull() +{ + CUnsignedAlert::SetNull(); + vchMsg.clear(); + vchSig.clear(); +} + +bool CAlert::IsNull() const +{ + return (nExpiration == 0); +} + +uint256 CAlert::GetHash() const +{ + return Hash(this->vchMsg.begin(), this->vchMsg.end()); +} + +bool CAlert::IsInEffect() const +{ + return (GetTime() < nExpiration); +} + +bool CAlert::Cancels(const CAlert& alert) const +{ + if (!IsInEffect()) + return false; // this was a no-op before 31403 + return (alert.nID <= nCancel || setCancel.count(alert.nID)); +} + +bool CAlert::AppliesTo(int nVersion, const std::string& strSubVerIn) const +{ + // Get a subversion without comments + std::string strSubVer = ""; + auto start = 0; + auto end = 0; + while (start < strSubVerIn.length() && end < strSubVerIn.length()) { + end = strSubVerIn.find('(', start); + if (end == std::string::npos) { + // Ensure we get the section of strSubVerIn after the final comment + end = strSubVerIn.length(); + } + strSubVer.append(strSubVerIn.substr(start, end - start)); + start = strSubVerIn.find(')', end); + if (start != std::string::npos) { + // Finish with start pointing at the next character we want + start += 1; + } + } + // Check against both the commented and uncommented subversion + // TODO: rework for client-version-embedded-in-strSubVer ? + return (IsInEffect() && + nMinVer <= nVersion && nVersion <= nMaxVer && + (setSubVer.empty() || setSubVer.count(strSubVerIn) || setSubVer.count(strSubVer))); +} + +bool CAlert::AppliesToMe() const +{ + return AppliesTo(PROTOCOL_VERSION, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector())); +} + +bool CAlert::RelayTo(CNode* pnode) const +{ + if (!IsInEffect()) + return false; + // don't relay to nodes which haven't sent their version message + if (pnode->nVersion == 0) + return false; + // returns true if wasn't already contained in the set + if (pnode->setKnown.insert(GetHash()).second) + { + if (AppliesTo(pnode->nVersion, pnode->strSubVer) || + AppliesToMe() || + GetTime() < nRelayUntil) + { + pnode->PushMessage("alert", *this); + return true; + } + } + return false; +} + +bool CAlert::CheckSignature(const std::vector& alertKey) const +{ + CPubKey key(alertKey); + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + return error("CAlert::CheckSignature(): verify signature failed"); + + // Now unserialize the data + CDataStream sMsg(vchMsg, SER_NETWORK, PROTOCOL_VERSION); + sMsg >> *(CUnsignedAlert*)this; + return true; +} + +CAlert CAlert::getAlertByHash(const uint256 &hash) +{ + CAlert retval; + { + LOCK(cs_mapAlerts); + map::iterator mi = mapAlerts.find(hash); + if(mi != mapAlerts.end()) + retval = mi->second; + } + return retval; +} + +bool CAlert::ProcessAlert(const std::vector& alertKey, bool fThread) +{ + if (!CheckSignature(alertKey)) + return false; + if (!IsInEffect()) + return false; + + // alert.nID=max is reserved for if the alert key is + // compromised. It must have a pre-defined message, + // must never expire, must apply to all versions, + // and must cancel all previous + // alerts or it will be ignored (so an attacker can't + // send an "everything is OK, don't panic" version that + // cannot be overridden): + int maxInt = std::numeric_limits::max(); + if (nID == maxInt) + { + if (!( + nExpiration == maxInt && + nCancel == (maxInt-1) && + nMinVer == 0 && + nMaxVer == maxInt && + setSubVer.empty() && + nPriority == maxInt && + strStatusBar == "URGENT: Alert key compromised, upgrade required" + )) + return false; + } + + { + LOCK(cs_mapAlerts); + // Cancel previous alerts + for (map::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();) + { + const CAlert& alert = (*mi).second; + if (Cancels(alert)) + { + LogPrint("alert", "cancelling alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mi = mapAlerts.erase(mi); + } + else if (!alert.IsInEffect()) + { + LogPrint("alert", "expiring alert %d\n", alert.nID); + uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED); + mi = mapAlerts.erase(mi); + } + else + mi++; + } + + // Check if this alert has been cancelled + for (std::pair& item : mapAlerts) + { + const CAlert& alert = item.second; + if (alert.Cancels(*this)) + { + LogPrint("alert", "alert already cancelled by %d\n", alert.nID); + return false; + } + } + + // Add to mapAlerts + mapAlerts.insert(make_pair(GetHash(), *this)); + // Notify UI and -alertnotify if it applies to me + if(AppliesToMe()) + { + uiInterface.NotifyAlertChanged(GetHash(), CT_NEW); + Notify(strStatusBar, fThread); + } + } + + LogPrint("alert", "accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe()); + return true; +} + +void +CAlert::Notify(const std::string& strMessage, bool fThread) +{ + std::string strCmd = GetArg("-alertnotify", ""); + if (strCmd.empty()) return; + + // Alert text should be plain ascii coming from a trusted source, but to + // be safe we first strip anything not in safeChars, then add single quotes around + // the whole string before passing it to the shell: + std::string singleQuote("'"); + std::string safeStatus = SanitizeString(strMessage); + safeStatus = singleQuote+safeStatus+singleQuote; + boost::replace_all(strCmd, "%s", safeStatus); + + if (fThread) + boost::thread t(runCommand, strCmd); // thread runs free + else + runCommand(strCmd); +} diff --git a/depend/zcash/src/alert.h b/depend/zcash/src/alert.h new file mode 100644 index 000000000..8cc1165b1 --- /dev/null +++ b/depend/zcash/src/alert.h @@ -0,0 +1,115 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_ALERT_H +#define BITCOIN_ALERT_H + +#include "serialize.h" +#include "sync.h" + +#include +#include +#include +#include + +/** Minimum alert priority for enabling safe mode. */ +static const int ALERT_PRIORITY_SAFE_MODE = 4000; + +class CAlert; +class CNode; +class uint256; + +extern std::map mapAlerts; +extern CCriticalSection cs_mapAlerts; + +/** Alerts are for notifying old versions if they become too obsolete and + * need to upgrade. The message is displayed in the status bar. + * Alert messages are broadcast as a vector of signed data. Unserializing may + * not read the entire buffer if the alert is for a newer version, but older + * versions can still relay the original data. + */ +class CUnsignedAlert +{ +public: + int nVersion; + int64_t nRelayUntil; // when newer nodes stop relaying to newer nodes + int64_t nExpiration; + int nID; + int nCancel; + std::set setCancel; + int nMinVer; // lowest version inclusive + int nMaxVer; // highest version inclusive + std::set setSubVer; // empty matches all + int nPriority; + + // Actions + std::string strComment; + std::string strStatusBar; + std::string strRPCError; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(this->nVersion); + READWRITE(nRelayUntil); + READWRITE(nExpiration); + READWRITE(nID); + READWRITE(nCancel); + READWRITE(setCancel); + READWRITE(nMinVer); + READWRITE(nMaxVer); + READWRITE(setSubVer); + READWRITE(nPriority); + + READWRITE(LIMITED_STRING(strComment, 65536)); + READWRITE(LIMITED_STRING(strStatusBar, 256)); + READWRITE(LIMITED_STRING(strRPCError, 256)); + } + + void SetNull(); + + std::string ToString() const; +}; + +/** An alert is a combination of a serialized CUnsignedAlert and a signature. */ +class CAlert : public CUnsignedAlert +{ +public: + std::vector vchMsg; + std::vector vchSig; + + CAlert() + { + SetNull(); + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(vchMsg); + READWRITE(vchSig); + } + + void SetNull(); + bool IsNull() const; + uint256 GetHash() const; + bool IsInEffect() const; + bool Cancels(const CAlert& alert) const; + bool AppliesTo(int nVersion, const std::string& strSubVerIn) const; + bool AppliesToMe() const; + bool RelayTo(CNode* pnode) const; + bool CheckSignature(const std::vector& alertKey) const; + bool ProcessAlert(const std::vector& alertKey, bool fThread = true); // fThread means run -alertnotify in a free-running thread + static void Notify(const std::string& strMessage, bool fThread); + + /* + * Get copy of (active) alert object by hash. Returns a null alert if it is not found. + */ + static CAlert getAlertByHash(const uint256 &hash); +}; + +#endif // BITCOIN_ALERT_H diff --git a/depend/zcash/src/alertkeys.h b/depend/zcash/src/alertkeys.h new file mode 100644 index 000000000..32d26638e --- /dev/null +++ b/depend/zcash/src/alertkeys.h @@ -0,0 +1,10 @@ +#ifndef BITCOIN_ALERTKEYS_H +#define BITCOIN_ALERTKEYS_H + +// REMINDER: DO NOT COMMIT YOUR PRIVATE KEYS TO THE GIT REPOSITORY! + +const char* pszPrivKey = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; +const char* pszTestNetPrivKey = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + +#endif + diff --git a/depend/zcash/src/amount.cpp b/depend/zcash/src/amount.cpp new file mode 100644 index 000000000..93da7104e --- /dev/null +++ b/depend/zcash/src/amount.cpp @@ -0,0 +1,40 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#include "amount.h" +#include "policy/fees.h" + +#include "tinyformat.h" + +const std::string CURRENCY_UNIT = "ZEC"; +const std::string MINOR_CURRENCY_UNIT = "zatoshis"; + +CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) +{ + if (nSize > 0) + nSatoshisPerK = nFeePaid*1000/nSize; + else + nSatoshisPerK = 0; +} + +CAmount CFeeRate::GetFeeForRelay(size_t nSize) const +{ + return std::min(GetFee(nSize), DEFAULT_FEE); +} + +CAmount CFeeRate::GetFee(size_t nSize) const +{ + CAmount nFee = nSatoshisPerK*nSize / 1000; + + if (nFee == 0 && nSatoshisPerK > 0) + nFee = nSatoshisPerK; + + return nFee; +} + +std::string CFeeRate::ToString() const +{ + return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT); +} diff --git a/depend/zcash/src/amount.h b/depend/zcash/src/amount.h new file mode 100644 index 000000000..407bd4057 --- /dev/null +++ b/depend/zcash/src/amount.h @@ -0,0 +1,67 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_AMOUNT_H +#define BITCOIN_AMOUNT_H + +#include "serialize.h" + +#include +#include + +typedef int64_t CAmount; + +static const CAmount COIN = 100000000; +static const CAmount CENT = 1000000; + +extern const std::string CURRENCY_UNIT; +extern const std::string MINOR_CURRENCY_UNIT; + +/** No amount larger than this (in zatoshi) is valid. + * + * Note that this constant is *not* the total money supply, which in Bitcoin + * currently happens to be less than 21,000,000 BTC for various reasons, but + * rather a sanity check. As this sanity check is used by consensus-critical + * validation code, the exact value of the MAX_MONEY constant is consensus + * critical; in unusual circumstances like a(nother) overflow bug that allowed + * for the creation of coins out of thin air modification could lead to a fork. + * */ +static const CAmount MAX_MONEY = 21000000 * COIN; +inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } + +/** Type-safe wrapper class to for fee rates + * (how much to pay based on transaction size) + */ +class CFeeRate +{ +private: + CAmount nSatoshisPerK; // unit is zatoshis-per-1,000-bytes +public: + CFeeRate() : nSatoshisPerK(0) { } + explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } + CFeeRate(const CAmount& nFeePaid, size_t nSize); + CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } + + CAmount GetFeeForRelay(size_t size) const; // unit returned is zatoshis + CAmount GetFee(size_t size) const; // unit returned is zatoshis + CAmount GetFeePerK() const { return GetFee(1000); } // zatoshis-per-1000-bytes + + friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; } + friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; } + friend bool operator==(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK == b.nSatoshisPerK; } + friend bool operator<=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK <= b.nSatoshisPerK; } + friend bool operator>=(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK >= b.nSatoshisPerK; } + CFeeRate& operator+=(const CFeeRate& a) { nSatoshisPerK += a.nSatoshisPerK; return *this; } + std::string ToString() const; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(nSatoshisPerK); + } +}; + +#endif // BITCOIN_AMOUNT_H diff --git a/depend/zcash/src/arith_uint256.cpp b/depend/zcash/src/arith_uint256.cpp new file mode 100644 index 000000000..6c2f8dbea --- /dev/null +++ b/depend/zcash/src/arith_uint256.cpp @@ -0,0 +1,261 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "arith_uint256.h" + +#include "uint256.h" +#include "utilstrencodings.h" +#include "crypto/common.h" + +#include +#include + +template +base_uint::base_uint(const std::string& str) +{ + SetHex(str); +} + +template +base_uint& base_uint::operator<<=(unsigned int shift) +{ + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) { + if (i + k + 1 < WIDTH && shift != 0) + pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); + if (i + k < WIDTH) + pn[i + k] |= (a.pn[i] << shift); + } + return *this; +} + +template +base_uint& base_uint::operator>>=(unsigned int shift) +{ + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) { + if (i - k - 1 >= 0 && shift != 0) + pn[i - k - 1] |= (a.pn[i] << (32 - shift)); + if (i - k >= 0) + pn[i - k] |= (a.pn[i] >> shift); + } + return *this; +} + +template +base_uint& base_uint::operator*=(uint32_t b32) +{ + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) { + uint64_t n = carry + (uint64_t)b32 * pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; +} + +template +base_uint& base_uint::operator*=(const base_uint& b) +{ + base_uint a = *this; + *this = 0; + for (int j = 0; j < WIDTH; j++) { + uint64_t carry = 0; + for (int i = 0; i + j < WIDTH; i++) { + uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i]; + pn[i + j] = n & 0xffffffff; + carry = n >> 32; + } + } + return *this; +} + +template +base_uint& base_uint::operator/=(const base_uint& b) +{ + base_uint div = b; // make a copy, so we can shift. + base_uint num = *this; // make a copy, so we can subtract. + *this = 0; // the quotient. + int num_bits = num.bits(); + int div_bits = div.bits(); + if (div_bits == 0) + throw uint_error("Division by zero"); + if (div_bits > num_bits) // the result is certainly 0. + return *this; + int shift = num_bits - div_bits; + div <<= shift; // shift so that div and num align. + while (shift >= 0) { + if (num >= div) { + num -= div; + pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result. + } + div >>= 1; // shift back. + shift--; + } + // num now contains the remainder of the division. + return *this; +} + +template +int base_uint::CompareTo(const base_uint& b) const +{ + for (int i = WIDTH - 1; i >= 0; i--) { + if (pn[i] < b.pn[i]) + return -1; + if (pn[i] > b.pn[i]) + return 1; + } + return 0; +} + +template +bool base_uint::EqualTo(uint64_t b) const +{ + for (int i = WIDTH - 1; i >= 2; i--) { + if (pn[i]) + return false; + } + if (pn[1] != (b >> 32)) + return false; + if (pn[0] != (b & 0xfffffffful)) + return false; + return true; +} + +template +double base_uint::getdouble() const +{ + double ret = 0.0; + double fact = 1.0; + for (int i = 0; i < WIDTH; i++) { + ret += fact * pn[i]; + fact *= 4294967296.0; + } + return ret; +} + +template +std::string base_uint::GetHex() const +{ + return ArithToUint256(*this).GetHex(); +} + +template +void base_uint::SetHex(const char* psz) +{ + *this = UintToArith256(uint256S(psz)); +} + +template +void base_uint::SetHex(const std::string& str) +{ + SetHex(str.c_str()); +} + +template +std::string base_uint::ToString() const +{ + return (GetHex()); +} + +template +unsigned int base_uint::bits() const +{ + for (int pos = WIDTH - 1; pos >= 0; pos--) { + if (pn[pos]) { + for (size_t bits = 31; bits > 0; bits--) { + if (pn[pos] & (1U << bits)) { + return 32 * pos + bits + 1; + } + } + return 32 * pos + 1; + } + } + return 0; +} + +// Explicit instantiations for base_uint<256> +template base_uint<256>::base_uint(const std::string&); +template base_uint<256>& base_uint<256>::operator<<=(unsigned int); +template base_uint<256>& base_uint<256>::operator>>=(unsigned int); +template base_uint<256>& base_uint<256>::operator*=(uint32_t b32); +template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b); +template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b); +template int base_uint<256>::CompareTo(const base_uint<256>&) const; +template bool base_uint<256>::EqualTo(uint64_t) const; +template double base_uint<256>::getdouble() const; +template std::string base_uint<256>::GetHex() const; +template std::string base_uint<256>::ToString() const; +template void base_uint<256>::SetHex(const char*); +template void base_uint<256>::SetHex(const std::string&); +template unsigned int base_uint<256>::bits() const; + +// This implementation directly uses shifts instead of going +// through an intermediate MPI representation. +arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) +{ + int nSize = nCompact >> 24; + uint32_t nWord = nCompact & 0x007fffff; + if (nSize <= 3) { + nWord >>= 8 * (3 - nSize); + *this = nWord; + } else { + *this = nWord; + *this <<= 8 * (nSize - 3); + } + if (pfNegative) + *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; + if (pfOverflow) + *pfOverflow = nWord != 0 && ((nSize > 34) || + (nWord > 0xff && nSize > 33) || + (nWord > 0xffff && nSize > 32)); + return *this; +} + +uint32_t arith_uint256::GetCompact(bool fNegative) const +{ + int nSize = (bits() + 7) / 8; + uint32_t nCompact = 0; + if (nSize <= 3) { + nCompact = GetLow64() << 8 * (3 - nSize); + } else { + arith_uint256 bn = *this >> 8 * (nSize - 3); + nCompact = bn.GetLow64(); + } + // The 0x00800000 bit denotes the sign. + // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. + if (nCompact & 0x00800000) { + nCompact >>= 8; + nSize++; + } + assert((nCompact & ~0x007fffff) == 0); + assert(nSize < 256); + nCompact |= nSize << 24; + nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); + return nCompact; +} + +uint256 ArithToUint256(const arith_uint256 &a) +{ + uint256 b; + for(int x=0; x +#include +#include +#include +#include +#include + +class uint256; + +class uint_error : public std::runtime_error { +public: + explicit uint_error(const std::string& str) : std::runtime_error(str) {} +}; + +/** Template base class for unsigned big integers. */ +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + uint32_t pn[WIDTH]; +public: + + base_uint() + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + } + + base_uint(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + base_uint& operator=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + base_uint(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + explicit base_uint(const std::string& str); + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + double getdouble() const; + + base_uint& operator=(uint64_t b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64_t b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64_t b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift); + base_uint& operator>>=(unsigned int shift); + + base_uint& operator+=(const base_uint& b) + { + uint64_t carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64_t n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64_t b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64_t b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + base_uint& operator*=(uint32_t b32); + base_uint& operator*=(const base_uint& b); + base_uint& operator/=(const base_uint& b); + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == (uint32_t)-1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + int CompareTo(const base_uint& b) const; + bool EqualTo(uint64_t b) const; + + friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; } + friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; } + friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; } + friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; } + friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; } + friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; } + friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; } + friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } + friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } + friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } + friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } + friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } + friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } + friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } + friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } + friend inline bool operator<=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) <= 0; } + friend inline bool operator==(const base_uint& a, uint64_t b) { return a.EqualTo(b); } + friend inline bool operator!=(const base_uint& a, uint64_t b) { return !a.EqualTo(b); } + + std::string GetHex() const; + void SetHex(const char* psz); + void SetHex(const std::string& str); + std::string ToString() const; + + unsigned int size() const + { + return sizeof(pn); + } + + /** + * Returns the position of the highest bit set plus one, or zero if the + * value is zero. + */ + unsigned int bits() const; + + uint64_t GetLow64() const + { + assert(WIDTH >= 2); + return pn[0] | (uint64_t)pn[1] << 32; + } +}; + +/** 256-bit unsigned big integer. */ +class arith_uint256 : public base_uint<256> { +public: + arith_uint256() {} + arith_uint256(const base_uint<256>& b) : base_uint<256>(b) {} + arith_uint256(uint64_t b) : base_uint<256>(b) {} + explicit arith_uint256(const std::string& str) : base_uint<256>(str) {} + + /** + * The "compact" format is a representation of a whole + * number N using an unsigned 32bit number similar to a + * floating point format. + * The most significant 8 bits are the unsigned exponent of base 256. + * This exponent can be thought of as "number of bytes of N". + * The lower 23 bits are the mantissa. + * Bit number 24 (0x800000) represents the sign of N. + * N = (-1^sign) * mantissa * 256^(exponent-3) + * + * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). + * MPI uses the most significant bit of the first byte as sign. + * Thus 0x1234560000 is compact (0x05123456) + * and 0xc0de000000 is compact (0x0600c0de) + * + * Bitcoin only uses this "compact" format for encoding difficulty + * targets, which are unsigned 256bit quantities. Thus, all the + * complexities of the sign bit and using base 256 are probably an + * implementation accident. + */ + arith_uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); + uint32_t GetCompact(bool fNegative = false) const; + + friend uint256 ArithToUint256(const arith_uint256 &); + friend arith_uint256 UintToArith256(const uint256 &); +}; + +uint256 ArithToUint256(const arith_uint256 &); +arith_uint256 UintToArith256(const uint256 &); + +#endif // BITCOIN_ARITH_UINT256_H diff --git a/depend/zcash/src/asyncrpcoperation.cpp b/depend/zcash/src/asyncrpcoperation.cpp new file mode 100644 index 000000000..4fa4ddeaf --- /dev/null +++ b/depend/zcash/src/asyncrpcoperation.cpp @@ -0,0 +1,181 @@ +// Copyright (c) 2016 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "asyncrpcoperation.h" + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +static boost::uuids::random_generator uuidgen; + +static std::map OperationStatusMap = { + {OperationStatus::READY, "queued"}, + {OperationStatus::EXECUTING, "executing"}, + {OperationStatus::CANCELLED, "cancelled"}, + {OperationStatus::FAILED, "failed"}, + {OperationStatus::SUCCESS, "success"} +}; + +/** + * Every operation instance should have a globally unique id + */ +AsyncRPCOperation::AsyncRPCOperation() : error_code_(0), error_message_() { + // Set a unique reference for each operation + boost::uuids::uuid uuid = uuidgen(); + id_ = "opid-" + boost::uuids::to_string(uuid); + creation_time_ = (int64_t)time(NULL); + set_state(OperationStatus::READY); +} + +AsyncRPCOperation::AsyncRPCOperation(const AsyncRPCOperation& o) : + id_(o.id_), creation_time_(o.creation_time_), state_(o.state_.load()), + start_time_(o.start_time_), end_time_(o.end_time_), + error_code_(o.error_code_), error_message_(o.error_message_), + result_(o.result_) +{ +} + +AsyncRPCOperation& AsyncRPCOperation::operator=( const AsyncRPCOperation& other ) { + this->id_ = other.id_; + this->creation_time_ = other.creation_time_; + this->state_.store(other.state_.load()); + this->start_time_ = other.start_time_; + this->end_time_ = other.end_time_; + this->error_code_ = other.error_code_; + this->error_message_ = other.error_message_; + this->result_ = other.result_; + return *this; +} + + +AsyncRPCOperation::~AsyncRPCOperation() { +} + +/** + * Override this cancel() method if you can interrupt main() when executing. + */ +void AsyncRPCOperation::cancel() { + if (isReady()) { + set_state(OperationStatus::CANCELLED); + } +} + +/** + * Start timing the execution run of the code you're interested in + */ +void AsyncRPCOperation::start_execution_clock() { + std::lock_guard guard(lock_); + start_time_ = std::chrono::system_clock::now(); +} + +/** + * Stop timing the execution run + */ +void AsyncRPCOperation::stop_execution_clock() { + std::lock_guard guard(lock_); + end_time_ = std::chrono::system_clock::now(); +} + +/** + * Implement this virtual method in any subclass. This is just an example implementation. + */ +void AsyncRPCOperation::main() { + if (isCancelled()) { + return; + } + + set_state(OperationStatus::EXECUTING); + + start_execution_clock(); + + // Do some work here.. + + stop_execution_clock(); + + // If there was an error, you might set it like this: + /* + setErrorCode(123); + setErrorMessage("Murphy's law"); + setState(OperationStatus::FAILED); + */ + + // Otherwise, if the operation was a success: + UniValue v(UniValue::VSTR, "We have a result!"); + set_result(v); + set_state(OperationStatus::SUCCESS); +} + +/** + * Return the error of the completed operation as a UniValue object. + * If there is no error, return null UniValue. + */ +UniValue AsyncRPCOperation::getError() const { + if (!isFailed()) { + return NullUniValue; + } + + std::lock_guard guard(lock_); + UniValue error(UniValue::VOBJ); + error.pushKV("code", this->error_code_); + error.pushKV("message", this->error_message_); + return error; +} + +/** + * Return the result of the completed operation as a UniValue object. + * If the operation did not succeed, return null UniValue. + */ +UniValue AsyncRPCOperation::getResult() const { + if (!isSuccess()) { + return NullUniValue; + } + + std::lock_guard guard(lock_); + return this->result_; +} + + +/** + * Returns a status UniValue object. + * If the operation has failed, it will include an error object. + * If the operation has succeeded, it will include the result value. + * If the operation was cancelled, there will be no error object or result value. + */ +UniValue AsyncRPCOperation::getStatus() const { + OperationStatus status = this->getState(); + UniValue obj(UniValue::VOBJ); + obj.pushKV("id", this->id_); + obj.pushKV("status", OperationStatusMap[status]); + obj.pushKV("creation_time", this->creation_time_); + // TODO: Issue #1354: There may be other useful metadata to return to the user. + UniValue err = this->getError(); + if (!err.isNull()) { + obj.pushKV("error", err.get_obj()); + } + UniValue result = this->getResult(); + if (!result.isNull()) { + obj.pushKV("result", result); + + // Include execution time for successful operation + std::chrono::duration elapsed_seconds = end_time_ - start_time_; + obj.pushKV("execution_secs", elapsed_seconds.count()); + + } + return obj; +} + +/** + * Return the operation state in human readable form. + */ +std::string AsyncRPCOperation::getStateAsString() const { + OperationStatus status = this->getState(); + return OperationStatusMap[status]; +} diff --git a/depend/zcash/src/asyncrpcoperation.h b/depend/zcash/src/asyncrpcoperation.h new file mode 100644 index 000000000..9879e23d0 --- /dev/null +++ b/depend/zcash/src/asyncrpcoperation.h @@ -0,0 +1,153 @@ +// Copyright (c) 2016 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + + +#ifndef ZCASH_ASYNCRPCOPERATION_H +#define ZCASH_ASYNCRPCOPERATION_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +/** + * AsyncRPCOperation objects are submitted to the AsyncRPCQueue for processing. + * + * To subclass AsyncRPCOperation, implement the main() method. + * Update the operation status as work is underway and completes. + * If main() can be interrupted, implement the cancel() method. + */ + +typedef std::string AsyncRPCOperationId; + +typedef enum class operationStateEnum { + READY = 0, + EXECUTING, + CANCELLED, + FAILED, + SUCCESS +} OperationStatus; + +class AsyncRPCOperation { +public: + AsyncRPCOperation(); + virtual ~AsyncRPCOperation(); + + // You must implement this method in your subclass. + virtual void main(); + + // Override this method if you can interrupt execution of main() in your subclass. + void cancel(); + + // Getters and setters + + OperationStatus getState() const { + return state_.load(); + } + + AsyncRPCOperationId getId() const { + return id_; + } + + int64_t getCreationTime() const { + return creation_time_; + } + + // Override this method to add data to the default status object. + virtual UniValue getStatus() const; + + UniValue getError() const; + + UniValue getResult() const; + + std::string getStateAsString() const; + + int getErrorCode() const { + std::lock_guard guard(lock_); + return error_code_; + } + + std::string getErrorMessage() const { + std::lock_guard guard(lock_); + return error_message_; + } + + bool isCancelled() const { + return OperationStatus::CANCELLED == getState(); + } + + bool isExecuting() const { + return OperationStatus::EXECUTING == getState(); + } + + bool isReady() const { + return OperationStatus::READY == getState(); + } + + bool isFailed() const { + return OperationStatus::FAILED == getState(); + } + + bool isSuccess() const { + return OperationStatus::SUCCESS == getState(); + } + +protected: + // The state_ is atomic because only it can be mutated externally. + // For example, the user initiates a shut down of the application, which closes + // the AsyncRPCQueue, which in turn invokes cancel() on all operations. + // The member variables below are protected rather than private in order to + // allow subclasses of AsyncRPCOperation the ability to access and update + // internal state. Currently, all operations are executed in a single-thread + // by a single worker. + mutable std::mutex lock_; // lock on this when read/writing non-atomics + UniValue result_; + int error_code_; + std::string error_message_; + std::atomic state_; + std::chrono::time_point start_time_, end_time_; + + void start_execution_clock(); + void stop_execution_clock(); + + void set_state(OperationStatus state) { + this->state_.store(state); + } + + void set_error_code(int errorCode) { + std::lock_guard guard(lock_); + this->error_code_ = errorCode; + } + + void set_error_message(std::string errorMessage) { + std::lock_guard guard(lock_); + this->error_message_ = errorMessage; + } + + void set_result(UniValue v) { + std::lock_guard guard(lock_); + this->result_ = v; + } + +private: + + // Derived classes should write their own copy constructor and assignment operators + AsyncRPCOperation(const AsyncRPCOperation& orig); + AsyncRPCOperation& operator=( const AsyncRPCOperation& other ); + + // Initialized in the operation constructor, never to be modified again. + AsyncRPCOperationId id_; + int64_t creation_time_; +}; + +#endif // ZCASH_ASYNCRPCOPERATION_H + diff --git a/depend/zcash/src/asyncrpcqueue.cpp b/depend/zcash/src/asyncrpcqueue.cpp new file mode 100644 index 000000000..e03244945 --- /dev/null +++ b/depend/zcash/src/asyncrpcqueue.cpp @@ -0,0 +1,233 @@ +// Copyright (c) 2016 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "asyncrpcqueue.h" + +static std::atomic workerCounter(0); + +/** + * Static method to return the shared/default queue. + */ +shared_ptr AsyncRPCQueue::sharedInstance() { + // Thread-safe in C+11 and gcc 4.3 + static shared_ptr q = std::make_shared(); + return q; +} + +AsyncRPCQueue::AsyncRPCQueue() : closed_(false), finish_(false) { +} + +AsyncRPCQueue::~AsyncRPCQueue() { + closeAndWait(); // join on all worker threads +} + +/** + * A worker will execute this method on a new thread + */ +void AsyncRPCQueue::run(size_t workerId) { + + while (true) { + AsyncRPCOperationId key; + std::shared_ptr operation; + { + std::unique_lock guard(lock_); + while (operation_id_queue_.empty() && !isClosed() && !isFinishing()) { + this->condition_.wait(guard); + } + + // Exit if the queue is empty and we are finishing up + if (isFinishing() && operation_id_queue_.empty()) { + break; + } + + // Exit if the queue is closing. + if (isClosed()) { + while (!operation_id_queue_.empty()) { + operation_id_queue_.pop(); + } + break; + } + + // Get operation id + key = operation_id_queue_.front(); + operation_id_queue_.pop(); + + // Search operation map + AsyncRPCOperationMap::const_iterator iter = operation_map_.find(key); + if (iter != operation_map_.end()) { + operation = iter->second; + } + } + + if (!operation) { + // cannot find operation in map, may have been removed + } else if (operation->isCancelled()) { + // skip cancelled operation + } else { + operation->main(); + } + } +} + + +/** + * Add shared_ptr to operation. + * + * To retain polymorphic behaviour, i.e. main() method of derived classes is invoked, + * caller should create the shared_ptr like this: + * + * std::shared_ptr ptr(new MyCustomAsyncRPCOperation(params)); + * + * Don't use std::make_shared(). + */ +void AsyncRPCQueue::addOperation(const std::shared_ptr &ptrOperation) { + std::lock_guard guard(lock_); + + // Don't add if queue is closed or finishing + if (isClosed() || isFinishing()) { + return; + } + + AsyncRPCOperationId id = ptrOperation->getId(); + operation_map_.emplace(id, ptrOperation); + operation_id_queue_.push(id); + this->condition_.notify_one(); +} + +/** + * Return the operation for a given operation id. + */ +std::shared_ptr AsyncRPCQueue::getOperationForId(AsyncRPCOperationId id) const { + std::shared_ptr ptr; + + std::lock_guard guard(lock_); + AsyncRPCOperationMap::const_iterator iter = operation_map_.find(id); + if (iter != operation_map_.end()) { + ptr = iter->second; + } + return ptr; +} + +/** + * Return the operation for a given operation id and then remove the operation from internal storage. + */ +std::shared_ptr AsyncRPCQueue::popOperationForId(AsyncRPCOperationId id) { + std::shared_ptr ptr = getOperationForId(id); + if (ptr) { + std::lock_guard guard(lock_); + // Note: if the id still exists in the operationIdQueue, when it gets processed by a worker + // there will no operation in the map to execute, so nothing will happen. + operation_map_.erase(id); + } + return ptr; +} + +/** + * Return true if the queue is closed to new operations. + */ +bool AsyncRPCQueue::isClosed() const { + return closed_.load(); +} + +/** + * Close the queue and cancel all existing operations + */ +void AsyncRPCQueue::close() { + closed_.store(true); + cancelAllOperations(); +} + +/** + * Return true if the queue is finishing up + */ +bool AsyncRPCQueue::isFinishing() const { + return finish_.load(); +} + +/** + * Close the queue but finish existing operations. Do not accept new operations. + */ +void AsyncRPCQueue::finish() { + finish_.store(true); +} + +/** + * Call cancel() on all operations + */ +void AsyncRPCQueue::cancelAllOperations() { + std::lock_guard guard(lock_); + for (auto key : operation_map_) { + key.second->cancel(); + } + this->condition_.notify_all(); +} + +/** + * Return the number of operations in the queue + */ +size_t AsyncRPCQueue::getOperationCount() const { + std::lock_guard guard(lock_); + return operation_id_queue_.size(); +} + +/** + * Spawn a worker thread + */ +void AsyncRPCQueue::addWorker() { + std::lock_guard guard(lock_); + workers_.emplace_back( std::thread(&AsyncRPCQueue::run, this, ++workerCounter) ); +} + +/** + * Return the number of worker threads spawned by the queue + */ +size_t AsyncRPCQueue::getNumberOfWorkers() const { + std::lock_guard guard(lock_); + return workers_.size(); +} + +/** + * Return a list of all known operation ids found in internal storage. + */ +std::vector AsyncRPCQueue::getAllOperationIds() const { + std::lock_guard guard(lock_); + std::vector v; + for(auto & entry: operation_map_) { + v.push_back(entry.first); + } + return v; +} + +/** + * Calling thread will close and wait for worker threads to join. + */ +void AsyncRPCQueue::closeAndWait() { + close(); + wait_for_worker_threads(); +} + +/** + * Block current thread until all workers have finished their tasks. + */ +void AsyncRPCQueue::finishAndWait() { + finish(); + wait_for_worker_threads(); +} + +/** + * Block current thread until all operations are finished or the queue has closed. + */ +void AsyncRPCQueue::wait_for_worker_threads() { + // Notify any workers who are waiting, so they see the updated queue state + { + std::lock_guard guard(lock_); + this->condition_.notify_all(); + } + + for (std::thread & t : this->workers_) { + if (t.joinable()) { + t.join(); + } + } +} diff --git a/depend/zcash/src/asyncrpcqueue.h b/depend/zcash/src/asyncrpcqueue.h new file mode 100644 index 000000000..f798c2d33 --- /dev/null +++ b/depend/zcash/src/asyncrpcqueue.h @@ -0,0 +1,68 @@ +// Copyright (c) 2016 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef ZCASH_ASYNCRPCQUEUE_H +#define ZCASH_ASYNCRPCQUEUE_H + +#include "asyncrpcoperation.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef std::unordered_map > AsyncRPCOperationMap; + + +class AsyncRPCQueue { +public: + static shared_ptr sharedInstance(); + + AsyncRPCQueue(); + virtual ~AsyncRPCQueue(); + + // We don't want queue to be copied or moved around + AsyncRPCQueue(AsyncRPCQueue const&) = delete; // Copy construct + AsyncRPCQueue(AsyncRPCQueue&&) = delete; // Move construct + AsyncRPCQueue& operator=(AsyncRPCQueue const&) = delete; // Copy assign + AsyncRPCQueue& operator=(AsyncRPCQueue &&) = delete; // Move assign + + void addWorker(); + size_t getNumberOfWorkers() const; + bool isClosed() const; + bool isFinishing() const; + void close(); // close queue and cancel all operations + void finish(); // close queue but finishing existing operations + void closeAndWait(); // block thread until all threads have terminated. + void finishAndWait(); // block thread until existing operations have finished, threads terminated + void cancelAllOperations(); // mark all operations in the queue as cancelled + size_t getOperationCount() const; + std::shared_ptr getOperationForId(AsyncRPCOperationId) const; + std::shared_ptr popOperationForId(AsyncRPCOperationId); + void addOperation(const std::shared_ptr &ptrOperation); + std::vector getAllOperationIds() const; + +private: + // addWorker() will spawn a new thread on run()) + void run(size_t workerId); + void wait_for_worker_threads(); + + // Why this is not a recursive lock: http://www.zaval.org/resources/library/butenhof1.html + mutable std::mutex lock_; + std::condition_variable condition_; + std::atomic closed_; + std::atomic finish_; + AsyncRPCOperationMap operation_map_; + std::queue operation_id_queue_; + std::vector workers_; +}; + +#endif // ZCASH_ASYNCRPCQUEUE_H diff --git a/depend/zcash/src/base58.cpp b/depend/zcash/src/base58.cpp new file mode 100644 index 000000000..3e2f18b40 --- /dev/null +++ b/depend/zcash/src/base58.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "base58.h" + +#include +#include + +#include +#include + +/** All alphanumeric characters except for "0", "I", "O", and "l" */ +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +bool DecodeBase58(const char* psz, std::vector& vch) +{ + // Skip leading spaces. + while (*psz && isspace(*psz)) + psz++; + // Skip and count leading '1's. + int zeroes = 0; + while (*psz == '1') { + zeroes++; + psz++; + } + // Allocate enough space in big-endian base256 representation. + std::vector b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. + // Process the characters. + while (*psz && !isspace(*psz)) { + // Decode base58 character + const char* ch = strchr(pszBase58, *psz); + if (ch == NULL) + return false; + // Apply "b256 = b256 * 58 + ch". + int carry = ch - pszBase58; + for (std::vector::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { + carry += 58 * (*it); + *it = carry % 256; + carry /= 256; + } + assert(carry == 0); + psz++; + } + // Skip trailing spaces. + while (isspace(*psz)) + psz++; + if (*psz != 0) + return false; + // Skip leading zeroes in b256. + std::vector::iterator it = b256.begin(); + while (it != b256.end() && *it == 0) + it++; + // Copy result into output vector. + vch.reserve(zeroes + (b256.end() - it)); + vch.assign(zeroes, 0x00); + while (it != b256.end()) + vch.push_back(*(it++)); + return true; +} + +std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ + // Skip & count leading zeroes. + int zeroes = 0; + while (pbegin != pend && *pbegin == 0) { + pbegin++; + zeroes++; + } + // Allocate enough space in big-endian base58 representation. + std::vector b58((pend - pbegin) * 138 / 100 + 1); // log(256) / log(58), rounded up. + // Process the bytes. + while (pbegin != pend) { + int carry = *pbegin; + // Apply "b58 = b58 * 256 + ch". + for (std::vector::reverse_iterator it = b58.rbegin(); it != b58.rend(); it++) { + carry += 256 * (*it); + *it = carry % 58; + carry /= 58; + } + assert(carry == 0); + pbegin++; + } + // Skip leading zeroes in base58 result. + std::vector::iterator it = b58.begin(); + while (it != b58.end() && *it == 0) + it++; + // Translate the result into a string. + std::string str; + str.reserve(zeroes + (b58.end() - it)); + str.assign(zeroes, '1'); + while (it != b58.end()) + str += pszBase58[*(it++)]; + return str; +} + +std::string EncodeBase58(const std::vector& vch) +{ + return EncodeBase58(vch.data(), vch.data() + vch.size()); +} + +bool DecodeBase58(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + +std::string EncodeBase58Check(const std::vector& vchIn) +{ + // add 4-byte hash check to the end + std::vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +bool DecodeBase58Check(const char* psz, std::vector& vchRet) +{ + if (!DecodeBase58(psz, vchRet) || + (vchRet.size() < 4)) { + vchRet.clear(); + return false; + } + // re-calculate the checksum, insure it matches the included 4-byte checksum + uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) { + vchRet.clear(); + return false; + } + vchRet.resize(vchRet.size() - 4); + return true; +} + +bool DecodeBase58Check(const std::string& str, std::vector& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} diff --git a/depend/zcash/src/base58.h b/depend/zcash/src/base58.h new file mode 100644 index 000000000..f29c37556 --- /dev/null +++ b/depend/zcash/src/base58.h @@ -0,0 +1,61 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +/** + * Why base-58 instead of standard base-64 encoding? + * - Don't want 0OIl characters that look the same in some fonts and + * could be used to create visually identical looking data. + * - A string with non-alphanumeric characters is not as easily accepted as input. + * - E-mail usually won't line-break if there's no punctuation to break at. + * - Double-clicking selects the whole string as one word if it's all alphanumeric. + */ +#ifndef BITCOIN_BASE58_H +#define BITCOIN_BASE58_H + +#include +#include + +/** + * Encode a byte sequence as a base58-encoded string. + * pbegin and pend cannot be NULL, unless both are. + */ +std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend); + +/** + * Encode a byte vector as a base58-encoded string + */ +std::string EncodeBase58(const std::vector& vch); + +/** + * Decode a base58-encoded string (psz) into a byte vector (vchRet). + * return true if decoding is successful. + * psz cannot be NULL. + */ +bool DecodeBase58(const char* psz, std::vector& vchRet); + +/** + * Decode a base58-encoded string (str) into a byte vector (vchRet). + * return true if decoding is successful. + */ +bool DecodeBase58(const std::string& str, std::vector& vchRet); + +/** + * Encode a byte vector into a base58-encoded string, including checksum + */ +std::string EncodeBase58Check(const std::vector& vchIn); + +/** + * Decode a base58-encoded string (psz) that includes a checksum into a byte + * vector (vchRet), return true if decoding is successful + */ +bool DecodeBase58Check(const char* psz, std::vector& vchRet); + +/** + * Decode a base58-encoded string (str) that includes a checksum into a byte + * vector (vchRet), return true if decoding is successful + */ +bool DecodeBase58Check(const std::string& str, std::vector& vchRet); + +#endif // BITCOIN_BASE58_H diff --git a/depend/zcash/src/bech32.cpp b/depend/zcash/src/bech32.cpp new file mode 100644 index 000000000..8910d0345 --- /dev/null +++ b/depend/zcash/src/bech32.cpp @@ -0,0 +1,194 @@ +// Copyright (c) 2017 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bech32.h" + +namespace +{ + +typedef std::vector data; + +/** The Bech32 character set for encoding. */ +const char* CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + +/** The Bech32 character set for decoding. */ +const int8_t CHARSET_REV[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1, + -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, + 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1 +}; + +/** Concatenate two byte arrays. */ +data Cat(data x, const data& y) +{ + x.insert(x.end(), y.begin(), y.end()); + return x; +} + +/** This function will compute what 6 5-bit values to XOR into the last 6 input values, in order to + * make the checksum 0. These 6 values are packed together in a single 30-bit integer. The higher + * bits correspond to earlier values. */ +uint32_t PolyMod(const data& v) +{ + // The input is interpreted as a list of coefficients of a polynomial over F = GF(32), with an + // implicit 1 in front. If the input is [v0,v1,v2,v3,v4], that polynomial is v(x) = + // 1*x^5 + v0*x^4 + v1*x^3 + v2*x^2 + v3*x + v4. The implicit 1 guarantees that + // [v0,v1,v2,...] has a distinct checksum from [0,v0,v1,v2,...]. + + // The output is a 30-bit integer whose 5-bit groups are the coefficients of the remainder of + // v(x) mod g(x), where g(x) is the Bech32 generator, + // x^6 + {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18}. g(x) is chosen in such a way + // that the resulting code is a BCH code, guaranteeing detection of up to 3 errors within a + // window of 1023 characters. Among the various possible BCH codes, one was selected to in + // fact guarantee detection of up to 4 errors within a window of 89 characters. + + // Note that the coefficients are elements of GF(32), here represented as decimal numbers + // between {}. In this finite field, addition is just XOR of the corresponding numbers. For + // example, {27} + {13} = {27 ^ 13} = {22}. Multiplication is more complicated, and requires + // treating the bits of values themselves as coefficients of a polynomial over a smaller field, + // GF(2), and multiplying those polynomials mod a^5 + a^3 + 1. For example, {5} * {26} = + // (a^2 + 1) * (a^4 + a^3 + a) = (a^4 + a^3 + a) * a^2 + (a^4 + a^3 + a) = a^6 + a^5 + a^4 + a + // = a^3 + 1 (mod a^5 + a^3 + 1) = {9}. + + // During the course of the loop below, `c` contains the bitpacked coefficients of the + // polynomial constructed from just the values of v that were processed so far, mod g(x). In + // the above example, `c` initially corresponds to 1 mod (x), and after processing 2 inputs of + // v, it corresponds to x^2 + v0*x + v1 mod g(x). As 1 mod g(x) = 1, that is the starting value + // for `c`. + uint32_t c = 1; + for (auto v_i : v) { + // We want to update `c` to correspond to a polynomial with one extra term. If the initial + // value of `c` consists of the coefficients of c(x) = f(x) mod g(x), we modify it to + // correspond to c'(x) = (f(x) * x + v_i) mod g(x), where v_i is the next input to + // process. Simplifying: + // c'(x) = (f(x) * x + v_i) mod g(x) + // ((f(x) mod g(x)) * x + v_i) mod g(x) + // (c(x) * x + v_i) mod g(x) + // If c(x) = c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5, we want to compute + // c'(x) = (c0*x^5 + c1*x^4 + c2*x^3 + c3*x^2 + c4*x + c5) * x + v_i mod g(x) + // = c0*x^6 + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i mod g(x) + // = c0*(x^6 mod g(x)) + c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i + // If we call (x^6 mod g(x)) = k(x), this can be written as + // c'(x) = (c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i) + c0*k(x) + + // First, determine the value of c0: + uint8_t c0 = c >> 25; + + // Then compute c1*x^5 + c2*x^4 + c3*x^3 + c4*x^2 + c5*x + v_i: + c = ((c & 0x1ffffff) << 5) ^ v_i; + + // Finally, for each set bit n in c0, conditionally add {2^n}k(x): + if (c0 & 1) c ^= 0x3b6a57b2; // k(x) = {29}x^5 + {22}x^4 + {20}x^3 + {21}x^2 + {29}x + {18} + if (c0 & 2) c ^= 0x26508e6d; // {2}k(x) = {19}x^5 + {5}x^4 + x^3 + {3}x^2 + {19}x + {13} + if (c0 & 4) c ^= 0x1ea119fa; // {4}k(x) = {15}x^5 + {10}x^4 + {2}x^3 + {6}x^2 + {15}x + {26} + if (c0 & 8) c ^= 0x3d4233dd; // {8}k(x) = {30}x^5 + {20}x^4 + {4}x^3 + {12}x^2 + {30}x + {29} + if (c0 & 16) c ^= 0x2a1462b3; // {16}k(x) = {21}x^5 + x^4 + {8}x^3 + {24}x^2 + {21}x + {19} + } + return c; +} + +/** Convert to lower case. */ +inline unsigned char LowerCase(unsigned char c) +{ + return (c >= 'A' && c <= 'Z') ? (c - 'A') + 'a' : c; +} + +/** Expand a HRP for use in checksum computation. */ +data ExpandHRP(const std::string& hrp) +{ + data ret; + ret.reserve(hrp.size() + 90); + ret.resize(hrp.size() * 2 + 1); + for (size_t i = 0; i < hrp.size(); ++i) { + unsigned char c = hrp[i]; + ret[i] = c >> 5; + ret[i + hrp.size() + 1] = c & 0x1f; + } + ret[hrp.size()] = 0; + return ret; +} + +/** Verify a checksum. */ +bool VerifyChecksum(const std::string& hrp, const data& values) +{ + // PolyMod computes what value to xor into the final values to make the checksum 0. However, + // if we required that the checksum was 0, it would be the case that appending a 0 to a valid + // list of values would result in a new valid list. For that reason, Bech32 requires the + // resulting checksum to be 1 instead. + return PolyMod(Cat(ExpandHRP(hrp), values)) == 1; +} + +/** Create a checksum. */ +data CreateChecksum(const std::string& hrp, const data& values) +{ + data enc = Cat(ExpandHRP(hrp), values); + enc.resize(enc.size() + 6); // Append 6 zeroes + uint32_t mod = PolyMod(enc) ^ 1; // Determine what to XOR into those 6 zeroes. + data ret(6); + for (size_t i = 0; i < 6; ++i) { + // Convert the 5-bit groups in mod to checksum values. + ret[i] = (mod >> (5 * (5 - i))) & 31; + } + return ret; +} + +} // namespace + +namespace bech32 +{ + +/** Encode a Bech32 string. */ +std::string Encode(const std::string& hrp, const data& values) { + data checksum = CreateChecksum(hrp, values); + data combined = Cat(values, checksum); + std::string ret = hrp + '1'; + ret.reserve(ret.size() + combined.size()); + for (auto c : combined) { + if (c >= 32) { + return ""; + } + ret += CHARSET[c]; + } + return ret; +} + +/** Decode a Bech32 string. */ +std::pair Decode(const std::string& str) { + bool lower = false, upper = false; + for (size_t i = 0; i < str.size(); ++i) { + unsigned char c = str[i]; + if (c < 33 || c > 126) return {}; + if (c >= 'a' && c <= 'z') lower = true; + if (c >= 'A' && c <= 'Z') upper = true; + } + if (lower && upper) return {}; + size_t pos = str.rfind('1'); + if (str.size() > 1023 || pos == str.npos || pos == 0 || pos + 7 > str.size()) { + return {}; + } + data values(str.size() - 1 - pos); + for (size_t i = 0; i < str.size() - 1 - pos; ++i) { + unsigned char c = str[i + pos + 1]; + int8_t rev = (c < 33 || c > 126) ? -1 : CHARSET_REV[c]; + if (rev == -1) { + return {}; + } + values[i] = rev; + } + std::string hrp; + for (size_t i = 0; i < pos; ++i) { + hrp += LowerCase(str[i]); + } + if (!VerifyChecksum(hrp, values)) { + return {}; + } + return {hrp, data(values.begin(), values.end() - 6)}; +} + +} // namespace bech32 diff --git a/depend/zcash/src/bech32.h b/depend/zcash/src/bech32.h new file mode 100644 index 000000000..eecc6e29f --- /dev/null +++ b/depend/zcash/src/bech32.h @@ -0,0 +1,30 @@ +// Copyright (c) 2017 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +// Bech32 is a string encoding format used in newer address types. +// The output consists of a human-readable part (alphanumeric), a +// separator character (1), and a base32 data section, the last +// 6 characters of which are a checksum. +// +// For more information, see BIP 173. + +#ifndef BITCOIN_BECH32_H +#define BITCOIN_BECH32_H + +#include +#include +#include + +namespace bech32 +{ + +/** Encode a Bech32 string. Returns the empty string in case of failure. */ +std::string Encode(const std::string& hrp, const std::vector& values); + +/** Decode a Bech32 string. Returns (hrp, data). Empty hrp means failure. */ +std::pair> Decode(const std::string& str); + +} // namespace bech32 + +#endif // BITCOIN_BECH32_H diff --git a/depend/zcash/src/bench/.gitignore b/depend/zcash/src/bench/.gitignore new file mode 100644 index 000000000..e231fe4ca --- /dev/null +++ b/depend/zcash/src/bench/.gitignore @@ -0,0 +1 @@ +bench_bitcoin diff --git a/depend/zcash/src/bench/Examples.cpp b/depend/zcash/src/bench/Examples.cpp new file mode 100644 index 000000000..3ca21f4dc --- /dev/null +++ b/depend/zcash/src/bench/Examples.cpp @@ -0,0 +1,34 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" +#include "main.h" +#include "utiltime.h" + +// Sanity test: this should loop ten times, and +// min/max/average should be close to 100ms. +static void Sleep100ms(benchmark::State& state) +{ + while (state.KeepRunning()) { + MilliSleep(100); + } +} + +BENCHMARK(Sleep100ms); + +// Extremely fast-running benchmark: +#include + +volatile double sum = 0.0; // volatile, global so not optimized away + +static void Trig(benchmark::State& state) +{ + double d = 0.01; + while (state.KeepRunning()) { + sum += sin(d); + d += 0.000001; + } +} + +BENCHMARK(Trig); diff --git a/depend/zcash/src/bench/base58.cpp b/depend/zcash/src/bench/base58.cpp new file mode 100644 index 000000000..d0a4234a4 --- /dev/null +++ b/depend/zcash/src/bench/base58.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2016 the Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" + +#include "main.h" +#include "base58.h" + +#include +#include +#include + + +static void Base58Encode(benchmark::State& state) +{ + static const std::array buff = { + { + 17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147, + 227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90, + 200, 24 + } + }; + while (state.KeepRunning()) { + EncodeBase58(buff.data(), buff.data() + buff.size()); + } +} + + +static void Base58CheckEncode(benchmark::State& state) +{ + static const std::array buff = { + { + 17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147, + 227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90, + 200, 24 + } + }; + std::vector vch; + vch.assign(buff.begin(), buff.end()); + while (state.KeepRunning()) { + EncodeBase58Check(vch); + } +} + + +static void Base58Decode(benchmark::State& state) +{ + const char* addr = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem"; + std::vector vch; + while (state.KeepRunning()) { + DecodeBase58(addr, vch); + } +} + + +BENCHMARK(Base58Encode); +BENCHMARK(Base58CheckEncode); +BENCHMARK(Base58Decode); diff --git a/depend/zcash/src/bench/bench.cpp b/depend/zcash/src/bench/bench.cpp new file mode 100644 index 000000000..268e3259d --- /dev/null +++ b/depend/zcash/src/bench/bench.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" + +#include "perf.h" + +#include +#include +#include + +benchmark::BenchRunner::BenchmarkMap &benchmark::BenchRunner::benchmarks() { + static std::map benchmarks_map; + return benchmarks_map; +} + +benchmark::BenchRunner::BenchRunner(std::string name, benchmark::BenchFunction func) +{ + benchmarks().insert(std::make_pair(name, func)); +} + +void +benchmark::BenchRunner::RunAll(benchmark::duration elapsedTimeForOne) +{ + perf_init(); + if (std::ratio_less_equal::value) { + std::cerr << "WARNING: Clock precision is worse than microsecond - benchmarks may be less accurate!\n"; + } + std::cout << "#Benchmark" << "," << "count" << "," << "min(ns)" << "," << "max(ns)" << "," << "average(ns)" << "," + << "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n"; + + for (const auto &p: benchmarks()) { + State state(p.first, elapsedTimeForOne); + p.second(state); + } + perf_fini(); +} + +bool benchmark::State::KeepRunning() +{ + if (count & countMask) { + ++count; + return true; + } + time_point now; + + uint64_t nowCycles; + if (count == 0) { + lastTime = beginTime = now = clock::now(); + lastCycles = beginCycles = nowCycles = perf_cpucycles(); + } + else { + now = clock::now(); + auto elapsed = now - lastTime; + auto elapsedOne = elapsed / (countMask + 1); + if (elapsedOne < minTime) minTime = elapsedOne; + if (elapsedOne > maxTime) maxTime = elapsedOne; + + // We only use relative values, so don't have to handle 64-bit wrap-around specially + nowCycles = perf_cpucycles(); + uint64_t elapsedOneCycles = (nowCycles - lastCycles) / (countMask + 1); + if (elapsedOneCycles < minCycles) minCycles = elapsedOneCycles; + if (elapsedOneCycles > maxCycles) maxCycles = elapsedOneCycles; + + if (elapsed*128 < maxElapsed) { + // If the execution was much too fast (1/128th of maxElapsed), increase the count mask by 8x and restart timing. + // The restart avoids including the overhead of this code in the measurement. + countMask = ((countMask<<3)|7) & ((1LL<<60)-1); + count = 0; + minTime = duration::max(); + maxTime = duration::zero(); + minCycles = std::numeric_limits::max(); + maxCycles = std::numeric_limits::min(); + return true; + } + if (elapsed*16 < maxElapsed) { + uint64_t newCountMask = ((countMask<<1)|1) & ((1LL<<60)-1); + if ((count & newCountMask)==0) { + countMask = newCountMask; + } + } + } + lastTime = now; + lastCycles = nowCycles; + ++count; + + if (now - beginTime < maxElapsed) return true; // Keep going + + --count; + + assert(count != 0 && "count == 0 => (now == 0 && beginTime == 0) => return above"); + + // Output results + // Duration casts are only necessary here because hardware with sub-nanosecond clocks + // will lose precision. + int64_t min_elapsed = std::chrono::duration_cast(minTime).count(); + int64_t max_elapsed = std::chrono::duration_cast(maxTime).count(); + int64_t avg_elapsed = std::chrono::duration_cast((now-beginTime)/count).count(); + int64_t averageCycles = (nowCycles-beginCycles)/count; + std::cout << std::fixed << std::setprecision(15) << name << "," << count << "," << min_elapsed << "," << max_elapsed << "," << avg_elapsed << "," + << minCycles << "," << maxCycles << "," << averageCycles << "\n"; + std::cout.copyfmt(std::ios(nullptr)); + + return false; +} diff --git a/depend/zcash/src/bench/bench.h b/depend/zcash/src/bench/bench.h new file mode 100644 index 000000000..1b529b356 --- /dev/null +++ b/depend/zcash/src/bench/bench.h @@ -0,0 +1,95 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_BENCH_BENCH_H +#define BITCOIN_BENCH_BENCH_H + +#include +#include +#include +#include +#include + +#include +#include + +// Simple micro-benchmarking framework; API mostly matches a subset of the Google Benchmark +// framework (see https://github.com/google/benchmark) +// Why not use the Google Benchmark framework? Because adding Yet Another Dependency +// (that uses cmake as its build system and has lots of features we don't need) isn't +// worth it. + +/* + * Usage: + +static void CODE_TO_TIME(benchmark::State& state) +{ + ... do any setup needed... + while (state.KeepRunning()) { + ... do stuff you want to time... + } + ... do any cleanup needed... +} + +BENCHMARK(CODE_TO_TIME); + + */ + +namespace benchmark { + // In case high_resolution_clock is steady, prefer that, otherwise use steady_clock. + struct best_clock { + using hi_res_clock = std::chrono::high_resolution_clock; + using steady_clock = std::chrono::steady_clock; + using type = std::conditional::type; + }; + using clock = best_clock::type; + using time_point = clock::time_point; + using duration = clock::duration; + + class State { + std::string name; + duration maxElapsed; + time_point beginTime, lastTime; + duration minTime, maxTime; + uint64_t count; + uint64_t countMask; + uint64_t beginCycles; + uint64_t lastCycles; + uint64_t minCycles; + uint64_t maxCycles; + public: + State(std::string _name, duration _maxElapsed) : + name(_name), + maxElapsed(_maxElapsed), + minTime(duration::max()), + maxTime(duration::zero()), + count(0), + countMask(1), + beginCycles(0), + lastCycles(0), + minCycles(std::numeric_limits::max()), + maxCycles(std::numeric_limits::min()) { + } + bool KeepRunning(); + }; + + typedef std::function BenchFunction; + + class BenchRunner + { + typedef std::map BenchmarkMap; + static BenchmarkMap &benchmarks(); + + public: + BenchRunner(std::string name, BenchFunction func); + + static void RunAll(duration elapsedTimeForOne = std::chrono::seconds(1)); + }; +} + +// BENCHMARK(foo) expands to: benchmark::BenchRunner bench_11foo("foo", foo); +#define BENCHMARK(n) \ + benchmark::BenchRunner BOOST_PP_CAT(bench_, BOOST_PP_CAT(__LINE__, n))(BOOST_PP_STRINGIZE(n), n); + +#endif // BITCOIN_BENCH_BENCH_H diff --git a/depend/zcash/src/bench/bench_bitcoin.cpp b/depend/zcash/src/bench/bench_bitcoin.cpp new file mode 100644 index 000000000..ec4edc5b6 --- /dev/null +++ b/depend/zcash/src/bench/bench_bitcoin.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" + +#include "fs.h" +#include "key.h" +#include "main.h" +#include "util.h" + +#include "librustzcash.h" + +const std::function G_TRANSLATION_FUN = nullptr; + +int +main(int argc, char** argv) +{ + ECC_Start(); + auto globalVerifyHandle = new ECCVerifyHandle(); + SetupEnvironment(); + fPrintToDebugLog = false; // don't want to write to debug.log file + + fs::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params"; + fs::path sapling_output = ZC_GetParamsDir() / "sapling-output.params"; + fs::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params"; + + static_assert( + sizeof(fs::path::value_type) == sizeof(codeunit), + "librustzcash not configured correctly"); + auto sapling_spend_str = sapling_spend.native(); + auto sapling_output_str = sapling_output.native(); + auto sprout_groth16_str = sprout_groth16.native(); + + librustzcash_init_zksnark_params( + reinterpret_cast(sapling_spend_str.c_str()), + sapling_spend_str.length(), + reinterpret_cast(sapling_output_str.c_str()), + sapling_output_str.length(), + reinterpret_cast(sprout_groth16_str.c_str()), + sprout_groth16_str.length() + ); + + benchmark::BenchRunner::RunAll(); + + ECC_Stop(); +} diff --git a/depend/zcash/src/bench/checkqueue.cpp b/depend/zcash/src/bench/checkqueue.cpp new file mode 100644 index 000000000..c5903cdd0 --- /dev/null +++ b/depend/zcash/src/bench/checkqueue.cpp @@ -0,0 +1,103 @@ +// Copyright (c) 2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" +#include "util.h" +#include "main.h" +#include "checkqueue.h" +#include "prevector.h" +#include +#include +#include "random.h" + + +// This Benchmark tests the CheckQueue with the lightest +// weight Checks, so it should make any lock contention +// particularly visible +static const int MIN_CORES = 2; +static const size_t BATCHES = 101; +static const size_t BATCH_SIZE = 30; +static const int PREVECTOR_SIZE = 28; +static const unsigned int QUEUE_BATCH_SIZE = 128; +static void CCheckQueueSpeed(benchmark::State& state) +{ + struct FakeJobNoWork { + bool operator()() + { + return true; + } + void swap(FakeJobNoWork& x){}; + }; + CCheckQueue queue {QUEUE_BATCH_SIZE}; + boost::thread_group tg; + for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) { + tg.create_thread([&]{queue.Thread();}); + } + while (state.KeepRunning()) { + CCheckQueueControl control(&queue); + + // We call Add a number of times to simulate the behavior of adding + // a block of transactions at once. + + std::vector> vBatches(BATCHES); + for (auto& vChecks : vBatches) { + vChecks.resize(BATCH_SIZE); + } + for (auto& vChecks : vBatches) { + // We can't make vChecks in the inner loop because we want to measure + // the cost of getting the memory to each thread and we might get the same + // memory + control.Add(vChecks); + } + // control waits for completion by RAII, but + // it is done explicitly here for clarity + control.Wait(); + } + tg.interrupt_all(); + tg.join_all(); +} + +// This Benchmark tests the CheckQueue with a slightly realistic workload, +// where checks all contain a prevector that is indirect 50% of the time +// and there is a little bit of work done between calls to Add. +static void CCheckQueueSpeedPrevectorJob(benchmark::State& state) +{ + struct PrevectorJob { + prevector p; + PrevectorJob(){ + } + PrevectorJob(FastRandomContext& insecure_rand){ + p.resize(insecure_rand.randrange(PREVECTOR_SIZE*2)); + } + bool operator()() + { + return true; + } + void swap(PrevectorJob& x){p.swap(x.p);}; + }; + CCheckQueue queue {QUEUE_BATCH_SIZE}; + boost::thread_group tg; + for (auto x = 0; x < std::max(MIN_CORES, GetNumCores()); ++x) { + tg.create_thread([&]{queue.Thread();}); + } + while (state.KeepRunning()) { + // Make insecure_rand here so that each iteration is identical. + FastRandomContext insecure_rand(true); + CCheckQueueControl control(&queue); + std::vector> vBatches(BATCHES); + for (auto& vChecks : vBatches) { + vChecks.reserve(BATCH_SIZE); + for (size_t x = 0; x < BATCH_SIZE; ++x) + vChecks.emplace_back(insecure_rand); + control.Add(vChecks); + } + // control waits for completion by RAII, but + // it is done explicitly here for clarity + control.Wait(); + } + tg.interrupt_all(); + tg.join_all(); +} +BENCHMARK(CCheckQueueSpeed); +BENCHMARK(CCheckQueueSpeedPrevectorJob); diff --git a/depend/zcash/src/bench/crypto_hash.cpp b/depend/zcash/src/bench/crypto_hash.cpp new file mode 100644 index 000000000..2f70580f0 --- /dev/null +++ b/depend/zcash/src/bench/crypto_hash.cpp @@ -0,0 +1,79 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include + +#include "bench.h" +#include "bloom.h" +#include "random.h" +#include "utiltime.h" +#include "crypto/ripemd160.h" +#include "crypto/sha1.h" +#include "crypto/sha256.h" +#include "crypto/sha512.h" + +/* Number of bytes to hash per iteration */ +static const uint64_t BUFFER_SIZE = 1000*1000; + +static void RIPEMD160(benchmark::State& state) +{ + uint8_t hash[CRIPEMD160::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CRIPEMD160().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA1(benchmark::State& state) +{ + uint8_t hash[CSHA1::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA1().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA256(benchmark::State& state) +{ + uint8_t hash[CSHA256::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA256().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void SHA512(benchmark::State& state) +{ + uint8_t hash[CSHA512::OUTPUT_SIZE]; + std::vector in(BUFFER_SIZE,0); + while (state.KeepRunning()) + CSHA512().Write(begin_ptr(in), in.size()).Finalize(hash); +} + +static void FastRandom_32bit(benchmark::State& state) +{ + FastRandomContext rng(true); + uint32_t x = 0; + while (state.KeepRunning()) { + for (int i = 0; i < 1000000; i++) { + x += rng.rand32(); + } + } +} + +static void FastRandom_1bit(benchmark::State& state) +{ + FastRandomContext rng(true); + uint32_t x = 0; + while (state.KeepRunning()) { + for (int i = 0; i < 1000000; i++) { + x += rng.randbool(); + } + } +} + +BENCHMARK(RIPEMD160); +BENCHMARK(SHA1); +BENCHMARK(SHA256); +BENCHMARK(SHA512); + +BENCHMARK(FastRandom_32bit); +BENCHMARK(FastRandom_1bit); diff --git a/depend/zcash/src/bench/lockedpool.cpp b/depend/zcash/src/bench/lockedpool.cpp new file mode 100644 index 000000000..4226d6b82 --- /dev/null +++ b/depend/zcash/src/bench/lockedpool.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" + +#include "support/lockedpool.h" + +#include +#include + +#define ASIZE 2048 +#define BITER 5000 +#define MSIZE 2048 + +static void LockedPool(benchmark::State& state) +{ + void *synth_base = reinterpret_cast(0x08000000); + const size_t synth_size = 1024*1024; + Arena b(synth_base, synth_size, 16); + + std::vector addr; + for (int x=0; x> 16) & (MSIZE-1)); + } + bool lsb = s & 1; + s >>= 1; + if (lsb) + s ^= 0xf00f00f0; // LFSR period 0xf7ffffe1 + } + } + for (void *ptr: addr) + b.free(ptr); + addr.clear(); +} + +BENCHMARK(LockedPool); diff --git a/depend/zcash/src/bench/perf.cpp b/depend/zcash/src/bench/perf.cpp new file mode 100644 index 000000000..fdc2cb692 --- /dev/null +++ b/depend/zcash/src/bench/perf.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "perf.h" + +#if defined(__i386__) || defined(__x86_64__) + +/* These architectures support querying the cycle counter + * from user space, no need for any syscall overhead. + */ +void perf_init(void) { } +void perf_fini(void) { } + +#elif defined(__linux__) + +#include +#include +#include + +static int fd = -1; +static struct perf_event_attr attr; + +void perf_init(void) +{ + attr.type = PERF_TYPE_HARDWARE; + attr.config = PERF_COUNT_HW_CPU_CYCLES; + fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); +} + +void perf_fini(void) +{ + if (fd != -1) { + close(fd); + } +} + +uint64_t perf_cpucycles(void) +{ + uint64_t result = 0; + if (fd == -1 || read(fd, &result, sizeof(result)) < (ssize_t)sizeof(result)) { + return 0; + } + return result; +} + +#else /* Unhandled platform */ + +void perf_init(void) { } +void perf_fini(void) { } +uint64_t perf_cpucycles(void) { return 0; } + +#endif diff --git a/depend/zcash/src/bench/perf.h b/depend/zcash/src/bench/perf.h new file mode 100644 index 000000000..630c70093 --- /dev/null +++ b/depend/zcash/src/bench/perf.h @@ -0,0 +1,37 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +/** Functions for measurement of CPU cycles */ +#ifndef BITCOIN_BENCH_PERF_H +#define BITCOIN_BENCH_PERF_H + +#include + +#if defined(__i386__) + +static inline uint64_t perf_cpucycles(void) +{ + uint64_t x; + __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); + return x; +} + +#elif defined(__x86_64__) + +static inline uint64_t perf_cpucycles(void) +{ + uint32_t hi, lo; + __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)lo)|(((uint64_t)hi)<<32); +} +#else + +uint64_t perf_cpucycles(void); + +#endif + +void perf_init(void); +void perf_fini(void); + +#endif // BITCOIN_BENCH_PERF_H diff --git a/depend/zcash/src/bench/prevector_destructor.cpp b/depend/zcash/src/bench/prevector_destructor.cpp new file mode 100644 index 000000000..7f2881615 --- /dev/null +++ b/depend/zcash/src/bench/prevector_destructor.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2015-2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" +#include "prevector.h" + +static void PrevectorDestructor(benchmark::State& state) +{ + while (state.KeepRunning()) { + for (auto x = 0; x < 1000; ++x) { + prevector<28, unsigned char> t0; + prevector<28, unsigned char> t1; + t0.resize(28); + t1.resize(29); + } + } +} + +static void PrevectorClear(benchmark::State& state) +{ + + while (state.KeepRunning()) { + for (auto x = 0; x < 1000; ++x) { + prevector<28, unsigned char> t0; + prevector<28, unsigned char> t1; + t0.resize(28); + t0.clear(); + t1.resize(29); + t0.clear(); + } + } +} + +BENCHMARK(PrevectorDestructor); +BENCHMARK(PrevectorClear); diff --git a/depend/zcash/src/bench/rollingbloom.cpp b/depend/zcash/src/bench/rollingbloom.cpp new file mode 100644 index 000000000..038e36fd5 --- /dev/null +++ b/depend/zcash/src/bench/rollingbloom.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include + +#include "bench.h" +#include "bloom.h" + +static void RollingBloom(benchmark::State& state) +{ + CRollingBloomFilter filter(120000, 0.000001); + std::vector data(32); + uint32_t count = 0; + uint32_t nEntriesPerGeneration = (120000 + 1) / 2; + uint32_t countnow = 0; + uint64_t match = 0; + while (state.KeepRunning()) { + count++; + data[0] = count; + data[1] = count >> 8; + data[2] = count >> 16; + data[3] = count >> 24; + if (countnow == nEntriesPerGeneration) { + auto b = benchmark::clock::now(); + filter.insert(data); + auto total = std::chrono::duration_cast(benchmark::clock::now() - b).count(); + std::cout << "RollingBloom-refresh,1," << total << "," << total << "," << total << "\n"; + countnow = 0; + } else { + filter.insert(data); + } + countnow++; + data[0] = count >> 24; + data[1] = count >> 16; + data[2] = count >> 8; + data[3] = count; + match += filter.contains(data); + } +} + +static void RollingBloomReset(benchmark::State& state) +{ + CRollingBloomFilter filter(120000, 0.000001); + while (state.KeepRunning()) { + filter.reset(); + } +} + +BENCHMARK(RollingBloom); +BENCHMARK(RollingBloomReset); // To-backport: 20000 diff --git a/depend/zcash/src/bench/verification.cpp b/depend/zcash/src/bench/verification.cpp new file mode 100644 index 000000000..c7f4c0391 --- /dev/null +++ b/depend/zcash/src/bench/verification.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2019 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bench.h" +#include "coins.h" +#include "consensus/upgrades.h" +#include "keystore.h" +#include "primitives/transaction.h" +#include "script/interpreter.h" +#include "script/sign.h" +#include "streams.h" +#include "uint256.h" +#include "utilstrencodings.h" +#include "version.h" + +#include "librustzcash.h" +#include + +static void ECDSA(benchmark::State& state) +{ + uint32_t consensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId; + CMutableTransaction mtx; + mtx.fOverwintered = true; + mtx.nVersion = SAPLING_TX_VERSION; + mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID; + + CKey key = CKey::TestOnlyRandomKey(false); + CBasicKeyStore keystore; + keystore.AddKeyPubKey(key, key.GetPubKey()); + CKeyID hash = key.GetPubKey().GetID(); + CScript scriptPubKey = GetScriptForDestination(hash); + + // Benchmark a transaction containing a single input and output. + auto nInputs = 1; + for(uint32_t ij = 0; ij < nInputs; ij++) { + uint32_t i = mtx.vin.size(); + uint256 prevId; + prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100"); + COutPoint outpoint(prevId, i); + + mtx.vin.resize(mtx.vin.size() + 1); + mtx.vin[i].prevout = outpoint; + mtx.vin[i].scriptSig = CScript(); + + mtx.vout.resize(mtx.vout.size() + 1); + mtx.vout[i].nValue = 1000; + mtx.vout[i].scriptPubKey = CScript() << OP_1; + } + + std::vector allPrevOutputs; + // for benchmarking we simply use dummy inputs + allPrevOutputs.resize(mtx.vin.size()); + const PrecomputedTransactionData txdata(mtx, allPrevOutputs); + + // sign all inputs + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, txdata, i, 1000, SIGHASH_ALL, consensusBranchId); + assert(hashSigned); + } + + CTransaction tx; + CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); + ssout << mtx; + ssout >> tx; + + ScriptError error; + + while (state.KeepRunning()) { + VerifyScript( + tx.vin[0].scriptSig, + scriptPubKey, + SCRIPT_VERIFY_P2SH, + TransactionSignatureChecker(&tx, txdata, 0, 1000), + consensusBranchId, + &error); + } +} + +static void JoinSplitSig(benchmark::State& state) +{ + Ed25519VerificationKey joinSplitPubKey; + Ed25519SigningKey joinSplitPrivKey; + uint256 dataToBeSigned; + Ed25519Signature joinSplitSig; + + ed25519_generate_keypair(&joinSplitPrivKey, &joinSplitPubKey); + ed25519_sign(&joinSplitPrivKey, dataToBeSigned.begin(), 32, &joinSplitSig); + + while (state.KeepRunning()) { + // Declared with warn_unused_result. + auto res = ed25519_verify( + &joinSplitPubKey, + &joinSplitSig, + dataToBeSigned.begin(), 32); + } +} + +static void SaplingSpend(benchmark::State& state) +{ + SpendDescription spend; + CDataStream ss( + ParseHex("8c6cf86bbb83bf0d075e5bd9bb4b5cd56141577be69f032880b11e26aa32aa5ef09fd00899e4b469fb11f38e9d09dc0379f0b11c23b5fe541765f76695120a03f0261d32af5d2a2b1e5c9a04200cd87d574dc42349de9790012ce560406a8a876a1e54cfcdc0eb74998abec2a9778330eeb2a0ac0e41d0c9ed5824fbd0dbf7da930ab299966ce333fd7bc1321dada0817aac5444e02c754069e218746bf879d5f2a20a8b028324fb2c73171e63336686aa5ec2e6e9a08eb18b87c14758c572f4531ccf6b55d09f44beb8b47563be4eff7a52598d80959dd9c9fee5ac4783d8370cb7d55d460053d3e067b5f9fe75ff2722623fb1825fcba5e9593d4205b38d1f502ff03035463043bd393a5ee039ce75a5d54f21b395255df6627ef96751566326f7d4a77d828aa21b1827282829fcbc42aad59cdb521e1a3aaa08b99ea8fe7fff0a04da31a52260fc6daeccd79bb877bdd8506614282258e15b3fe74bf71a93f4be3b770119edf99a317b205eea7d5ab800362b97384273888106c77d633600"), + SER_NETWORK, + PROTOCOL_VERSION); + ss >> spend; + uint256 dataToBeSigned = uint256S("0x2dbf83fe7b88a7cbd80fac0c719483906bb9a0c4fc69071e4780d5f2c76e592c"); + + auto ctx = librustzcash_sapling_verification_ctx_init(true); + + while (state.KeepRunning()) { + librustzcash_sapling_check_spend( + ctx, + spend.cv.begin(), + spend.anchor.begin(), + spend.nullifier.begin(), + spend.rk.begin(), + spend.zkproof.begin(), + spend.spendAuthSig.begin(), + dataToBeSigned.begin()); + } + + librustzcash_sapling_verification_ctx_free(ctx); +} + +static void SaplingOutput(benchmark::State& state) +{ + OutputDescription output; + CDataStream ss( + ParseHex("edd742af18857e5ec2d71d346a7fe2ac97c137339bd5268eea86d32e0ff4f38f76213fa8cfed3347ac4e8572dd88aff395c0c10a59f8b3f49d2bc539ed6c726667e29d4763f914ddd0abf1cdfa84e44de87c233434c7e69b8b5b8f4623c8aa444163425bae5cef842972fed66046c1c6ce65c866ad894d02e6e6dcaae7a962d9f2ef95757a09c486928e61f0f7aed90ad0a542b0d3dc5fe140dfa7626b9315c77e03b055f19cbacd21a866e46f06c00e0c7792b2a590a611439b510a9aaffcf1073bad23e712a9268b36888e3727033eee2ab4d869f54a843f93b36ef489fb177bf74b41a9644e5d2a0a417c6ac1c8869bc9b83273d453f878ed6fd96b82a5939903f7b64ecaf68ea16e255a7fb7cc0b6d8b5608a1c6b0ed3024cc62c2f0f9c5cfc7b431ae6e9d40815557aa1d010523f9e1960de77b2274cb6710d229d475c87ae900183206ba90cb5bbc8ec0df98341b82726c705e0308ca5dc08db4db609993a1046dfb43dfd8c760be506c0bed799bb2205fc29dc2e654dce731034a23b0aaf6da0199248702ee0523c159f41f4cbfff6c35ace4dd9ae834e44e09c76a0cbdda1d3f6a2c75ad71212daf9575ab5f09ca148718e667f29ddf18c8a330a86ace18a86e89454653902aa393c84c6b694f27d0d42e24e7ac9fe34733de5ec15f5066081ce912c62c1a804a2bb4dedcef7cc80274f6bb9e89e2fce91dc50d6a73c8aefb9872f1cf3524a92626a0b8f39bbf7bf7d96ca2f770fc04d7f457021c536a506a187a93b2245471ddbfb254a71bc4a0d72c8d639a31c7b1920087ffca05c24214157e2e7b28184e91989ef0b14f9b34c3dc3cc0ac64226b9e337095870cb0885737992e120346e630a416a9b217679ce5a778fb15779c136bcecca5efe79012013d77d90b4e99dd22c8f35bc77121716e160d05bd30d288ee8886390ee436f85bdc9029df888a3a3326d9d4ddba5cb5318b3274928829d662e96fea1d601f7a306251ed8c6cc4e5a3a7a98c35a3650482a0eee08f3b4c2da9b22947c96138f1505c2f081f8972d429f3871f32bef4aaa51aa6945df8e9c9760531ac6f627d17c1518202818a91ca304fb4037875c666060597976144fcbbc48a776a2c61beb9515fa8f3ae6d3a041d320a38a8ac75cb47bb9c866ee497fc3cd13299970c4b369c1c2ceb4220af082fbecdd8114492a8e4d713b5a73396fd224b36c1185bd5e20d683e6c8db35346c47ae7401988255da7cfffdced5801067d4d296688ee8fe424b4a8a69309ce257eefb9345ebfda3f6de46bb11ec94133e1f72cd7ac54934d6cf17b3440800e70b80ebc7c7bfc6fb0fc2c"), + SER_NETWORK, + PROTOCOL_VERSION); + ss >> output; + + auto ctx = librustzcash_sapling_verification_ctx_init(true); + + while (state.KeepRunning()) { + librustzcash_sapling_check_output( + ctx, + output.cv.begin(), + output.cmu.begin(), + output.ephemeralKey.begin(), + output.zkproof.begin()); + } + + librustzcash_sapling_verification_ctx_free(ctx); +} + +BENCHMARK(ECDSA); +BENCHMARK(JoinSplitSig); +BENCHMARK(SaplingSpend); +BENCHMARK(SaplingOutput); diff --git a/depend/zcash/src/bitcoin-cli-res.rc b/depend/zcash/src/bitcoin-cli-res.rc new file mode 100644 index 000000000..607c44420 --- /dev/null +++ b/depend/zcash/src/bitcoin-cli-res.rc @@ -0,0 +1,35 @@ +#include // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Zcash" + VALUE "FileDescription", "zcash-cli (JSON-RPC client for Zcash)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "zcash-cli" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." + VALUE "OriginalFilename", "zcash-cli.exe" + VALUE "ProductName", "zcash-cli" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/depend/zcash/src/bitcoin-cli.cpp b/depend/zcash/src/bitcoin-cli.cpp new file mode 100644 index 000000000..b78fb5461 --- /dev/null +++ b/depend/zcash/src/bitcoin-cli.cpp @@ -0,0 +1,436 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "chainparamsbase.h" +#include "clientversion.h" +#include "fs.h" +#include "rpc/client.h" +#include "rpc/protocol.h" +#include "util.h" +#include "utilstrencodings.h" + +#include + +#include +#include +#include "support/events.h" + +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif + +const std::function G_TRANSLATION_FUN = nullptr; + +static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; +static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; +static const int CONTINUE_EXECUTION=-1; + +std::string HelpMessageCli() +{ + std::string strUsage; + strUsage += HelpMessageGroup(_("Options:")); + strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); + strUsage += HelpMessageOpt("-datadir=", _("Specify data directory (this path cannot use '~')")); + strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). If first extra argument is `walletpassphrase` then the first line(password) will not be echoed.")); + AppendParamsHelpMessages(strUsage); + strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), DEFAULT_RPCCONNECT)); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 8232, 18232)); + strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); + strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcclienttimeout=", strprintf(_("Timeout in seconds during HTTP requests, or 0 for no timeout. (default: %d)"), DEFAULT_HTTP_CLIENT_TIMEOUT)); + + return strUsage; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Start +// + +// +// Exception thrown on connection error. This error is used to determine +// when to wait if -rpcwait is given. +// +class CConnectionFailed : public std::runtime_error +{ +public: + + explicit inline CConnectionFailed(const std::string& msg) : + std::runtime_error(msg) + {} + +}; + +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRPC(int argc, char* argv[]) +{ + static_assert(CONTINUE_EXECUTION != EXIT_FAILURE, + "CONTINUE_EXECUTION should be different from EXIT_FAILURE"); + static_assert(CONTINUE_EXECUTION != EXIT_SUCCESS, + "CONTINUE_EXECUTION should be different from EXIT_SUCCESS"); + // + // Parameters + // + ParseParameters(argc, argv); + if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { + std::string strUsage = _("Zcash RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo(); + if (!mapArgs.count("-version")) { + strUsage += "\n" + _("Usage:") + "\n" + + " zcash-cli [options] [params] " + _("Send command to Zcash") + "\n" + + " zcash-cli [options] help " + _("List commands") + "\n" + + " zcash-cli [options] help " + _("Get help for a command") + "\n"; + + strUsage += "\n" + HelpMessageCli(); + } else { + strUsage += LicenseInfo(); + } + + fprintf(stdout, "%s", strUsage.c_str()); + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + if (!fs::is_directory(GetDataDir(false))) { + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); + return EXIT_FAILURE; + } + try { + ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); + } catch (const std::exception& e) { + fprintf(stderr,"Error reading configuration file: %s\n", e.what()); + return EXIT_FAILURE; + } + // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) + try { + SelectBaseParams(ChainNameFromCommandLine()); + } catch(std::exception &e) { + fprintf(stderr, "Error: %s\n", e.what()); + return EXIT_FAILURE; + } + if (GetBoolArg("-rpcssl", false)) + { + fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); + return EXIT_FAILURE; + } + return CONTINUE_EXECUTION; +} + + +/** Reply structure for request_done to fill in */ +struct HTTPReply +{ + HTTPReply(): status(0), error(-1) {} + + int status; + int error; + std::string body; +}; + +const char *http_errorstring(int code) +{ + switch(code) { +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 + case EVREQ_HTTP_TIMEOUT: + return "timeout reached"; + case EVREQ_HTTP_EOF: + return "EOF reached"; + case EVREQ_HTTP_INVALID_HEADER: + return "error while reading header, or invalid header"; + case EVREQ_HTTP_BUFFER_ERROR: + return "error encountered while reading or writing"; + case EVREQ_HTTP_REQUEST_CANCEL: + return "request was canceled"; + case EVREQ_HTTP_DATA_TOO_LONG: + return "response body is larger than allowed"; +#endif + default: + return "unknown"; + } +} + +static void http_request_done(struct evhttp_request *req, void *ctx) +{ + HTTPReply *reply = static_cast(ctx); + + if (req == NULL) { + /* If req is NULL, it means an error occurred while connecting: the + * error code will have been passed to http_error_cb. + */ + reply->status = 0; + return; + } + + reply->status = evhttp_request_get_response_code(req); + + struct evbuffer *buf = evhttp_request_get_input_buffer(req); + if (buf) + { + size_t size = evbuffer_get_length(buf); + const char *data = (const char*)evbuffer_pullup(buf, size); + if (data) + reply->body = std::string(data, size); + evbuffer_drain(buf, size); + } +} + +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 +static void http_error_cb(enum evhttp_request_error err, void *ctx) +{ + HTTPReply *reply = static_cast(ctx); + reply->error = err; +} +#endif + +UniValue CallRPC(const std::string& strMethod, const UniValue& params) +{ + std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); + int port = GetArg("-rpcport", BaseParams().RPCPort()); + + // Obtain event base + raii_event_base base = obtain_event_base(); + + // Synchronously look up hostname + raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port); + evhttp_connection_set_timeout(evcon.get(), GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + + HTTPReply response; + raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response); + if (req == NULL) + throw std::runtime_error("create http request failed"); +#if LIBEVENT_VERSION_NUMBER >= 0x02010300 + evhttp_request_set_error_cb(req.get(), http_error_cb); +#endif + + // Get credentials + std::string strRPCUserColonPass; + if (mapArgs["-rpcpassword"] == "") { + // Try fall back to cookie-based authentication if no password is provided + if (!GetAuthCookie(&strRPCUserColonPass)) { + throw std::runtime_error(strprintf( + _("Could not locate RPC credentials. No authentication cookie could be found,\n" + "and no rpcpassword is set in the configuration file (%s)."), + GetConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)).string().c_str())); + + } + } else { + strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + } + + struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get()); + assert(output_headers); + evhttp_add_header(output_headers, "Host", host.c_str()); + evhttp_add_header(output_headers, "Connection", "close"); + evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); + + // Attach request data + std::string strRequest = JSONRPCRequest(strMethod, params, 1); + struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get()); + assert(output_buffer); + evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); + + int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, "/"); + req.release(); // ownership moved to evcon in above call + if (r != 0) { + throw CConnectionFailed("send http request failed"); + } + + event_base_dispatch(base.get()); + + if (response.status == 0) + throw CConnectionFailed(strprintf("couldn't connect to server: %s (code %d)\n(make sure server is running and you are connecting to the correct RPC port)", http_errorstring(response.error), response.error)); + else if (response.status == HTTP_UNAUTHORIZED) + throw std::runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + else if (response.status >= 400 && response.status != HTTP_BAD_REQUEST && response.status != HTTP_NOT_FOUND && response.status != HTTP_INTERNAL_SERVER_ERROR) + throw std::runtime_error(strprintf("server returned HTTP error %d", response.status)); + else if (response.body.empty()) + throw std::runtime_error("no response from server"); + + // Parse reply + UniValue valReply(UniValue::VSTR); + if (!valReply.read(response.body)) + throw std::runtime_error("couldn't parse reply from server"); + const UniValue& reply = valReply.get_obj(); + if (reply.empty()) + throw std::runtime_error("expected reply to have result, error and id properties"); + + return reply; +} + +bool SetStdinEcho(bool enable = true) +{ +#ifdef WIN32 + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return false; + DWORD mode; + // if it's not a terminal then stdin won't be echoed, so that's not an error + DWORD dwStdinType = GetFileType(hStdin) & ~FILE_TYPE_REMOTE; + bool could_be_terminal = dwStdinType == FILE_TYPE_CHAR || + (dwStdinType == FILE_TYPE_UNKNOWN && GetLastError() == NO_ERROR); + if (!could_be_terminal || GetConsoleMode(hStdin, &mode) == 0) return true; + + if (!enable) + mode &= ~ENABLE_ECHO_INPUT; + else + mode |= ENABLE_ECHO_INPUT; + + if (SetConsoleMode(hStdin, mode) == 0) return false; + +#else + struct termios tty; + if (tcgetattr(STDIN_FILENO, &tty) != 0) { + // if it's not a terminal then stdin won't be echoed, so that's not an error + return errno == ENOTTY; + } + if (!enable) + tty.c_lflag &= ~ECHO; + else + tty.c_lflag |= ECHO; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &tty) != 0) return false; +#endif + return true; +} + +int CommandLineRPC(int argc, char *argv[]) +{ + std::string strPrint; + int nRet = 0; + try { + // Skip switches + while (argc > 1 && IsSwitchChar(argv[1][0])) { + argc--; + argv++; + } + std::vector args = std::vector(&argv[1], &argv[argc]); + if (GetBoolArg("-stdin", false)) { + bool hide = false; + if (args.size() > 0 && args[0] == "walletpassphrase") { + if (!SetStdinEcho(false)) + throw std::runtime_error("unable to set terminal to non-echoing"); + hide = true; + } + + // Read one arg per line from stdin and append + std::string line; + while (std::getline(std::cin,line)) { + args.push_back(line); + if (hide) { + if (!SetStdinEcho(true)) + throw std::runtime_error("unable to set terminal back to echoing"); + hide = false; + } + } + } + if (args.size() < 1) + throw std::runtime_error("too few parameters (need at least command)"); + std::string strMethod = args[0]; + UniValue params = RPCConvertValues(strMethod, std::vector(args.begin()+1, args.end())); + + // Execute and handle connection failures with -rpcwait + const bool fWait = GetBoolArg("-rpcwait", false); + do { + try { + const UniValue reply = CallRPC(strMethod, params); + + // Parse reply + const UniValue& result = find_value(reply, "result"); + const UniValue& error = find_value(reply, "error"); + + if (!error.isNull()) { + // Error + int code = error["code"].get_int(); + if (fWait && code == RPC_IN_WARMUP) + throw CConnectionFailed("server in warmup"); + strPrint = "error: " + error.write(); + nRet = abs(code); + if (error.isObject()) + { + UniValue errCode = find_value(error, "code"); + UniValue errMsg = find_value(error, "message"); + strPrint = errCode.isNull() ? "" : "error code: "+errCode.getValStr()+"\n"; + + if (errMsg.isStr()) + strPrint += "error message:\n"+errMsg.get_str(); + } + } else { + // Result + if (result.isNull()) + strPrint = ""; + else if (result.isStr()) + strPrint = result.get_str(); + else + strPrint = result.write(2); + } + // Connection succeeded, no need to retry. + break; + } + catch (const CConnectionFailed&) { + if (fWait) + MilliSleep(1000); + else + throw; + } + } while (fWait); + } + catch (const std::exception& e) { + strPrint = std::string("error: ") + e.what(); + nRet = EXIT_FAILURE; + } + catch (...) { + PrintExceptionContinue(NULL, "CommandLineRPC()"); + throw; + } + + if (strPrint != "") { + fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + } + return nRet; +} + +int main(int argc, char* argv[]) +{ + SetupEnvironment(); + if (!SetupNetworking()) { + fprintf(stderr, "Error: Initializing networking failed\n"); + return EXIT_FAILURE; + } + + try { + int ret = AppInitRPC(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; + } + catch (const std::exception& e) { + PrintExceptionContinue(&e, "AppInitRPC()"); + return EXIT_FAILURE; + } catch (...) { + PrintExceptionContinue(NULL, "AppInitRPC()"); + return EXIT_FAILURE; + } + + int ret = EXIT_FAILURE; + try { + ret = CommandLineRPC(argc, argv); + } + catch (const std::exception& e) { + PrintExceptionContinue(&e, "CommandLineRPC()"); + } catch (...) { + PrintExceptionContinue(NULL, "CommandLineRPC()"); + } + return ret; +} diff --git a/depend/zcash/src/bitcoin-tx-res.rc b/depend/zcash/src/bitcoin-tx-res.rc new file mode 100644 index 000000000..028394e36 --- /dev/null +++ b/depend/zcash/src/bitcoin-tx-res.rc @@ -0,0 +1,35 @@ +#include // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Zcash" + VALUE "FileDescription", "zcash-tx (CLI Zcash transaction editor utility)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "zcash-tx" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." + VALUE "OriginalFilename", "zcash-tx.exe" + VALUE "ProductName", "zcash-tx" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/depend/zcash/src/bitcoin-tx.cpp b/depend/zcash/src/bitcoin-tx.cpp new file mode 100644 index 000000000..a15e2e1e9 --- /dev/null +++ b/depend/zcash/src/bitcoin-tx.cpp @@ -0,0 +1,712 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "clientversion.h" +#include "coins.h" +#include "consensus/consensus.h" +#include "consensus/upgrades.h" +#include "core_io.h" +#include "key_io.h" +#include "keystore.h" +#include "policy/policy.h" +#include "primitives/transaction.h" +#include "script/script.h" +#include "script/sign.h" +#include +#include "util.h" +#include "utilmoneystr.h" +#include "utilstrencodings.h" + +#include + +#include +#include + +static bool fCreateBlank; +static std::map registers; +static const int CONTINUE_EXECUTION=-1; + +const std::function G_TRANSLATION_FUN = nullptr; + +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRawTx(int argc, char* argv[]) +{ + // + // Parameters + // + ParseParameters(argc, argv); + + // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) + try { + SelectParams(ChainNameFromCommandLine()); + } catch(std::exception &e) { + fprintf(stderr, "Error: %s\n", e.what()); + return false; + } + + fCreateBlank = GetBoolArg("-create", false); + + if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help")) + { + // First part of help message is specific to this utility + std::string strUsage = _("Zcash zcash-tx utility version") + " " + FormatFullVersion() + "\n\n" + + _("Usage:") + "\n" + + " zcash-tx [options] [commands] " + _("Update hex-encoded zcash transaction") + "\n" + + " zcash-tx [options] -create [commands] " + _("Create hex-encoded zcash transaction") + "\n" + + "\n"; + + fprintf(stdout, "%s", strUsage.c_str()); + + strUsage = HelpMessageGroup(_("Options:")); + strUsage += HelpMessageOpt("-?", _("This help message")); + strUsage += HelpMessageOpt("-create", _("Create new, empty TX.")); + strUsage += HelpMessageOpt("-json", _("Select JSON output")); + strUsage += HelpMessageOpt("-txid", _("Output only the hex-encoded transaction id of the resultant transaction.")); + AppendParamsHelpMessages(strUsage); + + fprintf(stdout, "%s", strUsage.c_str()); + + strUsage = HelpMessageGroup(_("Commands:")); + strUsage += HelpMessageOpt("delin=N", _("Delete input N from TX")); + strUsage += HelpMessageOpt("delout=N", _("Delete output N from TX")); + strUsage += HelpMessageOpt("in=TXID:VOUT(:SEQUENCE_NUMBER)", _("Add input to TX")); + strUsage += HelpMessageOpt("locktime=N", _("Set TX lock time to N")); + strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N")); + strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX")); + strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX")); + strUsage += HelpMessageOpt("sign=HEIGHT:SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + + _("This command requires JSON registers:") + + _("prevtxs=JSON object") + ", " + + _("privatekeys=JSON object") + ". " + + _("See signrawtransaction docs for format of sighash flags, JSON objects.")); + fprintf(stdout, "%s", strUsage.c_str()); + + strUsage = HelpMessageGroup(_("Register Commands:")); + strUsage += HelpMessageOpt("load=NAME:FILENAME", _("Load JSON file FILENAME into register NAME")); + strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING")); + fprintf(stdout, "%s", strUsage.c_str()); + + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + return CONTINUE_EXECUTION; +} + +static void RegisterSetJson(const std::string& key, const std::string& rawJson) +{ + UniValue val; + if (!val.read(rawJson)) { + std::string strErr = "Cannot parse JSON for key " + key; + throw std::runtime_error(strErr); + } + + registers[key] = val; +} + +static void RegisterSet(const std::string& strInput) +{ + // separate NAME:VALUE in string + size_t pos = strInput.find(':'); + if ((pos == std::string::npos) || + (pos == 0) || + (pos == (strInput.size() - 1))) + throw std::runtime_error("Register input requires NAME:VALUE"); + + std::string key = strInput.substr(0, pos); + std::string valStr = strInput.substr(pos + 1, std::string::npos); + + RegisterSetJson(key, valStr); +} + +static void RegisterLoad(const std::string& strInput) +{ + // separate NAME:FILENAME in string + size_t pos = strInput.find(':'); + if ((pos == std::string::npos) || + (pos == 0) || + (pos == (strInput.size() - 1))) + throw std::runtime_error("Register load requires NAME:FILENAME"); + + std::string key = strInput.substr(0, pos); + std::string filename = strInput.substr(pos + 1, std::string::npos); + + FILE *f = fopen(filename.c_str(), "r"); + if (!f) { + std::string strErr = "Cannot open file " + filename; + throw std::runtime_error(strErr); + } + + // load file chunks into one big buffer + std::string valStr; + while ((!feof(f)) && (!ferror(f))) { + char buf[4096]; + int bread = fread(buf, 1, sizeof(buf), f); + if (bread <= 0) + break; + + valStr.insert(valStr.size(), buf, bread); + } + + int error = ferror(f); + fclose(f); + + if (error) { + std::string strErr = "Error reading file " + filename; + throw std::runtime_error(strErr); + } + + // evaluate as JSON buffer register + RegisterSetJson(key, valStr); +} + +static void MutateTxVersion(CMutableTransaction& tx, const std::string& cmdVal) +{ + int64_t newVersion = atoi64(cmdVal); + if (newVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION || newVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION) + throw std::runtime_error("Invalid TX version requested"); + + tx.nVersion = (int) newVersion; +} + +static void MutateTxExpiry(CMutableTransaction& tx, const std::string& cmdVal) +{ + int64_t newExpiry = atoi64(cmdVal); + if (newExpiry <= 0 || newExpiry >= TX_EXPIRY_HEIGHT_THRESHOLD) { + throw std::runtime_error("Invalid TX expiry requested"); + } + tx.nExpiryHeight = (int) newExpiry; +} + +static void MutateTxLocktime(CMutableTransaction& tx, const std::string& cmdVal) +{ + int64_t newLocktime = atoi64(cmdVal); + if (newLocktime < 0LL || newLocktime > 0xffffffffLL) + throw std::runtime_error("Invalid TX locktime requested"); + + tx.nLockTime = (unsigned int) newLocktime; +} + +static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInput) +{ + std::vector vStrInputParts; + boost::split(vStrInputParts, strInput, boost::is_any_of(":")); + + // separate TXID:VOUT in string + if (vStrInputParts.size()<2) + throw std::runtime_error("TX input missing separator"); + + // extract and validate TXID + std::string strTxid = vStrInputParts[0]; + if ((strTxid.size() != 64) || !IsHex(strTxid)) + throw std::runtime_error("invalid TX input txid"); + uint256 txid(uint256S(strTxid)); + + static const unsigned int minTxOutSz = 9; + static const unsigned int maxVout = MAX_BLOCK_SIZE / minTxOutSz; + + // extract and validate vout + std::string strVout = vStrInputParts[1]; + int vout = atoi(strVout); + if ((vout < 0) || (vout > (int)maxVout)) + throw std::runtime_error("invalid TX input vout"); + + // extract the optional sequence number + uint32_t nSequenceIn=std::numeric_limits::max(); + if (vStrInputParts.size() > 2) + nSequenceIn = atoi(vStrInputParts[2]); + + // append to transaction input list + CTxIn txin(txid, vout, CScript(), nSequenceIn); + tx.vin.push_back(txin); +} + +static void MutateTxAddOutAddr(CMutableTransaction& tx, const std::string& strInput) +{ + // separate VALUE:ADDRESS in string + size_t pos = strInput.find(':'); + if ((pos == std::string::npos) || + (pos == 0) || + (pos == (strInput.size() - 1))) + throw std::runtime_error("TX output missing separator"); + + // extract and validate VALUE + std::string strValue = strInput.substr(0, pos); + CAmount value; + if (!ParseMoney(strValue, value)) + throw std::runtime_error("invalid TX output value"); + + KeyIO keyIO(Params()); + + // extract and validate ADDRESS + std::string strAddr = strInput.substr(pos + 1, std::string::npos); + CTxDestination destination = keyIO.DecodeDestination(strAddr); + if (!IsValidDestination(destination)) { + throw std::runtime_error("invalid TX output address"); + } + CScript scriptPubKey = GetScriptForDestination(destination); + + // construct TxOut, append to transaction output list + CTxOut txout(value, scriptPubKey); + tx.vout.push_back(txout); +} + +static void MutateTxAddOutScript(CMutableTransaction& tx, const std::string& strInput) +{ + // separate VALUE:SCRIPT in string + size_t pos = strInput.find(':'); + if ((pos == std::string::npos) || + (pos == 0)) + throw std::runtime_error("TX output missing separator"); + + // extract and validate VALUE + std::string strValue = strInput.substr(0, pos); + CAmount value; + if (!ParseMoney(strValue, value)) + throw std::runtime_error("invalid TX output value"); + + // extract and validate script + std::string strScript = strInput.substr(pos + 1, std::string::npos); + CScript scriptPubKey = ParseScript(strScript); // throws on err + + // construct TxOut, append to transaction output list + CTxOut txout(value, scriptPubKey); + tx.vout.push_back(txout); +} + +static void MutateTxDelInput(CMutableTransaction& tx, const std::string& strInIdx) +{ + // parse requested deletion index + int inIdx = atoi(strInIdx); + if (inIdx < 0 || inIdx >= (int)tx.vin.size()) { + std::string strErr = "Invalid TX input index '" + strInIdx + "'"; + throw std::runtime_error(strErr.c_str()); + } + + // delete input from transaction + tx.vin.erase(tx.vin.begin() + inIdx); +} + +static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOutIdx) +{ + // parse requested deletion index + int outIdx = atoi(strOutIdx); + if (outIdx < 0 || outIdx >= (int)tx.vout.size()) { + std::string strErr = "Invalid TX output index '" + strOutIdx + "'"; + throw std::runtime_error(strErr.c_str()); + } + + // delete output from transaction + tx.vout.erase(tx.vout.begin() + outIdx); +} + +static const unsigned int N_SIGHASH_OPTS = 6; +static const struct { + const char *flagStr; + int flags; +} sighashOptions[N_SIGHASH_OPTS] = { + {"ALL", SIGHASH_ALL}, + {"NONE", SIGHASH_NONE}, + {"SINGLE", SIGHASH_SINGLE}, + {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY}, + {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY}, + {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY}, +}; + +static bool findSighashFlags(int& flags, const std::string& flagStr) +{ + flags = 0; + + for (unsigned int i = 0; i < N_SIGHASH_OPTS; i++) { + if (flagStr == sighashOptions[i].flagStr) { + flags = sighashOptions[i].flags; + return true; + } + } + + return false; +} + +uint256 ParseHashUO(std::map& o, std::string strKey) +{ + if (!o.count(strKey)) + return uint256(); + return ParseHashUV(o[strKey], strKey); +} + +std::vector ParseHexUO(std::map& o, std::string strKey) +{ + if (!o.count(strKey)) { + std::vector emptyVec; + return emptyVec; + } + return ParseHexUV(o[strKey], strKey); +} + +static CAmount AmountFromValue(const UniValue& value) +{ + if (!value.isNum() && !value.isStr()) + throw std::runtime_error("Amount is not a number or string"); + CAmount amount; + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) + throw std::runtime_error("Invalid amount"); + if (!MoneyRange(amount)) + throw std::runtime_error("Amount out of range"); + return amount; +} + +static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput) +{ + // separate HEIGHT:SIGHASH-FLAGS in string + size_t pos = strInput.find(':'); + if ((pos == 0) || + (pos == (strInput.size() - 1))) + throw std::runtime_error("Invalid sighash flag separator"); + + // extract and validate HEIGHT + std::string strHeight = strInput.substr(0, pos); + int nHeight = atoi(strHeight); + if (nHeight <= 0) { + throw std::runtime_error("invalid height"); + } + + // extract and validate SIGHASH-FLAGS + int nHashType = SIGHASH_ALL; + std::string flagStr; + if (pos != std::string::npos) { + flagStr = strInput.substr(pos + 1, std::string::npos); + } + if (flagStr.size() > 0) + if (!findSighashFlags(nHashType, flagStr)) + throw std::runtime_error("unknown sighash flag/sign option"); + + std::vector txVariants; + txVariants.push_back(tx); + + // mergedTx will end up with all the signatures; it + // starts as a clone of the raw tx: + CMutableTransaction mergedTx(txVariants[0]); + bool fComplete = true; + CCoinsView viewDummy; + CCoinsViewCache view(&viewDummy); + + if (!registers.count("privatekeys")) + throw std::runtime_error("privatekeys register variable must be set."); + bool fGivenKeys = false; + CBasicKeyStore tempKeystore; + UniValue keysObj = registers["privatekeys"]; + fGivenKeys = true; + + KeyIO keyIO(Params()); + + for (size_t kidx = 0; kidx < keysObj.size(); kidx++) { + if (!keysObj[kidx].isStr()) + throw std::runtime_error("privatekey not a std::string"); + CKey key = keyIO.DecodeSecret(keysObj[kidx].getValStr()); + if (!key.IsValid()) { + throw std::runtime_error("privatekey not valid"); + } + tempKeystore.AddKey(key); + } + + // Add previous txouts given in the RPC call: + if (!registers.count("prevtxs")) + throw std::runtime_error("prevtxs register variable must be set."); + UniValue prevtxsObj = registers["prevtxs"]; + { + for (size_t previdx = 0; previdx < prevtxsObj.size(); previdx++) { + UniValue prevOut = prevtxsObj[previdx]; + if (!prevOut.isObject()) + throw std::runtime_error("expected prevtxs internal object"); + + std::map types = boost::assign::map_list_of("txid", UniValue::VSTR)("vout",UniValue::VNUM)("scriptPubKey",UniValue::VSTR); + if (!prevOut.checkObject(types)) + throw std::runtime_error("prevtxs internal object typecheck fail"); + + uint256 txid = ParseHashUV(prevOut["txid"], "txid"); + + int nOut = atoi(prevOut["vout"].getValStr()); + if (nOut < 0) + throw std::runtime_error("vout must be positive"); + + std::vector pkData(ParseHexUV(prevOut["scriptPubKey"], "scriptPubKey")); + CScript scriptPubKey(pkData.begin(), pkData.end()); + + { + CCoinsModifier coins = view.ModifyCoins(txid); + if (coins->IsAvailable(nOut) && coins->vout[nOut].scriptPubKey != scriptPubKey) { + std::string err("Previous output scriptPubKey mismatch:\n"); + err = err + ScriptToAsmStr(coins->vout[nOut].scriptPubKey) + "\nvs:\n"+ + ScriptToAsmStr(scriptPubKey); + throw std::runtime_error(err); + } + if ((unsigned int)nOut >= coins->vout.size()) + coins->vout.resize(nOut+1); + coins->vout[nOut].scriptPubKey = scriptPubKey; + coins->vout[nOut].nValue = 0; + if (prevOut.exists("amount")) { + coins->vout[nOut].nValue = AmountFromValue(prevOut["amount"]); + } + } + + // if redeemScript given and private keys given, + // add redeemScript to the tempKeystore so it can be signed: + if (fGivenKeys && scriptPubKey.IsPayToScriptHash() && + prevOut.exists("redeemScript")) { + UniValue v = prevOut["redeemScript"]; + std::vector rsData(ParseHexUV(v, "redeemScript")); + CScript redeemScript(rsData.begin(), rsData.end()); + tempKeystore.AddCScript(redeemScript); + } + } + } + + const CKeyStore& keystore = tempKeystore; + // We don't support v5 transactions via this API yet. + if (mergedTx.nVersion >= ZIP225_TX_VERSION) { + throw std::runtime_error("v5+ transactions not supported yet"); + } + const PrecomputedTransactionData txdata(mergedTx, {}); + + bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); + + // Grab the consensus branch ID for the given height + auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus()); + + // Sign what we can: + for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { + CTxIn& txin = mergedTx.vin[i]; + const CCoins* coins = view.AccessCoins(txin.prevout.hash); + if (!coins || !coins->IsAvailable(txin.prevout.n)) { + fComplete = false; + continue; + } + const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; + + SignatureData sigdata; + // Only sign SIGHASH_SINGLE if there's a corresponding output: + if (!fHashSingle || (i < mergedTx.vout.size())) + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, txdata, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); + + // ... and merge in other signatures: + for (const CTransaction& txv : txVariants) + sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, txdata, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); + UpdateTransaction(mergedTx, i, sigdata); + + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, txdata, i, amount), consensusBranchId)) + fComplete = false; + } + + if (fComplete) { + // do nothing... for now + // perhaps store this for later optional JSON output + } + + tx = mergedTx; +} + +class Secp256k1Init +{ + ECCVerifyHandle globalVerifyHandle; + +public: + Secp256k1Init() { + ECC_Start(); + } + ~Secp256k1Init() { + ECC_Stop(); + } +}; + +static void MutateTx(CMutableTransaction& tx, const std::string& command, + const std::string& commandVal) +{ + boost::scoped_ptr ecc; + + if (command == "nversion") + MutateTxVersion(tx, commandVal); + else if (command == "locktime") + MutateTxLocktime(tx, commandVal); + else if (command == "expiry") + MutateTxExpiry(tx, commandVal); + + else if (command == "delin") + MutateTxDelInput(tx, commandVal); + else if (command == "in") + MutateTxAddInput(tx, commandVal); + + else if (command == "delout") + MutateTxDelOutput(tx, commandVal); + else if (command == "outaddr") + MutateTxAddOutAddr(tx, commandVal); + else if (command == "outscript") + MutateTxAddOutScript(tx, commandVal); + + else if (command == "sign") { + if (!ecc) { ecc.reset(new Secp256k1Init()); } + MutateTxSign(tx, commandVal); + } + + else if (command == "load") + RegisterLoad(commandVal); + + else if (command == "set") + RegisterSet(commandVal); + + else + throw std::runtime_error("unknown command"); +} + +static void OutputTxJSON(const CTransaction& tx) +{ + UniValue entry(UniValue::VOBJ); + TxToUniv(tx, uint256(), entry); + + std::string jsonOutput = entry.write(4); + fprintf(stdout, "%s\n", jsonOutput.c_str()); +} + +static void OutputTxHash(const CTransaction& tx) +{ + std::string strHexHash = tx.GetHash().GetHex(); // the hex-encoded transaction hash (aka the transaction id) + + fprintf(stdout, "%s\n", strHexHash.c_str()); +} + +static void OutputTxHex(const CTransaction& tx) +{ + std::string strHex = EncodeHexTx(tx); + + fprintf(stdout, "%s\n", strHex.c_str()); +} + +static void OutputTx(const CTransaction& tx) +{ + if (GetBoolArg("-json", false)) + OutputTxJSON(tx); + else if (GetBoolArg("-txid", false)) + OutputTxHash(tx); + else + OutputTxHex(tx); +} + +static std::string readStdin() +{ + char buf[4096]; + std::string ret; + + while (!feof(stdin)) { + size_t bread = fread(buf, 1, sizeof(buf), stdin); + ret.append(buf, bread); + if (bread < sizeof(buf)) + break; + } + + if (ferror(stdin)) + throw std::runtime_error("error reading stdin"); + + boost::algorithm::trim_right(ret); + + return ret; +} + +static int CommandLineRawTx(int argc, char* argv[]) +{ + std::string strPrint; + int nRet = 0; + try { + // Skip switches; Permit common stdin convention "-" + while (argc > 1 && IsSwitchChar(argv[1][0]) && + (argv[1][1] != 0)) { + argc--; + argv++; + } + + CTransaction txDecodeTmp; + int startArg; + + if (!fCreateBlank) { + // require at least one param + if (argc < 2) + throw std::runtime_error("too few parameters"); + + // param: hex-encoded bitcoin transaction + std::string strHexTx(argv[1]); + if (strHexTx == "-") // "-" implies standard input + strHexTx = readStdin(); + + if (!DecodeHexTx(txDecodeTmp, strHexTx)) + throw std::runtime_error("invalid transaction encoding"); + + startArg = 2; + } else + startArg = 1; + + CMutableTransaction tx(txDecodeTmp); + + for (int i = startArg; i < argc; i++) { + std::string arg = argv[i]; + std::string key, value; + size_t eqpos = arg.find('='); + if (eqpos == std::string::npos) + key = arg; + else { + key = arg.substr(0, eqpos); + value = arg.substr(eqpos + 1); + } + + MutateTx(tx, key, value); + } + + OutputTx(tx); + } + catch (const std::exception& e) { + strPrint = std::string("error: ") + e.what(); + nRet = EXIT_FAILURE; + } + catch (...) { + PrintExceptionContinue(NULL, "CommandLineRawTx()"); + throw; + } + + if (strPrint != "") { + fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); + } + return nRet; +} + +int main(int argc, char* argv[]) +{ + SetupEnvironment(); + + try { + int ret = AppInitRawTx(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; + } + catch (const std::exception& e) { + PrintExceptionContinue(&e, "AppInitRawTx()"); + return EXIT_FAILURE; + } catch (...) { + PrintExceptionContinue(NULL, "AppInitRawTx()"); + return EXIT_FAILURE; + } + + int ret = EXIT_FAILURE; + try { + ret = CommandLineRawTx(argc, argv); + } + catch (const std::exception& e) { + PrintExceptionContinue(&e, "CommandLineRawTx()"); + } catch (...) { + PrintExceptionContinue(NULL, "CommandLineRawTx()"); + } + return ret; +} diff --git a/depend/zcash/src/bitcoind-res.rc b/depend/zcash/src/bitcoind-res.rc new file mode 100644 index 000000000..de544f10f --- /dev/null +++ b/depend/zcash/src/bitcoind-res.rc @@ -0,0 +1,35 @@ +#include // needed for VERSIONINFO +#include "clientversion.h" // holds the needed client version information + +#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD +#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD) +#define VER_FILEVERSION VER_PRODUCTVERSION +#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" // U.S. English - multilingual (hex) + BEGIN + VALUE "CompanyName", "Zcash" + VALUE "FileDescription", "zcashd (Zcash node with a JSON-RPC server)" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "zcashd" + VALUE "LegalCopyright", COPYRIGHT_STR + VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or https://www.opensource.org/licenses/mit-license.php ." + VALUE "OriginalFilename", "zcashd.exe" + VALUE "ProductName", "zcashd" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal) + END +END diff --git a/depend/zcash/src/bitcoind.cpp b/depend/zcash/src/bitcoind.cpp new file mode 100644 index 000000000..f62a4270b --- /dev/null +++ b/depend/zcash/src/bitcoind.cpp @@ -0,0 +1,224 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "clientversion.h" +#include "deprecation.h" +#include "fs.h" +#include "rpc/server.h" +#include "init.h" +#include "main.h" +#include "noui.h" +#include "scheduler.h" +#include "util.h" +#include "httpserver.h" +#include "httprpc.h" + +#include +#include + +#include + +const std::function G_TRANSLATION_FUN = nullptr; + +/* Introduction text for doxygen: */ + +/*! \mainpage Developer documentation + * + * \section intro_sec Introduction + * + * This is the developer documentation of the reference client for an experimental new digital currency called Bitcoin (https://www.bitcoin.org/), + * which enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate + * with no central authority: managing transactions and issuing money are carried out collectively by the network. + * + * The software is a community-driven open source project, released under the MIT license. + * + * \section Navigation + * Use the buttons Namespaces, Classes or Files at the top of the page to start navigating the code. + */ + +static bool fDaemon; + +void WaitForShutdown(boost::thread_group* threadGroup) +{ + bool fShutdown = ShutdownRequested(); + // Tell the main threads to shutdown. + while (!fShutdown) + { + MilliSleep(200); + fShutdown = ShutdownRequested(); + } + if (threadGroup) + { + Interrupt(*threadGroup); + threadGroup->join_all(); + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// Start +// +bool AppInit(int argc, char* argv[]) +{ + boost::thread_group threadGroup; + CScheduler scheduler; + + bool fRet = false; + + // + // Parameters + // + ParseParameters(argc, argv); + + // Process help and version before taking care about datadir + if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) + { + std::string strUsage = _("Zcash Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n" + PrivacyInfo(); + + if (mapArgs.count("-version")) + { + strUsage += LicenseInfo(); + } + else + { + strUsage += "\n" + _("Usage:") + "\n" + + " zcashd [options] " + _("Start Zcash Daemon") + "\n"; + + strUsage += "\n" + HelpMessage(HMM_BITCOIND); + } + + fprintf(stdout, "%s", strUsage.c_str()); + return true; + } + + // Handle setting of allowed-deprecated features as early as possible + // so that it's possible for other initialization steps to respect them. + auto deprecationError = SetAllowedDeprecatedFeaturesFromCLIArgs(); + if (deprecationError.has_value()) { + fprintf(stderr, "%s", deprecationError.value().c_str()); + return false; + } + + try + { + if (!fs::is_directory(GetDataDir(false))) + { + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); + return false; + } + try + { + ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); + } catch (const missing_zcash_conf& e) { + auto confFilename = GetArg("-conf", BITCOIN_CONF_FILENAME); + fprintf(stderr, + (_("Before starting zcashd, you need to create a configuration file:\n" + "%s\n" + "It can be completely empty! That indicates you are happy with the default\n" + "configuration of zcashd. But requiring a configuration file to start ensures\n" + "that zcashd won't accidentally compromise your privacy if there was a default\n" + "option you needed to change.\n" + "\n" + "You can look at the example configuration file for suggestions of default\n" + "options that you may want to change. It should be in one of these locations,\n" + "depending on how you installed Zcash:\n") + + _("- Source code: %s%s\n" + "- .deb package: %s%s\n")).c_str(), + GetConfigFile(confFilename).string().c_str(), + "contrib/debian/examples/", confFilename.c_str(), + "/usr/share/doc/zcash/examples/", confFilename.c_str()); + return false; + } catch (const std::exception& e) { + fprintf(stderr,"Error reading configuration file: %s\n", e.what()); + return false; + } + // Check for -testnet or -regtest parameter (Params() calls are only valid after this clause) + try { + SelectParams(ChainNameFromCommandLine()); + } catch(std::exception &e) { + fprintf(stderr, "Error: %s\n", e.what()); + return false; + } + + // Command-line RPC + bool fCommandLine = false; + for (int i = 1; i < argc; i++) + if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "zcash:")) + fCommandLine = true; + + if (fCommandLine) + { + fprintf(stderr, "Error: There is no RPC client functionality in zcashd. Use the zcash-cli utility instead.\n"); + exit(EXIT_FAILURE); + } +#ifndef WIN32 + fDaemon = GetBoolArg("-daemon", false); + if (fDaemon) + { + fprintf(stdout, "Zcash server starting\n"); + + // Daemonize + pid_t pid = fork(); + if (pid < 0) + { + fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); + return false; + } + if (pid > 0) // Parent process, pid is child process id + { + return true; + } + // Child process falls through to rest of initialization + + pid_t sid = setsid(); + if (sid < 0) + fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); + } +#endif + SoftSetBoolArg("-server", true); + + // Set this early so that parameter interactions go to console + InitLogging(); + + // Now that we have logging set up, start the initialization span. + auto span = TracingSpan("info", "main", "Init"); + auto spanGuard = span.Enter(); + + InitParameterInteraction(); + fRet = AppInit2(threadGroup, scheduler); + } + catch (const std::exception& e) { + PrintExceptionContinue(&e, "AppInit()"); + } catch (...) { + PrintExceptionContinue(NULL, "AppInit()"); + } + + if (!fRet) + { + Interrupt(threadGroup); + // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of + // the startup-failure cases to make sure they don't result in a hang due to some + // thread-blocking-waiting-for-another-thread-during-startup case + } else { + WaitForShutdown(&threadGroup); + } + Shutdown(); + + return fRet; +} +#ifdef ZCASH_FUZZ +#warning BUILDING A FUZZER, NOT THE REAL MAIN +#include "fuzz.cpp" +#else +int main(int argc, char* argv[]) +{ + SetupEnvironment(); + + // Connect bitcoind signal handlers + noui_connect(); + + return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); +} +#endif diff --git a/depend/zcash/src/bloom.cpp b/depend/zcash/src/bloom.cpp new file mode 100644 index 000000000..b95420075 --- /dev/null +++ b/depend/zcash/src/bloom.cpp @@ -0,0 +1,276 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "bloom.h" + +#include "primitives/transaction.h" +#include "hash.h" +#include "script/script.h" +#include "script/standard.h" +#include "random.h" +#include "streams.h" + +#include +#include + +#include + +#define LN2SQUARED 0.4804530139182014246671025263266649717305529515945455 +#define LN2 0.6931471805599453094172321214581765680755001343602552 + +CBloomFilter::CBloomFilter(const unsigned int nElements, const double nFPRate, const unsigned int nTweakIn, unsigned char nFlagsIn) : + /** + * The ideal size for a bloom filter with a given number of elements and false positive rate is: + * - nElements * log(fp rate) / ln(2)^2 + * We ignore filter parameters which will create a bloom filter larger than the protocol limits + */ + vData(std::min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8), + /** + * The ideal number of hash functions is filter size * ln(2) / number of elements + * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits + * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas + */ + nHashFuncs(std::min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), + nTweak(nTweakIn), + nFlags(nFlagsIn) +{ +} + +inline unsigned int CBloomFilter::Hash(unsigned int nHashNum, const std::vector& vDataToHash) const +{ + // 0xFBA4C795 chosen as it guarantees a reasonable bit difference between nHashNum values. + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash) % (vData.size() * 8); +} + +void CBloomFilter::insert(const std::vector& vKey) +{ + if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700) + return; + for (unsigned int i = 0; i < nHashFuncs; i++) + { + unsigned int nIndex = Hash(i, vKey); + // Sets bit nIndex of vData + vData[nIndex >> 3] |= (1 << (7 & nIndex)); + } +} + +void CBloomFilter::insert(const COutPoint& outpoint) +{ + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << outpoint; + std::vector data(stream.begin(), stream.end()); + insert(data); +} + +void CBloomFilter::insert(const uint256& hash) +{ + std::vector data(hash.begin(), hash.end()); + insert(data); +} + +bool CBloomFilter::contains(const std::vector& vKey) const +{ + if (vData.empty()) // Avoid divide-by-zero (CVE-2013-5700) + return true; + for (unsigned int i = 0; i < nHashFuncs; i++) + { + unsigned int nIndex = Hash(i, vKey); + // Checks bit nIndex of vData + if (!(vData[nIndex >> 3] & (1 << (7 & nIndex)))) + return false; + } + return true; +} + +bool CBloomFilter::contains(const COutPoint& outpoint) const +{ + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << outpoint; + std::vector data(stream.begin(), stream.end()); + return contains(data); +} + +bool CBloomFilter::contains(const uint256& hash) const +{ + std::vector data(hash.begin(), hash.end()); + return contains(data); +} + +bool CBloomFilter::IsWithinSizeConstraints() const +{ + return vData.size() <= MAX_BLOOM_FILTER_SIZE && nHashFuncs <= MAX_HASH_FUNCS; +} + +bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx) +{ + bool fFound = false; + // Match if the filter contains the hash of tx + // for finding tx when they appear in a block + if (vData.empty()) // zero-size = "match-all" filter + return true; + const uint256& hash = tx.GetHash(); + if (contains(hash)) + fFound = true; + + for (unsigned int i = 0; i < tx.vout.size(); i++) + { + const CTxOut& txout = tx.vout[i]; + // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx + // If this matches, also add the specific output that was matched. + // This means clients don't have to update the filter themselves when a new relevant tx + // is discovered in order to find spending transactions, which avoids round-tripping and race conditions. + CScript::const_iterator pc = txout.scriptPubKey.begin(); + std::vector data; + while (pc < txout.scriptPubKey.end()) + { + opcodetype opcode; + if (!txout.scriptPubKey.GetOp(pc, opcode, data)) + break; + if (data.size() != 0 && contains(data)) + { + fFound = true; + if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_ALL) + insert(COutPoint(hash, i)); + else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY) + { + txnouttype type; + std::vector > vSolutions; + if (Solver(txout.scriptPubKey, type, vSolutions) && + (type == TX_PUBKEY || type == TX_MULTISIG)) + insert(COutPoint(hash, i)); + } + break; + } + } + } + + if (fFound) + return true; + + for (const CTxIn& txin : tx.vin) + { + // Match if the filter contains an outpoint tx spends + if (contains(txin.prevout)) + return true; + + // Match if the filter contains any arbitrary script data element in any scriptSig in tx + CScript::const_iterator pc = txin.scriptSig.begin(); + std::vector data; + while (pc < txin.scriptSig.end()) + { + opcodetype opcode; + if (!txin.scriptSig.GetOp(pc, opcode, data)) + break; + if (data.size() != 0 && contains(data)) + return true; + } + } + + return false; +} + +CRollingBloomFilter::CRollingBloomFilter(const unsigned int nElements, const double fpRate) +{ + double logFpRate = log(fpRate); + /* The optimal number of hash functions is log(fpRate) / log(0.5), but + * restrict it to the range 1-50. */ + nHashFuncs = std::max(1, std::min((int)round(logFpRate / log(0.5)), 50)); + /* In this rolling bloom filter, we'll store between 2 and 3 generations of nElements / 2 entries. */ + nEntriesPerGeneration = (nElements + 1) / 2; + uint32_t nMaxElements = nEntriesPerGeneration * 3; + /* The maximum fpRate = pow(1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits), nHashFuncs) + * => pow(fpRate, 1.0 / nHashFuncs) = 1.0 - exp(-nHashFuncs * nMaxElements / nFilterBits) + * => 1.0 - pow(fpRate, 1.0 / nHashFuncs) = exp(-nHashFuncs * nMaxElements / nFilterBits) + * => log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) = -nHashFuncs * nMaxElements / nFilterBits + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - pow(fpRate, 1.0 / nHashFuncs)) + * => nFilterBits = -nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs)) + */ + uint32_t nFilterBits = (uint32_t)ceil(-1.0 * nHashFuncs * nMaxElements / log(1.0 - exp(logFpRate / nHashFuncs))); + data.clear(); + /* For each data element we need to store 2 bits. If both bits are 0, the + * bit is treated as unset. If the bits are (01), (10), or (11), the bit is + * treated as set in generation 1, 2, or 3 respectively. + * These bits are stored in separate integers: position P corresponds to bit + * (P & 63) of the integers data[(P >> 6) * 2] and data[(P >> 6) * 2 + 1]. */ + data.resize(((nFilterBits + 63) / 64) << 1); + reset(); +} + +/* Similar to CBloomFilter::Hash */ +static inline uint32_t RollingBloomHash(unsigned int nHashNum, uint32_t nTweak, const std::vector& vDataToHash) { + return MurmurHash3(nHashNum * 0xFBA4C795 + nTweak, vDataToHash); +} + + +// A replacement for x % n. This assumes that x and n are 32bit integers, and x is a uniformly random distributed 32bit value +// which should be the case for a good hash. +// See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ +static inline uint32_t FastMod(uint32_t x, size_t n) { + return ((uint64_t)x * (uint64_t)n) >> 32; +} + +void CRollingBloomFilter::insert(const std::vector& vKey) +{ + if (nEntriesThisGeneration == nEntriesPerGeneration) { + nEntriesThisGeneration = 0; + nGeneration++; + if (nGeneration == 4) { + nGeneration = 1; + } + uint64_t nGenerationMask1 = 0 - (uint64_t)(nGeneration & 1); + uint64_t nGenerationMask2 = 0 - (uint64_t)(nGeneration >> 1); + /* Wipe old entries that used this generation number. */ + for (uint32_t p = 0; p < data.size(); p += 2) { + uint64_t p1 = data[p], p2 = data[p + 1]; + uint64_t mask = (p1 ^ nGenerationMask1) | (p2 ^ nGenerationMask2); + data[p] = p1 & mask; + data[p + 1] = p2 & mask; + } + } + nEntriesThisGeneration++; + + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = RollingBloomHash(n, nTweak, vKey); + int bit = h & 0x3F; + /* FastMod works with the upper bits of h, so it is safe to ignore that the lower bits of h are already used for bit. */ + uint32_t pos = FastMod(h, data.size()); + /* The lowest bit of pos is ignored, and set to zero for the first bit, and to one for the second. */ + data[pos & ~1] = (data[pos & ~1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration & 1)) << bit; + data[pos | 1] = (data[pos | 1] & ~(((uint64_t)1) << bit)) | ((uint64_t)(nGeneration >> 1)) << bit; + } +} + +void CRollingBloomFilter::insert(const uint256& hash) +{ + std::vector vData(hash.begin(), hash.end()); + insert(vData); +} + +bool CRollingBloomFilter::contains(const std::vector& vKey) const +{ + for (int n = 0; n < nHashFuncs; n++) { + uint32_t h = RollingBloomHash(n, nTweak, vKey); + int bit = h & 0x3F; + uint32_t pos = FastMod(h, data.size()); + /* If the relevant bit is not set in either data[pos & ~1] or data[pos | 1], the filter does not contain vKey */ + if (!(((data[pos & ~1] | data[pos | 1]) >> bit) & 1)) { + return false; + } + } + return true; +} + +bool CRollingBloomFilter::contains(const uint256& hash) const +{ + std::vector vData(hash.begin(), hash.end()); + return contains(vData); +} + +void CRollingBloomFilter::reset() +{ + nTweak = GetRand(std::numeric_limits::max()); + nEntriesThisGeneration = 0; + nGeneration = 1; + std::fill(data.begin(), data.end(), 0); +} diff --git a/depend/zcash/src/bloom.h b/depend/zcash/src/bloom.h new file mode 100644 index 000000000..e4c01fe49 --- /dev/null +++ b/depend/zcash/src/bloom.h @@ -0,0 +1,142 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_BLOOM_H +#define BITCOIN_BLOOM_H + +#include "serialize.h" + +#include + +class COutPoint; +class CTransaction; +class uint256; + +//! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% +static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes +static const unsigned int MAX_HASH_FUNCS = 50; + +/** + * First two bits of nFlags control how much IsRelevantAndUpdate actually updates + * The remaining bits are reserved + */ +enum bloomflags +{ + BLOOM_UPDATE_NONE = 0, + BLOOM_UPDATE_ALL = 1, + // Only adds outpoints to the filter if the output is a pay-to-pubkey/pay-to-multisig script + BLOOM_UPDATE_P2PUBKEY_ONLY = 2, + BLOOM_UPDATE_MASK = 3, +}; + +/** + * BloomFilter is a probabilistic filter which SPV clients provide + * so that we can filter the transactions we send them. + * + * This allows for significantly more efficient transaction and block downloads. + * + * Because bloom filters are probabilistic, a SPV node can increase the false- + * positive rate, making us send it transactions which aren't actually its, + * allowing clients to trade more bandwidth for more privacy by obfuscating which + * keys are controlled by them. + */ +class CBloomFilter +{ +private: + std::vector vData; + unsigned int nHashFuncs; + unsigned int nTweak; + unsigned char nFlags; + + unsigned int Hash(unsigned int nHashNum, const std::vector& vDataToHash) const; + +public: + /** + * Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements + * Note that if the given parameters will result in a filter outside the bounds of the protocol limits, + * the filter created will be as close to the given parameters as possible within the protocol limits. + * This will apply if nFPRate is very low or nElements is unreasonably high. + * nTweak is a constant which is added to the seed value passed to the hash function + * It should generally always be a random value (and is largely only exposed for unit testing) + * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) + */ + CBloomFilter(const unsigned int nElements, const double nFPRate, const unsigned int nTweak, unsigned char nFlagsIn); + CBloomFilter() : nHashFuncs(0), nTweak(0), nFlags(0) {} + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(vData); + READWRITE(nHashFuncs); + READWRITE(nTweak); + READWRITE(nFlags); + } + + void insert(const std::vector& vKey); + void insert(const COutPoint& outpoint); + void insert(const uint256& hash); + + bool contains(const std::vector& vKey) const; + bool contains(const COutPoint& outpoint) const; + bool contains(const uint256& hash) const; + + //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS + //! (catch a filter which was just deserialized which was too big) + bool IsWithinSizeConstraints() const; + + //! Also adds any outputs which match the filter to the filter (to match their spending txes) + bool IsRelevantAndUpdate(const CTransaction& tx); +}; + +/** + * RollingBloomFilter is a probabilistic "keep track of most recently inserted" set. + * Construct it with the number of items to keep track of, and a false-positive + * rate. Unlike CBloomFilter, by default nTweak is set to a cryptographically + * secure random value for you. Similarly rather than clear() the method + * reset() is provided, which also changes nTweak to decrease the impact of + * false-positives. + * + * contains(item) will always return true if item was one of the last N to 1.5*N + * insert()'ed ... but may also return true for items that were not inserted. + * + * It needs around 1.8 bytes per element per factor 0.1 of false positive rate. + * For example, if we want 1000 elements, we'd need: + * - ~1800 bytes for a false positive rate of 0.1 + * - ~3600 bytes for a false positive rate of 0.01 + * - ~5400 bytes for a false positive rate of 0.001 + * + * If we make these simplifying assumptions: + * - logFpRate / log(0.5) doesn't get rounded or clamped in the nHashFuncs calculation + * - nElements is even, so that nEntriesPerGeneration == nElements / 2 + * + * Then we get a more accurate estimate for filter bytes: + * + * 3/(log(256)*log(2)) * log(1/fpRate) * nElements + */ +class CRollingBloomFilter +{ +public: + // A random bloom filter calls GetRand() at creation time. + // Don't create global CRollingBloomFilter objects, as they may be + // constructed before the randomizer is properly initialized. + CRollingBloomFilter(const unsigned int nElements, const double nFPRate); + + void insert(const std::vector& vKey); + void insert(const uint256& hash); + bool contains(const std::vector& vKey) const; + bool contains(const uint256& hash) const; + + void reset(); + +private: + int nEntriesPerGeneration; + int nEntriesThisGeneration; + int nGeneration; + std::vector data; + unsigned int nTweak; + int nHashFuncs; +}; + +#endif // BITCOIN_BLOOM_H diff --git a/depend/zcash/src/chain.cpp b/depend/zcash/src/chain.cpp new file mode 100644 index 000000000..7d45026bb --- /dev/null +++ b/depend/zcash/src/chain.cpp @@ -0,0 +1,109 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#include "chain.h" + +/** + * CChain implementation + */ +void CChain::SetTip(CBlockIndex *pindex) { + if (pindex == NULL) { + vChain.clear(); + return; + } + vChain.resize(pindex->nHeight + 1); + while (pindex && vChain[pindex->nHeight] != pindex) { + vChain[pindex->nHeight] = pindex; + pindex = pindex->pprev; + } +} + +CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { + int nStep = 1; + std::vector vHave; + vHave.reserve(32); + + if (!pindex) + pindex = Tip(); + while (pindex) { + vHave.push_back(pindex->GetBlockHash()); + // Stop when we have added the genesis block. + if (pindex->nHeight == 0) + break; + // Exponentially larger steps back, plus the genesis block. + int nHeight = std::max(pindex->nHeight - nStep, 0); + if (Contains(pindex)) { + // Use O(1) CChain index if possible. + pindex = (*this)[nHeight]; + } else { + // Otherwise, use O(log n) skiplist. + pindex = pindex->GetAncestor(nHeight); + } + if (vHave.size() > 10) + nStep *= 2; + } + + return CBlockLocator(vHave); +} + +const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + assert(pindex != nullptr); + if (pindex->nHeight > Height()) + pindex = pindex->GetAncestor(Height()); + while (pindex && !Contains(pindex)) + pindex = pindex->pprev; + return pindex; +} + +/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ +int static inline InvertLowestOne(int n) { return n & (n - 1); } + +/** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ +int static inline GetSkipHeight(int height) { + if (height < 2) + return 0; + + // Determine which height to jump back to. Any number strictly lower than height is acceptable, + // but the following expression seems to perform well in simulations (max 110 steps to go back + // up to 2**18 blocks). + return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); +} + +CBlockIndex* CBlockIndex::GetAncestor(int height) +{ + if (height > nHeight || height < 0) + return NULL; + + CBlockIndex* pindexWalk = this; + int heightWalk = nHeight; + while (heightWalk > height) { + int heightSkip = GetSkipHeight(heightWalk); + int heightSkipPrev = GetSkipHeight(heightWalk - 1); + if (pindexWalk->pskip != NULL && + (heightSkip == height || + (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && + heightSkipPrev >= height)))) { + // Only follow pskip if pprev->pskip isn't better than pskip->pprev. + pindexWalk = pindexWalk->pskip; + heightWalk = heightSkip; + } else { + assert(pindexWalk->pprev); + pindexWalk = pindexWalk->pprev; + heightWalk--; + } + } + return pindexWalk; +} + +const CBlockIndex* CBlockIndex::GetAncestor(int height) const +{ + return const_cast(this)->GetAncestor(height); +} + +void CBlockIndex::BuildSkip() +{ + if (pprev) + pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); +} diff --git a/depend/zcash/src/chain.h b/depend/zcash/src/chain.h new file mode 100644 index 000000000..1a5933c67 --- /dev/null +++ b/depend/zcash/src/chain.h @@ -0,0 +1,649 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CHAIN_H +#define BITCOIN_CHAIN_H + +#include "arith_uint256.h" +#include "primitives/block.h" +#include "pow.h" +#include "tinyformat.h" +#include "uint256.h" + +#include +#include + +static const int SPROUT_VALUE_VERSION = 1001400; +static const int SAPLING_VALUE_VERSION = 1010100; +static const int CHAIN_HISTORY_ROOT_VERSION = 2010200; +static const int NU5_DATA_VERSION = 4050000; + +/** + * Maximum amount of time that a block timestamp is allowed to be ahead of the + * median-time-past of the previous block. + */ +static const int64_t MAX_FUTURE_BLOCK_TIME_MTP = 90 * 60; + +/** + * Maximum amount of time that a block timestamp is allowed to be ahead of the + * current local time. + */ +static const int64_t MAX_FUTURE_BLOCK_TIME_LOCAL = 2 * 60 * 60; + +/** + * Timestamp window used as a grace period by code that compares external + * timestamps (such as timestamps passed to RPCs, or wallet key creation times) + * to block timestamps. + */ +static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME_LOCAL + 60; + +static_assert(MAX_FUTURE_BLOCK_TIME_LOCAL > MAX_FUTURE_BLOCK_TIME_MTP, + "MAX_FUTURE_BLOCK_TIME_LOCAL must be greater than MAX_FUTURE_BLOCK_TIME_MTP"); +static_assert(TIMESTAMP_WINDOW > MAX_FUTURE_BLOCK_TIME_LOCAL, + "TIMESTAMP_WINDOW must be greater than MAX_FUTURE_BLOCK_TIME_LOCAL"); + + +class CBlockFileInfo +{ +public: + unsigned int nBlocks; //!< number of blocks stored in file + unsigned int nSize; //!< number of used bytes of block file + unsigned int nUndoSize; //!< number of used bytes in the undo file + unsigned int nHeightFirst; //!< lowest height of block in file + unsigned int nHeightLast; //!< highest height of block in file + uint64_t nTimeFirst; //!< earliest time of block in file + uint64_t nTimeLast; //!< latest time of block in file + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(VARINT(nBlocks)); + READWRITE(VARINT(nSize)); + READWRITE(VARINT(nUndoSize)); + READWRITE(VARINT(nHeightFirst)); + READWRITE(VARINT(nHeightLast)); + READWRITE(VARINT(nTimeFirst)); + READWRITE(VARINT(nTimeLast)); + } + + void SetNull() { + nBlocks = 0; + nSize = 0; + nUndoSize = 0; + nHeightFirst = 0; + nHeightLast = 0; + nTimeFirst = 0; + nTimeLast = 0; + } + + CBlockFileInfo() { + SetNull(); + } + + std::string ToString() const; + + /** update statistics (does not update nSize) */ + void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn) { + if (nBlocks==0 || nHeightFirst > nHeightIn) + nHeightFirst = nHeightIn; + if (nBlocks==0 || nTimeFirst > nTimeIn) + nTimeFirst = nTimeIn; + nBlocks++; + if (nHeightIn > nHeightLast) + nHeightLast = nHeightIn; + if (nTimeIn > nTimeLast) + nTimeLast = nTimeIn; + } +}; + +struct CDiskBlockPos +{ + int nFile; + unsigned int nPos; + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(VARINT(nFile)); + READWRITE(VARINT(nPos)); + } + + CDiskBlockPos() { + SetNull(); + } + + CDiskBlockPos(int nFileIn, unsigned int nPosIn) { + nFile = nFileIn; + nPos = nPosIn; + } + + friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return (a.nFile == b.nFile && a.nPos == b.nPos); + } + + friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return !(a == b); + } + + void SetNull() { nFile = -1; nPos = 0; } + bool IsNull() const { return (nFile == -1); } + + std::string ToString() const + { + return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos); + } + +}; + +enum BlockStatus: uint32_t { + //! Unused. + BLOCK_VALID_UNKNOWN = 0, + + //! Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future + BLOCK_VALID_HEADER = 1, + + //! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents + //! are also at least TREE. + BLOCK_VALID_TREE = 2, + + /** + * Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, + * sigops, size, merkle root. Implies all parents are at least TREE but not necessarily TRANSACTIONS. When all + * parent blocks also have TRANSACTIONS, CBlockIndex::nChainTx will be set. + */ + BLOCK_VALID_TRANSACTIONS = 3, + + //! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30. + //! Implies all parents are also at least CHAIN. + BLOCK_VALID_CHAIN = 4, + + //! Scripts & signatures ok. Implies all parents are also at least SCRIPTS. + BLOCK_VALID_SCRIPTS = 5, + + //! All validity bits. + BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | + BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, + + BLOCK_HAVE_DATA = 8, //! full block available in blk*.dat + BLOCK_HAVE_UNDO = 16, //! undo data available in rev*.dat + BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, + + BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed + BLOCK_FAILED_CHILD = 64, //! descends from failed block + BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, + + BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade +}; + +//! Short-hand for the highest consensus validity we implement. +//! Blocks with this validity are assumed to satisfy all consensus rules. +static const BlockStatus BLOCK_VALID_CONSENSUS = BLOCK_VALID_SCRIPTS; + +/** The block chain is a tree shaped structure starting with the + * genesis block at the root, with each block potentially having multiple + * candidates to be the next block. A blockindex may have multiple pprev pointing + * to it, but at most one of them can be part of the currently active branch. + */ +class CBlockIndex +{ +public: + //! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex + const uint256* phashBlock; + + //! pointer to the index of the predecessor of this block + CBlockIndex* pprev; + + //! pointer to the index of some further predecessor of this block + CBlockIndex* pskip; + + //! height of the entry in the chain. The genesis block has height 0 + int nHeight; + + //! Which # file this block is stored in (blk?????.dat) + int nFile; + + //! Byte offset within blk?????.dat where this block's data is stored + unsigned int nDataPos; + + //! Byte offset within rev?????.dat where this block's undo data is stored + unsigned int nUndoPos; + + //! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block + arith_uint256 nChainWork; + + //! Number of transactions in this block. + //! Note: in a potential headers-first mode, this number cannot be relied upon + unsigned int nTx; + + //! (memory only) Number of transactions in the chain up to and including this block. + //! This value will be non-zero only if and only if transactions for this block and all its parents are available. + //! Change to 64-bit type when necessary; won't happen before 2030 + unsigned int nChainTx; + + //! Verification status of this block. See enum BlockStatus + unsigned int nStatus; + + //! Branch ID corresponding to the consensus rules used to validate this block. + //! Only cached if block validity is BLOCK_VALID_CONSENSUS. + //! Persisted at each activation height, memory-only for intervening blocks. + std::optional nCachedBranchId; + + //! Root of the ZIP 244 authorizing data commitment tree for this block. + //! + //! - For blocks prior to (not including) the NU5 activation block, this is always + //! null. + //! - For blocks including and after the NU5 activation block, this is only set once + //! a block has been connected to the main chain, and will be null otherwise. + uint256 hashAuthDataRoot; + + //! The anchor for the tree state up to the start of this block + uint256 hashSproutAnchor; + + //! (memory only) The anchor for the tree state up to the end of this block + uint256 hashFinalSproutRoot; + + //! Change in value held by the Sprout circuit over this block. + //! Will be std::nullopt for older blocks on old nodes until a reindex has taken place. + std::optional nSproutValue; + + //! (memory only) Total value held by the Sprout circuit up to and including this block. + //! Will be std::nullopt for on old nodes until a reindex has taken place. + //! Will be std::nullopt if nChainTx is zero. + std::optional nChainSproutValue; + + //! Change in value held by the Sapling circuit over this block. + //! Not a std::optional because this was added before Sapling activated, so we can + //! rely on the invariant that every block before this was added had nSaplingValue = 0. + CAmount nSaplingValue; + + //! (memory only) Total value held by the Sapling circuit up to and including this block. + //! Will be std::nullopt if nChainTx is zero. + std::optional nChainSaplingValue; + + //! Change in value held by the Orchard circuit over this block. + //! Not a std::optional because this was added before Orchard activated, so we can + //! rely on the invariant that every block before this was added had nOrchardValue = 0. + CAmount nOrchardValue; + + //! (memory only) Total value held by the Orchard circuit up to and including this block. + //! Will be std::nullopt if and only if nChainTx is zero. + std::optional nChainOrchardValue; + + //! Root of the Sapling commitment tree as of the end of this block. + //! + //! - For blocks prior to (not including) the Heartwood activation block, this is + //! always equal to hashBlockCommitments. + //! - For blocks including and after the Heartwood activation block, this is only set + //! once a block has been connected to the main chain, and will be null otherwise. + uint256 hashFinalSaplingRoot; + + //! Root of the Orchard commitment tree as of the end of this block. + //! + //! - For blocks prior to (not including) the NU5 activation block, this is always + //! null. + //! - For blocks including and after the NU5 activation block, this is only set + //! once a block has been connected to the main chain, and will be null otherwise. + uint256 hashFinalOrchardRoot; + + //! Root of the ZIP 221 history tree as of the end of the previous block. + //! + //! - For blocks prior to and including the Heartwood activation block, this is + //! always null. + //! - For blocks after (not including) the Heartwood activation block, and prior to + //! (not including) the NU5 activation block, this is always equal to + //! hashBlockCommitments. + //! - For blocks including and after the NU5 activation block, this is only set + //! once a block has been connected to the main chain, and will be null otherwise. + uint256 hashChainHistoryRoot; + + //! block header + int nVersion; + uint256 hashMerkleRoot; + uint256 hashBlockCommitments; + unsigned int nTime; + unsigned int nBits; + uint256 nNonce; + std::vector nSolution; + + //! (memory only) Sequential id assigned to distinguish order in which blocks are received. + uint32_t nSequenceId; + + void SetNull() + { + phashBlock = NULL; + pprev = NULL; + pskip = NULL; + nHeight = 0; + nFile = 0; + nDataPos = 0; + nUndoPos = 0; + nChainWork = arith_uint256(); + nTx = 0; + nChainTx = 0; + nStatus = 0; + nCachedBranchId = std::nullopt; + hashAuthDataRoot = uint256(); + hashSproutAnchor = uint256(); + hashFinalSproutRoot = uint256(); + hashFinalSaplingRoot = uint256(); + hashFinalOrchardRoot = uint256(); + hashChainHistoryRoot = uint256(); + nSequenceId = 0; + nSproutValue = std::nullopt; + nChainSproutValue = std::nullopt; + nSaplingValue = 0; + nChainSaplingValue = std::nullopt; + nOrchardValue = 0; + nChainOrchardValue = std::nullopt; + + nVersion = 0; + hashMerkleRoot = uint256(); + hashBlockCommitments = uint256(); + nTime = 0; + nBits = 0; + nNonce = uint256(); + nSolution.clear(); + } + + CBlockIndex() + { + SetNull(); + } + + CBlockIndex(const CBlockHeader& block) + { + SetNull(); + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + hashBlockCommitments = block.hashBlockCommitments; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + nSolution = block.nSolution; + } + + CDiskBlockPos GetBlockPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_DATA) { + ret.nFile = nFile; + ret.nPos = nDataPos; + } + return ret; + } + + CDiskBlockPos GetUndoPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_UNDO) { + ret.nFile = nFile; + ret.nPos = nUndoPos; + } + return ret; + } + + CBlockHeader GetBlockHeader() const + { + CBlockHeader block; + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.hashBlockCommitments = hashBlockCommitments; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + block.nSolution = nSolution; + return block; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + int64_t GetBlockTime() const + { + return (int64_t)nTime; + } + + enum { nMedianTimeSpan=11 }; + + int64_t GetMedianTimePast() const + { + int64_t pmedian[nMedianTimeSpan]; + int64_t* pbegin = &pmedian[nMedianTimeSpan]; + int64_t* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->GetBlockTime(); + + std::sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + std::string ToString() const + { + return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, nHeight, + hashMerkleRoot.ToString(), + GetBlockHash().ToString()); + } + + //! Check whether this block index entry is valid up to the passed validity level. + bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); + } + + //! Raise the validity level of this block index entry. + //! Returns true if the validity was changed. + bool RaiseValidity(enum BlockStatus nUpTo) + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { + nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; + return true; + } + return false; + } + + //! Build the skiplist pointer for this entry. + void BuildSkip(); + + //! Efficiently find an ancestor of this block. + CBlockIndex* GetAncestor(int height); + const CBlockIndex* GetAncestor(int height) const; +}; + +/** Used to marshal pointers into hashes for db storage. */ +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + + // This is the serialized `nVersion` of the block index, which is only set + // after the (de)serialization routine is called. This should only be used + // in LoadBlockIndexGuts (which is the only place where we read block index + // objects from disk anyway). + int nClientVersion = 0; + + CDiskBlockIndex() { + hashPrev = uint256(); + } + + explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex) { + hashPrev = (pprev ? pprev->GetBlockHash() : uint256()); + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + int nVersion = s.GetVersion(); + if (!(s.GetType() & SER_GETHASH)) + READWRITE(VARINT(nVersion)); + nClientVersion = nVersion; + + READWRITE(VARINT(nHeight)); + READWRITE(VARINT(nStatus)); + READWRITE(VARINT(nTx)); + if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) + READWRITE(VARINT(nFile)); + if (nStatus & BLOCK_HAVE_DATA) + READWRITE(VARINT(nDataPos)); + if (nStatus & BLOCK_HAVE_UNDO) + READWRITE(VARINT(nUndoPos)); + if (nStatus & BLOCK_ACTIVATES_UPGRADE) { + if (ser_action.ForRead()) { + uint32_t branchId; + READWRITE(branchId); + nCachedBranchId = branchId; + } else { + // nCachedBranchId must always be set if BLOCK_ACTIVATES_UPGRADE is set. + assert(nCachedBranchId); + uint32_t branchId = *nCachedBranchId; + READWRITE(branchId); + } + } + READWRITE(hashSproutAnchor); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(hashBlockCommitments); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + READWRITE(nSolution); + + // Only read/write nSproutValue if the client version used to create + // this index was storing them. + if ((s.GetType() & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) { + READWRITE(nSproutValue); + } + + // Only read/write nSaplingValue if the client version used to create + // this index was storing them. + if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) { + READWRITE(nSaplingValue); + } + + // Only read/write hashFinalSaplingRoot and hashChainHistoryRoot if the + // client version used to create this index was storing them. + if ((s.GetType() & SER_DISK) && (nVersion >= CHAIN_HISTORY_ROOT_VERSION)) { + READWRITE(hashFinalSaplingRoot); + READWRITE(hashChainHistoryRoot); + } else if (ser_action.ForRead()) { + // For block indices written before the client was Heartwood-aware, + // these are always identical. + hashFinalSaplingRoot = hashBlockCommitments; + } + + // Only read/write NU5 data if the client version used to create this + // index was storing them. For block indices written before the client + // was NU5-aware, these are always null / zero. + if ((s.GetType() & SER_DISK) && (nVersion >= NU5_DATA_VERSION)) { + READWRITE(hashAuthDataRoot); + READWRITE(hashFinalOrchardRoot); + READWRITE(nOrchardValue); + } + + // If you have just added new serialized fields above, remember to add + // them to CBlockTreeDB::LoadBlockIndexGuts() in txdb.cpp :) + } + + uint256 GetBlockHash() const + { + CBlockHeader block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.hashBlockCommitments = hashBlockCommitments; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + block.nSolution = nSolution; + return block.GetHash(); + } + + + std::string ToString() const + { + std::string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s)", + GetBlockHash().ToString(), + hashPrev.ToString()); + return str; + } +}; + +/** An in-memory indexed chain of blocks. */ +class CChain { +private: + std::vector vChain; + +public: + /** Returns the index entry for the genesis block of this chain, or NULL if none. */ + CBlockIndex *Genesis() const { + return vChain.size() > 0 ? vChain[0] : NULL; + } + + /** Returns the index entry for the tip of this chain, or NULL if none. */ + CBlockIndex *Tip() const { + return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; + } + + /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ + CBlockIndex *operator[](int nHeight) const { + if (nHeight < 0 || nHeight >= (int)vChain.size()) + return NULL; + return vChain[nHeight]; + } + + /** Compare two chains efficiently. */ + friend bool operator==(const CChain &a, const CChain &b) { + return a.vChain.size() == b.vChain.size() && + a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; + } + + /** Efficiently check whether a block is present in this chain. */ + bool Contains(const CBlockIndex *pindex) const { + return (*this)[pindex->nHeight] == pindex; + } + + /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ + CBlockIndex *Next(const CBlockIndex *pindex) const { + if (Contains(pindex)) + return (*this)[pindex->nHeight + 1]; + else + return NULL; + } + + /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ + int Height() const { + return int(vChain.size()) - 1; + } + + /** Set/initialize a chain with a given tip. */ + void SetTip(CBlockIndex *pindex); + + /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ + CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; + + /** Find the last common block between this chain and a block index entry. */ + const CBlockIndex *FindFork(const CBlockIndex *pindex) const; +}; + +#endif // BITCOIN_CHAIN_H diff --git a/depend/zcash/src/chainparams.cpp b/depend/zcash/src/chainparams.cpp new file mode 100644 index 000000000..8bfb35718 --- /dev/null +++ b/depend/zcash/src/chainparams.cpp @@ -0,0 +1,860 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2015-2020 The Zcash Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "key_io.h" +#include "main.h" +#include "crypto/equihash.h" + +#include "tinyformat.h" +#include "util.h" +#include "utilstrencodings.h" + +#include +#include +#include + +#include + +#include "chainparamsseeds.h" + +static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const uint256& nNonce, const std::vector& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +{ + // To create a genesis block for a new chain which is Overwintered: + // txNew.nVersion = OVERWINTER_TX_VERSION + // txNew.fOverwintered = true + // txNew.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID + // txNew.nExpiryHeight = + CMutableTransaction txNew; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 520617983 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = genesisReward; + txNew.vout[0].scriptPubKey = genesisOutputScript; + + CBlock genesis; + genesis.nTime = nTime; + genesis.nBits = nBits; + genesis.nNonce = nNonce; + genesis.nSolution = nSolution; + genesis.nVersion = nVersion; + genesis.vtx.push_back(txNew); + genesis.hashPrevBlock.SetNull(); + genesis.hashMerkleRoot = genesis.BuildMerkleTree(); + return genesis; +} + +/** + * Build the genesis block. Note that the output of its generation + * transaction cannot be spent since it did not originally exist in the + * database (and is in any case of zero value). + * + * >>> from hashlib import blake2s + * >>> 'Zcash' + blake2s(b'The Economist 2016-10-29 Known unknown: Another crypto-currency is born. BTC#436254 0000000000000000044f321997f336d2908cf8c8d6893e88dbf067e2d949487d ETH#2521903 483039a6b6bd8bd05f0584f9a078d075e454925eb71c1f13eaff59b405a721bb DJIA close on 27 Oct 2016: 18,169.68').hexdigest() + * + * CBlock(hash=00040fe8, ver=4, hashPrevBlock=00000000000000, hashMerkleRoot=c4eaa5, nTime=1477641360, nBits=1f07ffff, nNonce=4695, vtx=1) + * CTransaction(hash=c4eaa5, ver=1, vin.size=1, vout.size=1, nLockTime=0) + * CTxIn(COutPoint(000000, -1), coinbase 04ffff071f0104455a6361736830623963346565663862376363343137656535303031653335303039383462366665613335363833613763616331343161303433633432303634383335643334) + * CTxOut(nValue=0.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + * vMerkleTree: c4eaa5 + */ +static CBlock CreateGenesisBlock(uint32_t nTime, const uint256& nNonce, const std::vector& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +{ + const char* pszTimestamp = "Zcash0b9c4eef8b7cc417ee5001e3500984b6fea35683a7cac141a043c42064835d34"; + const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nSolution, nBits, nVersion, genesisReward); +} + +/** + * Main network + */ +/** + * What makes a good checkpoint block? + * + Is surrounded by blocks with reasonable timestamps + * (no blocks before with a timestamp after, none after with + * timestamp before) + * + Contains no strange transactions + */ + +const arith_uint256 maxUint = UintToArith256(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); + +class CMainParams : public CChainParams { +public: + CMainParams() { + keyConstants.strNetworkID = "main"; + strCurrencyUnits = "ZEC"; + keyConstants.bip44CoinType = 133; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md + consensus.fCoinbaseMustBeShielded = true; + consensus.nSubsidySlowStartInterval = 20000; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = POST_BLOSSOM_HALVING_INTERVAL(Consensus::PRE_BLOSSOM_HALVING_INTERVAL); + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 4000; + const size_t N = 200, K = 9; + static_assert(equihash_parameters_acceptable(N, K)); + consensus.nEquihashN = N; + consensus.nEquihashK = K; + consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowAveragingWindow = 17; + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); + consensus.nPowMaxAdjustDown = 32; // 32% adjustment down + consensus.nPowMaxAdjustUp = 16; // 16% adjustment up + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + consensus.nPowAllowMinDifficultyBlocksAfterHeight = std::nullopt; + consensus.fPowNoRetargeting = false; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170005; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 347500; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].hashActivationBlock = + uint256S("0000000003761c0d0c3974b54bdb425613bbb1eaadd6e70b764de82f195ea243"); + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 419200; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].hashActivationBlock = + uint256S("00000000025a57200d898ac7f21e26bf29028bbe96ec46e05b2c17cc9db9e4f3"); + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170009; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight = 653600; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].hashActivationBlock = + uint256S("00000000020bebb33c1b34b67a982a328ab212a206dacbe561a7cc94aab3e9bb"); + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nProtocolVersion = 170011; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nActivationHeight = 903000; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].hashActivationBlock = + uint256S("0000000000aad1c8698964a93c35ecf8b4d05e848de9e2fe7606067139be5643"); + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nProtocolVersion = 170013; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight = 1046400; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].hashActivationBlock = + uint256S("00000000002038016f976744c369dce7419fca30e7171dfac703af5e5f7ad1d4"); + consensus.vUpgrades[Consensus::UPGRADE_NU5].nProtocolVersion = 170100; + consensus.vUpgrades[Consensus::UPGRADE_NU5].nActivationHeight = 1687104; + + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nProtocolVersion = 0x7FFFFFFF; + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + + consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48; + + // guarantees the first 2 characters, when base58 encoded, are "t1" + keyConstants.base58Prefixes[PUBKEY_ADDRESS] = {0x1C,0xB8}; + // guarantees the first 2 characters, when base58 encoded, are "t3" + keyConstants.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBD}; + // the first character, when base58 encoded, is "5" or "K" or "L" (as in Bitcoin) + keyConstants.base58Prefixes[SECRET_KEY] = {0x80}; + // do not rely on these BIP32 prefixes; they are not specified and may change + keyConstants.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x88,0xB2,0x1E}; + keyConstants.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x88,0xAD,0xE4}; + // guarantees the first 2 characters, when base58 encoded, are "zc" + keyConstants.base58Prefixes[ZCPAYMENT_ADDRESS] = {0x16,0x9A}; + // guarantees the first 4 characters, when base58 encoded, are "ZiVK" + keyConstants.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAB,0xD3}; + // guarantees the first 2 characters, when base58 encoded, are "SK" + keyConstants.base58Prefixes[ZCSPENDING_KEY] = {0xAB,0x36}; + + keyConstants.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zs"; + keyConstants.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviews"; + keyConstants.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivks"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-main"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviews"; + + { + std::vector ecc_addresses = { + "t3LmX1cxWPPPqL4TZHx42HU3U5ghbFjRiif", + "t3Toxk1vJQ6UjWQ42tUJz2rV2feUWkpbTDs", + "t3ZBdBe4iokmsjdhMuwkxEdqMCFN16YxKe6", + "t3ZuaJziLM8xZ32rjDUzVjVtyYdDSz8GLWB", + "t3bAtYWa4bi8VrtvqySxnbr5uqcG9czQGTZ", + "t3dktADfb5Rmxncpe1HS5BRS5Gcj7MZWYBi", + "t3hgskquvKKoCtvxw86yN7q8bzwRxNgUZmc", + "t3R1VrLzwcxAZzkX4mX3KGbWpNsgtYtMntj", + "t3ff6fhemqPMVujD3AQurxRxTdvS1pPSaa2", + "t3cEUQFG3KYnFG6qYhPxSNgGi3HDjUPwC3J", + "t3WR9F5U4QvUFqqx9zFmwT6xFqduqRRXnaa", + "t3PYc1LWngrdUrJJbHkYPCKvJuvJjcm85Ch", + "t3bgkjiUeatWNkhxY3cWyLbTxKksAfk561R", + "t3Z5rrR8zahxUpZ8itmCKhMSfxiKjUp5Dk5", + "t3PU1j7YW3fJ67jUbkGhSRto8qK2qXCUiW3", + "t3S3yaT7EwNLaFZCamfsxxKwamQW2aRGEkh", + "t3eutXKJ9tEaPSxZpmowhzKhPfJvmtwTEZK", + "t3gbTb7brxLdVVghSPSd3ycGxzHbUpukeDm", + "t3UCKW2LrHFqPMQFEbZn6FpjqnhAAbfpMYR", + "t3NyHsrnYbqaySoQqEQRyTWkjvM2PLkU7Uu", + "t3QEFL6acxuZwiXtW3YvV6njDVGjJ1qeaRo", + "t3PdBRr2S1XTDzrV8bnZkXF3SJcrzHWe1wj", + "t3ZWyRPpWRo23pKxTLtWsnfEKeq9T4XPxKM", + "t3he6QytKCTydhpztykFsSsb9PmBT5JBZLi", + "t3VWxWDsLb2TURNEP6tA1ZSeQzUmPKFNxRY", + "t3NmWLvZkbciNAipauzsFRMxoZGqmtJksbz", + "t3cKr4YxVPvPBG1mCvzaoTTdBNokohsRJ8n", + "t3T3smGZn6BoSFXWWXa1RaoQdcyaFjMfuYK", + "t3gkDUe9Gm4GGpjMk86TiJZqhztBVMiUSSA", + "t3eretuBeBXFHe5jAqeSpUS1cpxVh51fAeb", + "t3dN8g9zi2UGJdixGe9txeSxeofLS9t3yFQ", + "t3S799pq9sYBFwccRecoTJ3SvQXRHPrHqvx", + "t3fhYnv1S5dXwau7GED3c1XErzt4n4vDxmf", + "t3cmE3vsBc5xfDJKXXZdpydCPSdZqt6AcNi", + "t3h5fPdjJVHaH4HwynYDM5BB3J7uQaoUwKi", + "t3Ma35c68BgRX8sdLDJ6WR1PCrKiWHG4Da9", + "t3LokMKPL1J8rkJZvVpfuH7dLu6oUWqZKQK", + "t3WFFGbEbhJWnASZxVLw2iTJBZfJGGX73mM", + "t3L8GLEsUn4QHNaRYcX3EGyXmQ8kjpT1zTa", + "t3PgfByBhaBSkH8uq4nYJ9ZBX4NhGCJBVYm", + "t3WecsqKDhWXD4JAgBVcnaCC2itzyNZhJrv", + "t3ZG9cSfopnsMQupKW5v9sTotjcP5P6RTbn", + "t3hC1Ywb5zDwUYYV8LwhvF5rZ6m49jxXSG5", + "t3VgMqDL15ZcyQDeqBsBW3W6rzfftrWP2yB", + "t3LC94Y6BwLoDtBoK2NuewaEbnko1zvR9rm", + "t3cWCUZJR3GtALaTcatrrpNJ3MGbMFVLRwQ", + "t3YYF4rPLVxDcF9hHFsXyc5Yq1TFfbojCY6", + "t3XHAGxRP2FNfhAjxGjxbrQPYtQQjc3RCQD", + }; + + // ZF and MG each use a single address repeated 48 times, + // once for each funding period. + std::vector zf_addresses(48, "t3dvVE3SQEi7kqNzwrfNePxZ1d4hUyztBA1"); + std::vector mg_addresses(48, "t3XyYW8yBFRuMnfvm5KLGFbEVz25kckZXym"); + + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_BP, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400, + ecc_addresses); + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_ZF, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400, + zf_addresses); + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_MG, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2726400, + mg_addresses); + } + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("00000000000000000000000000000000000000000000000004a90edff47bbdc6"); + + /** + * The message start string should be awesome! ⓩ⤠+ */ + pchMessageStart[0] = 0x24; + pchMessageStart[1] = 0xe9; + pchMessageStart[2] = 0x27; + pchMessageStart[3] = 0x64; + vAlertPubKey = ParseHex("04b7ecf0baa90495ceb4e4090f6b2fd37eec1e9c85fac68a487f3ce11589692e4a317479316ee814e066638e1db54e37a10689b70286e6315b1087b6615d179264"); + nDefaultPort = 8233; + nPruneAfterHeight = 100000; + + genesis = CreateGenesisBlock( + 1477641360, + uint256S("0x0000000000000000000000000000000000000000000000000000000000001257"), + ParseHex("000a889f00854b8665cd555f4656f68179d31ccadc1b1f7fb0952726313b16941da348284d67add4686121d4e3d930160c1348d8191c25f12b267a6a9c131b5031cbf8af1f79c9d513076a216ec87ed045fa966e01214ed83ca02dc1797270a454720d3206ac7d931a0a680c5c5e099057592570ca9bdf6058343958b31901fce1a15a4f38fd347750912e14004c73dfe588b903b6c03166582eeaf30529b14072a7b3079e3a684601b9b3024054201f7440b0ee9eb1a7120ff43f713735494aa27b1f8bab60d7f398bca14f6abb2adbf29b04099121438a7974b078a11635b594e9170f1086140b4173822dd697894483e1c6b4e8b8dcd5cb12ca4903bc61e108871d4d915a9093c18ac9b02b6716ce1013ca2c1174e319c1a570215bc9ab5f7564765f7be20524dc3fdf8aa356fd94d445e05ab165ad8bb4a0db096c097618c81098f91443c719416d39837af6de85015dca0de89462b1d8386758b2cf8a99e00953b308032ae44c35e05eb71842922eb69797f68813b59caf266cb6c213569ae3280505421a7e3a0a37fdf8e2ea354fc5422816655394a9454bac542a9298f176e211020d63dee6852c40de02267e2fc9d5e1ff2ad9309506f02a1a71a0501b16d0d36f70cdfd8de78116c0c506ee0b8ddfdeb561acadf31746b5a9dd32c21930884397fb1682164cb565cc14e089d66635a32618f7eb05fe05082b8a3fae620571660a6b89886eac53dec109d7cbb6930ca698a168f301a950be152da1be2b9e07516995e20baceebecb5579d7cdbc16d09f3a50cb3c7dffe33f26686d4ff3f8946ee6475e98cf7b3cf9062b6966e838f865ff3de5fb064a37a21da7bb8dfd2501a29e184f207caaba364f36f2329a77515dcb710e29ffbf73e2bbd773fab1f9a6b005567affff605c132e4e4dd69f36bd201005458cfbd2c658701eb2a700251cefd886b1e674ae816d3f719bac64be649c172ba27a4fd55947d95d53ba4cbc73de97b8af5ed4840b659370c556e7376457f51e5ebb66018849923db82c1c9a819f173cccdb8f3324b239609a300018d0fb094adf5bd7cbb3834c69e6d0b3798065c525b20f040e965e1a161af78ff7561cd874f5f1b75aa0bc77f720589e1b810f831eac5073e6dd46d00a2793f70f7427f0f798f2f53a67e615e65d356e66fe40609a958a05edb4c175bcc383ea0530e67ddbe479a898943c6e3074c6fcc252d6014de3a3d292b03f0d88d312fe221be7be7e3c59d07fa0f2f4029e364f1f355c5d01fa53770d0cd76d82bf7e60f6903bc1beb772e6fde4a70be51d9c7e03c8d6d8dfb361a234ba47c470fe630820bbd920715621b9fbedb49fcee165ead0875e6c2b1af16f50b5d6140cc981122fcbcf7c5a4e3772b3661b628e08380abc545957e59f634705b1bbde2f0b4e055a5ec5676d859be77e20962b645e051a880fddb0180b4555789e1f9344a436a84dc5579e2553f1e5fb0a599c137be36cabbed0319831fea3fddf94ddc7971e4bcf02cdc93294a9aab3e3b13e3b058235b4f4ec06ba4ceaa49d675b4ba80716f3bc6976b1fbf9c8bf1f3e3a4dc1cd83ef9cf816667fb94f1e923ff63fef072e6a19321e4812f96cb0ffa864da50ad74deb76917a336f31dce03ed5f0303aad5e6a83634f9fcc371096f8288b8f02ddded5ff1bb9d49331e4a84dbe1543164438fde9ad71dab024779dcdde0b6602b5ae0a6265c14b94edd83b37403f4b78fcd2ed555b596402c28ee81d87a909c4e8722b30c71ecdd861b05f61f8b1231795c76adba2fdefa451b283a5d527955b9f3de1b9828e7b2e74123dd47062ddcc09b05e7fa13cb2212a6fdbc65d7e852cec463ec6fd929f5b8483cf3052113b13dac91b69f49d1b7d1aec01c4a68e41ce157"), + 0x1f07ffff, 4, 0); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x00040fe8ec8471911baa1db1266ea15dd06b4a8a5c453883c000b031973dce08")); + assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb")); + + vFixedSeeds.clear(); + vSeeds.clear(); + vSeeds.push_back(CDNSSeedData("z.cash", "dnsseed.z.cash")); // Zcash + vSeeds.push_back(CDNSSeedData("str4d.xyz", "dnsseed.str4d.xyz")); // @str4d + vSeeds.push_back(CDNSSeedData("zfnd.org", "mainnet.seeder.zfnd.org")); // Zcash Foundation + vSeeds.push_back(CDNSSeedData("yolo.money", "mainnet.is.yolo.money")); // gtank + + vFixedSeeds = std::vector(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main)); + + fMiningRequiresPeers = true; + fDefaultConsistencyChecks = false; + fRequireStandard = true; + fMineBlocksOnDemand = false; + fTestnetToBeDeprecatedFieldRPC = false; + + checkpointData = (CCheckpointData) { + boost::assign::map_list_of + (0, consensus.hashGenesisBlock) + (2500, uint256S("0x00000006dc968f600be11a86cbfbf7feb61c7577f45caced2e82b6d261d19744")) + (15000, uint256S("0x00000000b6bc56656812a5b8dcad69d6ad4446dec23b5ec456c18641fb5381ba")) + (67500, uint256S("0x000000006b366d2c1649a6ebb4787ac2b39c422f451880bc922e3a6fbd723616")) + (100000, uint256S("0x000000001c5c82cd6baccfc0879e3830fd50d5ede17fa2c37a9a253c610eb285")) + (133337, uint256S("0x0000000002776ccfaf06cc19857accf3e20c01965282f916b8a886e3e4a05be9")) + (180000, uint256S("0x000000001205b742eac4a1b3959635bdf8aeada078d6a996df89740f7b54351d")) + (222222, uint256S("0x000000000cafb9e56445a6cabc8057b57ee6fcc709e7adbfa195e5c7fac61343")) + (270000, uint256S("0x00000000025c1cfa0258e33ab050aaa9338a3d4aaa3eb41defefc887779a9729")) + (304600, uint256S("0x00000000028324e022a45014c4a4dc51e95d41e6bceb6ad554c5b65d5cea3ea5")) + (410100, uint256S("0x0000000002c565958f783a24a4ac17cde898ff525e75ed9baf66861b0b9fcada")) + (497000, uint256S("0x0000000000abd333f0acca6ffdf78a167699686d6a7d25c33fca5f295061ffff")) + (525000, uint256S("0x0000000001a36c500378be8862d9bf1bea8f1616da6e155971b608139cc7e39b")), + 1556722044, // * UNIX timestamp of last checkpoint block + 4653556, // * total number of transactions between genesis and last checkpoint + 5106 // * estimated number of transactions per day after checkpoint + // total number of tx / (checkpoint block height / (24 * 24)) + }; + + // Hardcoded fallback value for the Sprout shielded value pool balance + // for nodes that have not reindexed since the introduction of monitoring + // in #2795. + nSproutValuePoolCheckpointHeight = 520633; + nSproutValuePoolCheckpointBalance = 22145062442933; + fZIP209Enabled = true; + hashSproutValuePoolCheckpointBlock = uint256S("0000000000c7b46b6bc04b4cbf87d8bb08722aebd51232619b214f7273f8460e"); + + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { + "t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd", /* main-index: 0*/ + "t3cL9AucCajm3HXDhb5jBnJK2vapVoXsop3", /* main-index: 1*/ + "t3fqvkzrrNaMcamkQMwAyHRjfDdM2xQvDTR", /* main-index: 2*/ + "t3TgZ9ZT2CTSK44AnUPi6qeNaHa2eC7pUyF", /* main-index: 3*/ + "t3SpkcPQPfuRYHsP5vz3Pv86PgKo5m9KVmx", /* main-index: 4*/ + "t3Xt4oQMRPagwbpQqkgAViQgtST4VoSWR6S", /* main-index: 5*/ + "t3ayBkZ4w6kKXynwoHZFUSSgXRKtogTXNgb", /* main-index: 6*/ + "t3adJBQuaa21u7NxbR8YMzp3km3TbSZ4MGB", /* main-index: 7*/ + "t3K4aLYagSSBySdrfAGGeUd5H9z5Qvz88t2", /* main-index: 8*/ + "t3RYnsc5nhEvKiva3ZPhfRSk7eyh1CrA6Rk", /* main-index: 9*/ + "t3Ut4KUq2ZSMTPNE67pBU5LqYCi2q36KpXQ", /* main-index: 10*/ + "t3ZnCNAvgu6CSyHm1vWtrx3aiN98dSAGpnD", /* main-index: 11*/ + "t3fB9cB3eSYim64BS9xfwAHQUKLgQQroBDG", /* main-index: 12*/ + "t3cwZfKNNj2vXMAHBQeewm6pXhKFdhk18kD", /* main-index: 13*/ + "t3YcoujXfspWy7rbNUsGKxFEWZqNstGpeG4", /* main-index: 14*/ + "t3bLvCLigc6rbNrUTS5NwkgyVrZcZumTRa4", /* main-index: 15*/ + "t3VvHWa7r3oy67YtU4LZKGCWa2J6eGHvShi", /* main-index: 16*/ + "t3eF9X6X2dSo7MCvTjfZEzwWrVzquxRLNeY", /* main-index: 17*/ + "t3esCNwwmcyc8i9qQfyTbYhTqmYXZ9AwK3X", /* main-index: 18*/ + "t3M4jN7hYE2e27yLsuQPPjuVek81WV3VbBj", /* main-index: 19*/ + "t3gGWxdC67CYNoBbPjNvrrWLAWxPqZLxrVY", /* main-index: 20*/ + "t3LTWeoxeWPbmdkUD3NWBquk4WkazhFBmvU", /* main-index: 21*/ + "t3P5KKX97gXYFSaSjJPiruQEX84yF5z3Tjq", /* main-index: 22*/ + "t3f3T3nCWsEpzmD35VK62JgQfFig74dV8C9", /* main-index: 23*/ + "t3Rqonuzz7afkF7156ZA4vi4iimRSEn41hj", /* main-index: 24*/ + "t3fJZ5jYsyxDtvNrWBeoMbvJaQCj4JJgbgX", /* main-index: 25*/ + "t3Pnbg7XjP7FGPBUuz75H65aczphHgkpoJW", /* main-index: 26*/ + "t3WeKQDxCijL5X7rwFem1MTL9ZwVJkUFhpF", /* main-index: 27*/ + "t3Y9FNi26J7UtAUC4moaETLbMo8KS1Be6ME", /* main-index: 28*/ + "t3aNRLLsL2y8xcjPheZZwFy3Pcv7CsTwBec", /* main-index: 29*/ + "t3gQDEavk5VzAAHK8TrQu2BWDLxEiF1unBm", /* main-index: 30*/ + "t3Rbykhx1TUFrgXrmBYrAJe2STxRKFL7G9r", /* main-index: 31*/ + "t3aaW4aTdP7a8d1VTE1Bod2yhbeggHgMajR", /* main-index: 32*/ + "t3YEiAa6uEjXwFL2v5ztU1fn3yKgzMQqNyo", /* main-index: 33*/ + "t3g1yUUwt2PbmDvMDevTCPWUcbDatL2iQGP", /* main-index: 34*/ + "t3dPWnep6YqGPuY1CecgbeZrY9iUwH8Yd4z", /* main-index: 35*/ + "t3QRZXHDPh2hwU46iQs2776kRuuWfwFp4dV", /* main-index: 36*/ + "t3enhACRxi1ZD7e8ePomVGKn7wp7N9fFJ3r", /* main-index: 37*/ + "t3PkLgT71TnF112nSwBToXsD77yNbx2gJJY", /* main-index: 38*/ + "t3LQtHUDoe7ZhhvddRv4vnaoNAhCr2f4oFN", /* main-index: 39*/ + "t3fNcdBUbycvbCtsD2n9q3LuxG7jVPvFB8L", /* main-index: 40*/ + "t3dKojUU2EMjs28nHV84TvkVEUDu1M1FaEx", /* main-index: 41*/ + "t3aKH6NiWN1ofGd8c19rZiqgYpkJ3n679ME", /* main-index: 42*/ + "t3MEXDF9Wsi63KwpPuQdD6by32Mw2bNTbEa", /* main-index: 43*/ + "t3WDhPfik343yNmPTqtkZAoQZeqA83K7Y3f", /* main-index: 44*/ + "t3PSn5TbMMAEw7Eu36DYctFezRzpX1hzf3M", /* main-index: 45*/ + "t3R3Y5vnBLrEn8L6wFjPjBLnxSUQsKnmFpv", /* main-index: 46*/ + "t3Pcm737EsVkGTbhsu2NekKtJeG92mvYyoN", /* main-index: 47*/ + }; + + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight(0)); + } +}; +static CMainParams mainParams; + +/** + * Testnet (v3) + */ +class CTestNetParams : public CChainParams { +public: + CTestNetParams() { + keyConstants.strNetworkID = "test"; + strCurrencyUnits = "TAZ"; + keyConstants.bip44CoinType = 1; + consensus.fCoinbaseMustBeShielded = true; + consensus.nSubsidySlowStartInterval = 20000; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = POST_BLOSSOM_HALVING_INTERVAL(Consensus::PRE_BLOSSOM_HALVING_INTERVAL); + consensus.nMajorityEnforceBlockUpgrade = 51; + consensus.nMajorityRejectBlockOutdated = 75; + consensus.nMajorityWindow = 400; + const size_t N = 200, K = 9; + static_assert(equihash_parameters_acceptable(N, K)); + consensus.nEquihashN = N; + consensus.nEquihashK = K; + consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowAveragingWindow = 17; + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); + consensus.nPowMaxAdjustDown = 32; // 32% adjustment down + consensus.nPowMaxAdjustUp = 16; // 16% adjustment up + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + consensus.nPowAllowMinDifficultyBlocksAfterHeight = 299187; + consensus.fPowNoRetargeting = false; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 207500; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].hashActivationBlock = + uint256S("0000257c4331b098045023fcfbfa2474681f4564ab483f84e4e1ad078e4acf44"); + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170007; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 280000; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].hashActivationBlock = + uint256S("000420e7fcc3a49d729479fb0b560dd7b8617b178a08e9e389620a9d1dd6361a"); + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170008; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight = 584000; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].hashActivationBlock = + uint256S("00367515ef2e781b8c9358b443b6329572599edd02c59e8af67db9785122f298"); + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nProtocolVersion = 170010; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nActivationHeight = 903800; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].hashActivationBlock = + uint256S("05688d8a0e9ff7c04f6f05e6d695dc5ab43b9c4803342d77ae360b2b27d2468e"); + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nProtocolVersion = 170012; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight = 1028500; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].hashActivationBlock = + uint256S("01a4d7c6aada30c87762c1bf33fff5df7266b1fd7616bfdb5227fa59bd79e7a2"); + consensus.vUpgrades[Consensus::UPGRADE_NU5].nProtocolVersion = 170050; + consensus.vUpgrades[Consensus::UPGRADE_NU5].nActivationHeight = 1842420; + consensus.vUpgrades[Consensus::UPGRADE_NU5].hashActivationBlock = + uint256S("0006d75c60b3093d1b671ff7da11c99ea535df9927c02e6ed9eb898605eb7381"); + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nProtocolVersion = 0x7FFFFFFF; + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + + consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48; + + // guarantees the first 2 characters, when base58 encoded, are "tm" + keyConstants.base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25}; + // guarantees the first 2 characters, when base58 encoded, are "t2" + keyConstants.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA}; + // the first character, when base58 encoded, is "9" or "c" (as in Bitcoin) + keyConstants.base58Prefixes[SECRET_KEY] = {0xEF}; + // do not rely on these BIP32 prefixes; they are not specified and may change + keyConstants.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF}; + keyConstants.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94}; + // guarantees the first 2 characters, when base58 encoded, are "zt" + keyConstants.base58Prefixes[ZCPAYMENT_ADDRESS] = {0x16,0xB6}; + // guarantees the first 4 characters, when base58 encoded, are "ZiVt" + keyConstants.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C}; + // guarantees the first 2 characters, when base58 encoded, are "ST" + keyConstants.base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08}; + + keyConstants.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "ztestsapling"; + keyConstants.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewtestsapling"; + keyConstants.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivktestsapling"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-test"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewtestsapling"; + + // Testnet funding streams + { + std::vector ecc_addresses = { + "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz", + "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz", + "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz", + "t26ovBdKAJLtrvBsE2QGF4nqBkEuptuPFZz", + "t2NNHrgPpE388atmWSF4DxAb3xAoW5Yp45M", + "t2VMN28itPyMeMHBEd9Z1hm6YLkQcGA1Wwe", + "t2CHa1TtdfUV8UYhNm7oxbzRyfr8616BYh2", + "t2F77xtr28U96Z2bC53ZEdTnQSUAyDuoa67", + "t2ARrzhbgcpoVBDPivUuj6PzXzDkTBPqfcT", + "t278aQ8XbvFR15mecRguiJDQQVRNnkU8kJw", + "t2Dp1BGnZsrTXZoEWLyjHmg3EPvmwBnPDGB", + "t2KzeqXgf4ju33hiSqCuKDb8iHjPCjMq9iL", + "t2Nyxqv1BiWY1eUSiuxVw36oveawYuo18tr", + "t2DKFk5JRsVoiuinK8Ti6eM4Yp7v8BbfTyH", + "t2CUaBca4k1x36SC4q8Nc8eBoqkMpF3CaLg", + "t296SiKL7L5wvFmEdMxVLz1oYgd6fTfcbZj", + "t29fBCFbhgsjL3XYEZ1yk1TUh7eTusB6dPg", + "t2FGofLJXa419A76Gpf5ncxQB4gQXiQMXjK", + "t2ExfrnRVnRiXDvxerQ8nZbcUQvNvAJA6Qu", + "t28JUffLp47eKPRHKvwSPzX27i9ow8LSXHx", + "t2JXWPtrtyL861rFWMZVtm3yfgxAf4H7uPA", + "t2QdgbJoWfYHgyvEDEZBjHmgkr9yNJff3Hi", + "t2QW43nkco8r32ZGRN6iw6eSzyDjkMwCV3n", + "t2DgYDXMJTYLwNcxighQ9RCgPxMVATRcUdC", + "t2Bop7dg33HGZx3wunnQzi2R2ntfpjuti3M", + "t2HVeEwovcLq9RstAbYkqngXNEsCe2vjJh9", + "t2HxbP5keQSx7p592zWQ5bJ5GrMmGDsV2Xa", + "t2TJzUg2matao3mztBRJoWnJY6ekUau6tPD", + "t29pMzxmo6wod25YhswcjKv3AFRNiBZHuhj", + "t2QBQMRiJKYjshJpE6RhbF7GLo51yE6d4wZ", + "t2F5RqnqguzZeiLtYHFx4yYfy6pDnut7tw5", + "t2CHvyZANE7XCtg8AhZnrcHCC7Ys1jJhK13", + "t2BRzpMdrGWZJ2upsaNQv6fSbkbTy7EitLo", + "t2BFixHGQMAWDY67LyTN514xRAB94iEjXp3", + "t2Uvz1iVPzBEWfQBH1p7NZJsFhD74tKaG8V", + "t2CmFDj5q6rJSRZeHf1SdrowinyMNcj438n", + "t2ErNvWEReTfPDBaNizjMPVssz66aVZh1hZ", + "t2GeJQ8wBUiHKDVzVM5ZtKfY5reCg7CnASs", + "t2L2eFtkKv1G6j55kLytKXTGuir4raAy3yr", + "t2EK2b87dpPazb7VvmEGc8iR6SJ289RywGL", + "t2DJ7RKeZJxdA4nZn8hRGXE8NUyTzjujph9", + "t2K1pXo4eByuWpKLkssyMLe8QKUbxnfFC3H", + "t2TB4mbSpuAcCWkH94Leb27FnRxo16AEHDg", + "t2Phx4gVL4YRnNsH3jM1M7jE4Fo329E66Na", + "t2VQZGmeNomN8c3USefeLL9nmU6M8x8CVzC", + "t2RicCvTVTY5y9JkreSRv3Xs8q2K67YxHLi", + "t2JrSLxTGc8wtPDe9hwbaeUjCrCfc4iZnDD", + "t2Uh9Au1PDDSw117sAbGivKREkmMxVC5tZo", + "t2FDwoJKLeEBMTy3oP7RLQ1Fihhvz49a3Bv", + "t2FY18mrgtb7QLeHA8ShnxLXuW8cNQ2n1v8", + "t2L15TkDYum7dnQRBqfvWdRe8Yw3jVy9z7g", + }; + + // ZF and MG use the same address for each funding period + std::vector zf_addresses(51, "t27eWDgjFYJGVXmzrXeVjnb5J3uXDM9xH9v"); + std::vector mg_addresses(51, "t2Gvxv2uNM7hbbACjNox4H6DjByoKZ2Fa3P"); + + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_BP, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2796000, + ecc_addresses); + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_ZF, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2796000, + zf_addresses); + consensus.AddZIP207FundingStream( + keyConstants, + Consensus::FS_ZIP214_MG, + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight, 2796000, + mg_addresses); + } + + // On testnet we activate this rule 6 blocks after Blossom activation. From block 299188 and + // prior to Blossom activation, the testnet minimum-difficulty threshold was 15 minutes (i.e. + // a minimum difficulty block can be mined if no block is mined normally within 15 minutes): + // + // However the median-time-past is 6 blocks behind, and the worst-case time for 7 blocks at a + // 15-minute spacing is ~105 minutes, which exceeds the limit imposed by the soft fork of + // 90 minutes. + // + // After Blossom, the minimum difficulty threshold time is changed to 6 times the block target + // spacing, which is 7.5 minutes: + // + // 7 times that is 52.5 minutes which is well within the limit imposed by the soft fork. + + static_assert(6 * Consensus::POST_BLOSSOM_POW_TARGET_SPACING * 7 < MAX_FUTURE_BLOCK_TIME_MTP - 60, + "MAX_FUTURE_BLOCK_TIME_MTP is too low given block target spacing"); + consensus.nFutureTimestampSoftForkHeight = consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight + 6; + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000000000000263c0984a2"); + + pchMessageStart[0] = 0xfa; + pchMessageStart[1] = 0x1a; + pchMessageStart[2] = 0xf9; + pchMessageStart[3] = 0xbf; + vAlertPubKey = ParseHex("044e7a1553392325c871c5ace5d6ad73501c66f4c185d6b0453cf45dec5a1322e705c672ac1a27ef7cdaf588c10effdf50ed5f95f85f2f54a5f6159fca394ed0c6"); + nDefaultPort = 18233; + nPruneAfterHeight = 1000; + + genesis = CreateGenesisBlock( + 1477648033, + uint256S("0x0000000000000000000000000000000000000000000000000000000000000006"), + ParseHex("00a6a51259c3f6732481e2d035197218b7a69504461d04335503cd69759b2d02bd2b53a9653f42cb33c608511c953673fa9da76170958115fe92157ad3bb5720d927f18e09459bf5c6072973e143e20f9bdf0584058c96b7c2234c7565f100d5eea083ba5d3dbaff9f0681799a113e7beff4a611d2b49590563109962baa149b628aae869af791f2f70bb041bd7ebfa658570917f6654a142b05e7ec0289a4f46470be7be5f693b90173eaaa6e84907170f32602204f1f4e1c04b1830116ffd0c54f0b1caa9a5698357bd8aa1f5ac8fc93b405265d824ba0e49f69dab5446653927298e6b7bdc61ee86ff31c07bde86331b4e500d42e4e50417e285502684b7966184505b885b42819a88469d1e9cf55072d7f3510f85580db689302eab377e4e11b14a91fdd0df7627efc048934f0aff8e7eb77eb17b3a95de13678004f2512293891d8baf8dde0ef69be520a58bbd6038ce899c9594cf3e30b8c3d9c7ecc832d4c19a6212747b50724e6f70f6451f78fd27b58ce43ca33b1641304a916186cfbe7dbca224f55d08530ba851e4df22baf7ab7078e9cbea46c0798b35a750f54103b0cdd08c81a6505c4932f6bfbd492a9fced31d54e98b6370d4c96600552fcf5b37780ed18c8787d03200963600db297a8f05dfa551321d17b9917edadcda51e274830749d133ad226f8bb6b94f13b4f77e67b35b71f52112ce9ba5da706ad9573584a2570a4ff25d29ab9761a06bdcf2c33638bf9baf2054825037881c14adf3816ba0cbd0fca689aad3ce16f2fe362c98f48134a9221765d939f0b49677d1c2447e56b46859f1810e2cf23e82a53e0d44f34dae932581b3b7f49eaec59af872cf9de757a964f7b33d143a36c270189508fcafe19398e4d2966948164d40556b05b7ff532f66f5d1edc41334ef742f78221dfe0c7ae2275bb3f24c89ae35f00afeea4e6ed187b866b209dc6e83b660593fce7c40e143beb07ac86c56f39e895385924667efe3a3f031938753c7764a2dbeb0a643fd359c46e614873fd0424e435fa7fac083b9a41a9d6bf7e284eee537ea7c50dd239f359941a43dc982745184bf3ee31a8dc850316aa9c6b66d6985acee814373be3458550659e1a06287c3b3b76a185c5cb93e38c1eebcf34ff072894b6430aed8d34122dafd925c46a515cca79b0269c92b301890ca6b0dc8b679cdac0f23318c105de73d7a46d16d2dad988d49c22e9963c117960bdc70ef0db6b091cf09445a516176b7f6d58ec29539166cc8a38bbff387acefffab2ea5faad0e8bb70625716ef0edf61940733c25993ea3de9f0be23d36e7cb8da10505f9dc426cd0e6e5b173ab4fff8c37e1f1fb56d1ea372013d075e0934c6919393cfc21395eea20718fad03542a4162a9ded66c814ad8320b2d7c2da3ecaf206da34c502db2096d1c46699a91dd1c432f019ad434e2c1ce507f91104f66f491fed37b225b8e0b2888c37276cfa0468fc13b8d593fd9a2675f0f5b20b8a15f8fa7558176a530d6865738ddb25d3426dab905221681cf9da0e0200eea5b2eba3ad3a5237d2a391f9074bf1779a2005cee43eec2b058511532635e0fea61664f531ac2b356f40db5c5d275a4cf5c82d468976455af4e3362cc8f71aa95e71d394aff3ead6f7101279f95bcd8a0fedce1d21cb3c9f6dd3b182fce0db5d6712981b651f29178a24119968b14783cafa713bc5f2a65205a42e4ce9dc7ba462bdb1f3e4553afc15f5f39998fdb53e7e231e3e520a46943734a007c2daa1eda9f495791657eefcac5c32833936e568d06187857ed04d7b97167ae207c5c5ae54e528c36016a984235e9c5b2f0718d7b3aa93c7822ccc772580b6599671b3c02ece8a21399abd33cfd3028790133167d0a97e7de53dc8ff"), + 0x2007ffff, 4, 0); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x05a60a92d99d85997cce3b87616c089f6124d7342af37106edc76126334a2c38")); + assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb")); + + vFixedSeeds.clear(); + vSeeds.clear(); + vSeeds.push_back(CDNSSeedData("z.cash", "dnsseed.testnet.z.cash")); // Zcash + vSeeds.push_back(CDNSSeedData("zfnd.org", "testnet.seeder.zfnd.org")); // Zcash Foundation + vSeeds.push_back(CDNSSeedData("yolo.money", "testnet.is.yolo.money")); // gtank + + vFixedSeeds = std::vector(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test)); + + fMiningRequiresPeers = true; + fDefaultConsistencyChecks = false; + fRequireStandard = true; + fMineBlocksOnDemand = false; + fTestnetToBeDeprecatedFieldRPC = true; + + + checkpointData = (CCheckpointData) { + boost::assign::map_list_of + (0, consensus.hashGenesisBlock) + (38000, uint256S("0x001e9a2d2e2892b88e9998cf7b079b41d59dd085423a921fe8386cecc42287b8")), + 1486897419, // * UNIX timestamp of last checkpoint block + 47163, // * total number of transactions between genesis and last checkpoint + 715 // total number of tx / (checkpoint block height / (24 * 24)) + }; + + // Hardcoded fallback value for the Sprout shielded value pool balance + // for nodes that have not reindexed since the introduction of monitoring + // in #2795. + nSproutValuePoolCheckpointHeight = 440329; + nSproutValuePoolCheckpointBalance = 40000029096803; + fZIP209Enabled = true; + hashSproutValuePoolCheckpointBlock = uint256S("000a95d08ba5dcbabe881fc6471d11807bcca7df5f1795c99f3ec4580db4279b"); + + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { + "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi", "t2N9PH9Wk9xjqYg9iin1Ua3aekJqfAtE543", "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2", "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy", + "t2BkYdVCHzvTJJUTx4yZB8qeegD8QsPx8bo", "t2J8q1xH1EuigJ52MfExyyjYtN3VgvshKDf", "t2Crq9mydTm37kZokC68HzT6yez3t2FBnFj", "t2EaMPUiQ1kthqcP5UEkF42CAFKJqXCkXC9", + "t2F9dtQc63JDDyrhnfpzvVYTJcr57MkqA12", "t2LPirmnfYSZc481GgZBa6xUGcoovfytBnC", "t26xfxoSw2UV9Pe5o3C8V4YybQD4SESfxtp", "t2D3k4fNdErd66YxtvXEdft9xuLoKD7CcVo", + "t2DWYBkxKNivdmsMiivNJzutaQGqmoRjRnL", "t2C3kFF9iQRxfc4B9zgbWo4dQLLqzqjpuGQ", "t2MnT5tzu9HSKcppRyUNwoTp8MUueuSGNaB", "t2AREsWdoW1F8EQYsScsjkgqobmgrkKeUkK", + "t2Vf4wKcJ3ZFtLj4jezUUKkwYR92BLHn5UT", "t2K3fdViH6R5tRuXLphKyoYXyZhyWGghDNY", "t2VEn3KiKyHSGyzd3nDw6ESWtaCQHwuv9WC", "t2F8XouqdNMq6zzEvxQXHV1TjwZRHwRg8gC", + "t2BS7Mrbaef3fA4xrmkvDisFVXVrRBnZ6Qj", "t2FuSwoLCdBVPwdZuYoHrEzxAb9qy4qjbnL", "t2SX3U8NtrT6gz5Db1AtQCSGjrpptr8JC6h", "t2V51gZNSoJ5kRL74bf9YTtbZuv8Fcqx2FH", + "t2FyTsLjjdm4jeVwir4xzj7FAkUidbr1b4R", "t2EYbGLekmpqHyn8UBF6kqpahrYm7D6N1Le", "t2NQTrStZHtJECNFT3dUBLYA9AErxPCmkka", "t2GSWZZJzoesYxfPTWXkFn5UaxjiYxGBU2a", + "t2RpffkzyLRevGM3w9aWdqMX6bd8uuAK3vn", "t2JzjoQqnuXtTGSN7k7yk5keURBGvYofh1d", "t2AEefc72ieTnsXKmgK2bZNckiwvZe3oPNL", "t2NNs3ZGZFsNj2wvmVd8BSwSfvETgiLrD8J", + "t2ECCQPVcxUCSSQopdNquguEPE14HsVfcUn", "t2JabDUkG8TaqVKYfqDJ3rqkVdHKp6hwXvG", "t2FGzW5Zdc8Cy98ZKmRygsVGi6oKcmYir9n", "t2DUD8a21FtEFn42oVLp5NGbogY13uyjy9t", + "t2UjVSd3zheHPgAkuX8WQW2CiC9xHQ8EvWp", "t2TBUAhELyHUn8i6SXYsXz5Lmy7kDzA1uT5", "t2Tz3uCyhP6eizUWDc3bGH7XUC9GQsEyQNc", "t2NysJSZtLwMLWEJ6MH3BsxRh6h27mNcsSy", + "t2KXJVVyyrjVxxSeazbY9ksGyft4qsXUNm9", "t2J9YYtH31cveiLZzjaE4AcuwVho6qjTNzp", "t2QgvW4sP9zaGpPMH1GRzy7cpydmuRfB4AZ", "t2NDTJP9MosKpyFPHJmfjc5pGCvAU58XGa4", + "t29pHDBWq7qN4EjwSEHg8wEqYe9pkmVrtRP", "t2Ez9KM8VJLuArcxuEkNRAkhNvidKkzXcjJ", "t2D5y7J5fpXajLbGrMBQkFg2mFN8fo3n8cX", "t2UV2wr1PTaUiybpkV3FdSdGxUJeZdZztyt", + }; + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight(0)); + } +}; +static CTestNetParams testNetParams; + +/** + * Regression test + */ +class CRegTestParams : public CChainParams { +public: + CRegTestParams() { + keyConstants.strNetworkID = "regtest"; + strCurrencyUnits = "REG"; + keyConstants.bip44CoinType = 1; + consensus.fCoinbaseMustBeShielded = false; + consensus.nSubsidySlowStartInterval = 0; + consensus.nPreBlossomSubsidyHalvingInterval = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL; + consensus.nPostBlossomSubsidyHalvingInterval = POST_BLOSSOM_HALVING_INTERVAL(Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL); + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + const size_t N = 48, K = 5; + static_assert(equihash_parameters_acceptable(N, K)); + consensus.nEquihashN = N; + consensus.nEquihashK = K; + consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); // if this is any larger, the for loop in GetNextWorkRequired can overflow bnTot + consensus.nPowAveragingWindow = 17; + assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); + consensus.nPowMaxAdjustDown = 0; // Turn off adjustment down + consensus.nPowMaxAdjustUp = 0; // Turn off adjustment up + consensus.nPreBlossomPowTargetSpacing = Consensus::PRE_BLOSSOM_POW_TARGET_SPACING; + consensus.nPostBlossomPowTargetSpacing = Consensus::POST_BLOSSOM_POW_TARGET_SPACING; + consensus.nPowAllowMinDifficultyBlocksAfterHeight = 0; + consensus.fPowNoRetargeting = true; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nProtocolVersion = 170006; + consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nProtocolVersion = 170008; + consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nProtocolVersion = 170010; + consensus.vUpgrades[Consensus::UPGRADE_HEARTWOOD].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nProtocolVersion = 170012; + consensus.vUpgrades[Consensus::UPGRADE_CANOPY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_NU5].nProtocolVersion = 170050; + consensus.vUpgrades[Consensus::UPGRADE_NU5].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nProtocolVersion = 0x7FFFFFFF; + consensus.vUpgrades[Consensus::UPGRADE_ZFUTURE].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + + consensus.nFundingPeriodLength = consensus.nPostBlossomSubsidyHalvingInterval / 48; + // Defined funding streams can be enabled with node config flags. + + // These prefixes are the same as the testnet prefixes + keyConstants.base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25}; + keyConstants.base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA}; + keyConstants.base58Prefixes[SECRET_KEY] = {0xEF}; + // do not rely on these BIP32 prefixes; they are not specified and may change + keyConstants.base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF}; + keyConstants.base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94}; + keyConstants.base58Prefixes[ZCPAYMENT_ADDRESS] = {0x16,0xB6}; + keyConstants.base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C}; + keyConstants.base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08}; + + keyConstants.bech32HRPs[SAPLING_PAYMENT_ADDRESS] = "zregtestsapling"; + keyConstants.bech32HRPs[SAPLING_FULL_VIEWING_KEY] = "zviewregtestsapling"; + keyConstants.bech32HRPs[SAPLING_INCOMING_VIEWING_KEY] = "zivkregtestsapling"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_SPEND_KEY] = "secret-extended-key-regtest"; + keyConstants.bech32HRPs[SAPLING_EXTENDED_FVK] = "zxviewregtestsapling"; + + // The best chain should have at least this much work. + consensus.nMinimumChainWork = uint256S("0x00"); + + pchMessageStart[0] = 0xaa; + pchMessageStart[1] = 0xe8; + pchMessageStart[2] = 0x3f; + pchMessageStart[3] = 0x5f; + nDefaultPort = 18344; + nPruneAfterHeight = 1000; + + genesis = CreateGenesisBlock( + 1296688602, + uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"), + ParseHex("01936b7db1eb4ac39f151b8704642d0a8bda13ec547d54cd5e43ba142fc6d8877cab07b3"), + 0x200f0f0f, 4, 0); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x029f11d80ef9765602235e1bc9727e3eb6ba20839319f761fee920d63401e327")); + assert(genesis.hashMerkleRoot == uint256S("0xc4eaa58879081de3c24a7b117ed2b28300e7ec4c4c1dff1d3f1268b7857a4ddb")); + + vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. + vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. + + fMiningRequiresPeers = false; + fDefaultConsistencyChecks = true; + fRequireStandard = false; + fMineBlocksOnDemand = true; + fTestnetToBeDeprecatedFieldRPC = false; + + checkpointData = (CCheckpointData){ + boost::assign::map_list_of + ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), + 0, + 0, + 0 + }; + + // Founders reward script expects a vector of 2-of-3 multisig addresses + vFoundersRewardAddress = { "t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg" }; + assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight(0)); + + // do not require the wallet backup to be confirmed in regtest mode + fRequireWalletBackup = false; + } + + void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) + { + assert(idx > Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES); + consensus.vUpgrades[idx].nActivationHeight = nActivationHeight; + } + + void UpdateFundingStreamParameters(Consensus::FundingStreamIndex idx, Consensus::FundingStream fs) + { + assert(idx >= Consensus::FIRST_FUNDING_STREAM && idx < Consensus::MAX_FUNDING_STREAMS); + consensus.vFundingStreams[idx] = fs; + } + + void UpdateRegtestPow( + int64_t nPowMaxAdjustDown, + int64_t nPowMaxAdjustUp, + uint256 powLimit, + bool noRetargeting) + { + consensus.nPowMaxAdjustDown = nPowMaxAdjustDown; + consensus.nPowMaxAdjustUp = nPowMaxAdjustUp; + consensus.powLimit = powLimit; + consensus.fPowNoRetargeting = noRetargeting; + } + + void SetRegTestZIP209Enabled() { + fZIP209Enabled = true; + } +}; +static CRegTestParams regTestParams; + +static CChainParams *pCurrentParams = 0; + +const CChainParams &Params() { + assert(pCurrentParams); + return *pCurrentParams; +} + +CChainParams& Params(const std::string& chain) +{ + if (chain == CBaseChainParams::MAIN) + return mainParams; + else if (chain == CBaseChainParams::TESTNET) + return testNetParams; + else if (chain == CBaseChainParams::REGTEST) + return regTestParams; + else + throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); +} + +void SelectParams(const std::string& network) +{ + SelectBaseParams(network); + pCurrentParams = &Params(network); + + // Some python qa rpc tests need to enforce the coinbase consensus rule + if (network == CBaseChainParams::REGTEST && mapArgs.count("-regtestshieldcoinbase")) { + regTestParams.SetRegTestCoinbaseMustBeShielded(); + } + + // When a developer is debugging turnstile violations in regtest mode, enable ZIP209 + if (network == CBaseChainParams::REGTEST && mapArgs.count("-developersetpoolsizezero")) { + regTestParams.SetRegTestZIP209Enabled(); + } +} + + +// Block height must be >0 and <=last founders reward block height +// Index variable i ranges from 0 - (vFoundersRewardAddress.size()-1) +std::string CChainParams::GetFoundersRewardAddressAtHeight(int nHeight) const { + int preBlossomMaxHeight = consensus.GetLastFoundersRewardBlockHeight(0); + // zip208 + // FounderAddressAdjustedHeight(height) := + // height, if not IsBlossomActivated(height) + // BlossomActivationHeight + floor((height - BlossomActivationHeight) / BlossomPoWTargetSpacingRatio), otherwise + bool blossomActive = consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM); + if (blossomActive) { + int blossomActivationHeight = consensus.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight; + nHeight = blossomActivationHeight + ((nHeight - blossomActivationHeight) / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO); + } + assert(nHeight > 0 && nHeight <= preBlossomMaxHeight); + size_t addressChangeInterval = (preBlossomMaxHeight + vFoundersRewardAddress.size()) / vFoundersRewardAddress.size(); + size_t i = nHeight / addressChangeInterval; + return vFoundersRewardAddress[i]; +} + +// Block height must be >0 and <=last founders reward block height +// The founders reward address is expected to be a multisig (P2SH) address +CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const { + assert(nHeight > 0 && nHeight <= consensus.GetLastFoundersRewardBlockHeight(nHeight)); + + KeyIO keyIO(*this); + auto address = keyIO.DecodePaymentAddress(GetFoundersRewardAddressAtHeight(nHeight).c_str()); + assert(address.has_value()); + assert(std::holds_alternative(address.value())); + CScriptID scriptID = std::get(address.value()); + CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; + return script; +} + +std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const { + assert(i >= 0 && i < vFoundersRewardAddress.size()); + return vFoundersRewardAddress[i]; +} + +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) +{ + regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight); +} + +void UpdateFundingStreamParameters(Consensus::FundingStreamIndex idx, Consensus::FundingStream fs) +{ + regTestParams.UpdateFundingStreamParameters(idx, fs); +} + +void UpdateRegtestPow( + int64_t nPowMaxAdjustDown, + int64_t nPowMaxAdjustUp, + uint256 powLimit, + bool noRetargeting) +{ + regTestParams.UpdateRegtestPow(nPowMaxAdjustDown, nPowMaxAdjustUp, powLimit, noRetargeting); +} diff --git a/depend/zcash/src/chainparams.h b/depend/zcash/src/chainparams.h new file mode 100644 index 000000000..4b04ac967 --- /dev/null +++ b/depend/zcash/src/chainparams.h @@ -0,0 +1,154 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CHAINPARAMS_H +#define BITCOIN_CHAINPARAMS_H + +#include "chainparamsbase.h" +#include "consensus/params.h" +#include "primitives/block.h" +#include "protocol.h" + +#include + +struct CDNSSeedData { + std::string name, host; + CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {} +}; + +struct SeedSpec6 { + uint8_t addr[16]; + uint16_t port; +}; + +typedef std::map MapCheckpoints; + +struct CCheckpointData { + MapCheckpoints mapCheckpoints; + int64_t nTimeLastCheckpoint; + int64_t nTransactionsLastCheckpoint; + double fTransactionsPerDay; +}; + +/** + * CChainParams defines various tweakable parameters of a given instance of the + * Bitcoin system. There are three: the main network on which people trade goods + * and services, the public test network which gets reset from time to time and + * a regression test mode which is intended for private networks only. It has + * minimal difficulty to ensure that blocks can be found instantly. + */ +class CChainParams: public KeyConstants +{ +public: + const Consensus::Params& GetConsensus() const { return consensus; } + const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } + const std::vector& AlertKey() const { return vAlertPubKey; } + int GetDefaultPort() const { return nDefaultPort; } + + CAmount SproutValuePoolCheckpointHeight() const { return nSproutValuePoolCheckpointHeight; } + CAmount SproutValuePoolCheckpointBalance() const { return nSproutValuePoolCheckpointBalance; } + uint256 SproutValuePoolCheckpointBlockHash() const { return hashSproutValuePoolCheckpointBlock; } + bool ZIP209Enabled() const { return fZIP209Enabled; } + bool RequireWalletBackup() const { return fRequireWalletBackup; } + + const CBlock& GenesisBlock() const { return genesis; } + /** Make miner wait to have peers to avoid wasting work */ + bool MiningRequiresPeers() const { return fMiningRequiresPeers; } + /** Default value for -checkmempool and -checkblockindex argument */ + bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } + /** Policy: Filter transactions that do not match well-defined patterns */ + bool RequireStandard() const { return fRequireStandard; } + int64_t PruneAfterHeight() const { return nPruneAfterHeight; } + std::string CurrencyUnits() const { return strCurrencyUnits; } + /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ + bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } + /** In the future use NetworkIDString() for RPC fields */ + bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } + const std::vector& DNSSeeds() const { return vSeeds; } + /** Return the BIP70 network string (main, test or regtest) */ + std::string NetworkIDString() const { + return keyConstants.NetworkIDString(); + } + /** Return the BIP44 coin type for addresses created by the zcashd embedded wallet. */ + uint32_t BIP44CoinType() const { + return keyConstants.BIP44CoinType(); + } + const std::vector& Base58Prefix(Base58Type type) const { + return keyConstants.Base58Prefix(type); + } + const std::string& Bech32HRP(Bech32Type type) const { + return keyConstants.Bech32HRP(type); + } + const std::vector& FixedSeeds() const { return vFixedSeeds; } + const CCheckpointData& Checkpoints() const { return checkpointData; } + /** Return the founder's reward address and script for a given block height */ + std::string GetFoundersRewardAddressAtHeight(int height) const; + CScript GetFoundersRewardScriptAtHeight(int height) const; + std::string GetFoundersRewardAddressAtIndex(int i) const; + /** Enforce coinbase consensus rule in regtest mode */ + void SetRegTestCoinbaseMustBeShielded() { consensus.fCoinbaseMustBeShielded = true; } +protected: + CChainParams() {} + + Consensus::Params consensus; + CMessageHeader::MessageStartChars pchMessageStart; + //! Raw pub key bytes for the broadcast alert signing key. + std::vector vAlertPubKey; + int nDefaultPort = 0; + uint64_t nPruneAfterHeight = 0; + std::vector vSeeds; + CBaseKeyConstants keyConstants; + std::string strCurrencyUnits; + CBlock genesis; + std::vector vFixedSeeds; + bool fMiningRequiresPeers = false; + bool fDefaultConsistencyChecks = false; + bool fRequireStandard = false; + bool fMineBlocksOnDemand = false; + bool fTestnetToBeDeprecatedFieldRPC = false; + CCheckpointData checkpointData; + std::vector vFoundersRewardAddress; + + CAmount nSproutValuePoolCheckpointHeight = 0; + CAmount nSproutValuePoolCheckpointBalance = 0; + uint256 hashSproutValuePoolCheckpointBlock; + bool fZIP209Enabled = false; + bool fRequireWalletBackup = true; +}; + +/** + * Return the currently selected parameters. This won't change after app + * startup, except for unit tests. + */ +const CChainParams &Params(); + +/** + * @returns CChainParams for the given BIP70 chain name. + */ +CChainParams& Params(const std::string& chain); + +/** + * Sets the params returned by Params() to those for the given BIP70 chain name. + * @throws std::runtime_error when the chain is not supported. + */ +void SelectParams(const std::string& chain); + +/** + * Allows modifying the network upgrade regtest parameters. + */ +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); + +void UpdateRegtestPow( + int64_t nPowMaxAdjustDown, + int64_t nPowMaxAdjustUp, + uint256 powLimit, + bool noRetargeting); + +/** + * Allows modifying the regtest funding stream parameters. + */ +void UpdateFundingStreamParameters(Consensus::FundingStreamIndex idx, Consensus::FundingStream fs); + +#endif // BITCOIN_CHAINPARAMS_H diff --git a/depend/zcash/src/chainparamsbase.cpp b/depend/zcash/src/chainparamsbase.cpp new file mode 100644 index 000000000..7f1860c65 --- /dev/null +++ b/depend/zcash/src/chainparamsbase.cpp @@ -0,0 +1,118 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#include "chainparamsbase.h" + +#include "tinyformat.h" +#include "util.h" + +#include + +const std::string CBaseChainParams::MAIN = "main"; +const std::string CBaseChainParams::TESTNET = "test"; +const std::string CBaseChainParams::REGTEST = "regtest"; + +void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp) +{ + strUsage += HelpMessageGroup(_("Chain selection options:")); + strUsage += HelpMessageOpt("-testnet", _("Use the test chain")); + if (debugHelp) { + strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. " + "This is intended for regression testing tools and app development."); + } +} + +/** + * Main network + */ +class CBaseMainParams : public CBaseChainParams +{ +public: + CBaseMainParams() + { + nRPCPort = 8232; + } +}; +static CBaseMainParams mainParams; + +/** + * Testnet (v3) + */ +class CBaseTestNetParams : public CBaseChainParams +{ +public: + CBaseTestNetParams() + { + nRPCPort = 18232; + strDataDir = "testnet3"; + } +}; +static CBaseTestNetParams testNetParams; + +/* + * Regression test + */ +class CBaseRegTestParams : public CBaseChainParams +{ +public: + CBaseRegTestParams() + { + nRPCPort = 18232; + strDataDir = "regtest"; + } +}; +static CBaseRegTestParams regTestParams; + +/* + * Unit test + */ +class CBaseUnitTestParams : public CBaseMainParams +{ +public: + CBaseUnitTestParams() + { + strDataDir = "unittest"; + } +}; +static CBaseUnitTestParams unitTestParams; + +static CBaseChainParams* pCurrentBaseParams = 0; + +const CBaseChainParams& BaseParams() +{ + assert(pCurrentBaseParams); + return *pCurrentBaseParams; +} + +void SelectBaseParams(const std::string& chain) +{ + if (chain == CBaseChainParams::MAIN) + pCurrentBaseParams = &mainParams; + else if (chain == CBaseChainParams::TESTNET) + pCurrentBaseParams = &testNetParams; + else if (chain == CBaseChainParams::REGTEST) + pCurrentBaseParams = ®TestParams; + else + throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); +} + +std::string ChainNameFromCommandLine() +{ + bool fRegTest = GetBoolArg("-regtest", false); + bool fTestNet = GetBoolArg("-testnet", false); + + if (fTestNet && fRegTest) + throw std::runtime_error("Invalid combination of -regtest and -testnet."); + if (fRegTest) + return CBaseChainParams::REGTEST; + if (fTestNet) + return CBaseChainParams::TESTNET; + return CBaseChainParams::MAIN; +} + +bool AreBaseParamsConfigured() +{ + return pCurrentBaseParams != NULL; +} diff --git a/depend/zcash/src/chainparamsbase.h b/depend/zcash/src/chainparamsbase.h new file mode 100644 index 000000000..5d2526fca --- /dev/null +++ b/depend/zcash/src/chainparamsbase.h @@ -0,0 +1,60 @@ +// Copyright (c) 2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CHAINPARAMSBASE_H +#define BITCOIN_CHAINPARAMSBASE_H + +#include +#include + +/** + * CBaseChainParams defines the base parameters (shared between bitcoin-cli and bitcoind) + * of a given instance of the Bitcoin system. + */ +class CBaseChainParams +{ +public: + /** BIP70 chain name strings (main, test or regtest) */ + static const std::string MAIN; + static const std::string TESTNET; + static const std::string REGTEST; + + const std::string& DataDir() const { return strDataDir; } + int RPCPort() const { return nRPCPort; } + +protected: + CBaseChainParams() {} + + int nRPCPort = 0; + std::string strDataDir; +}; + +/** + * Append the help messages for the chainparams options to the + * parameter string. + */ +void AppendParamsHelpMessages(std::string& strUsage, bool debugHelp=true); + +/** + * Return the currently selected parameters. This won't change after app + * startup, except for unit tests. + */ +const CBaseChainParams& BaseParams(); + +/** Sets the params returned by Params() to those for the given network. */ +void SelectBaseParams(const std::string& chain); + +/** + * Looks for -regtest, -testnet and returns the appropriate BIP70 chain name. + * @return CBaseChainParams::MAX_NETWORK_TYPES if an invalid combination is given. CBaseChainParams::MAIN by default. + */ +std::string ChainNameFromCommandLine(); + +/** + * Return true if SelectBaseParamsFromCommandLine() has been called to select + * a network. + */ +bool AreBaseParamsConfigured(); + +#endif // BITCOIN_CHAINPARAMSBASE_H diff --git a/depend/zcash/src/chainparamsseeds.h b/depend/zcash/src/chainparamsseeds.h new file mode 100644 index 000000000..1139441fd --- /dev/null +++ b/depend/zcash/src/chainparamsseeds.h @@ -0,0 +1,15 @@ +#ifndef BITCOIN_CHAINPARAMSSEEDS_H +#define BITCOIN_CHAINPARAMSSEEDS_H +/** + * List of fixed seed nodes for the bitcoin network + * AUTOGENERATED by contrib/seeds/generate-seeds.py + * + * Each line contains a 16-byte IPv6 address and a port. + * IPv4 as well as onion addresses are wrapped inside a IPv6 address accordingly. + */ +static SeedSpec6 pnSeed6_main[] = { +}; + +static SeedSpec6 pnSeed6_test[] = { +}; +#endif // BITCOIN_CHAINPARAMSSEEDS_H diff --git a/depend/zcash/src/checkpoints.cpp b/depend/zcash/src/checkpoints.cpp new file mode 100644 index 000000000..1d3f1fabb --- /dev/null +++ b/depend/zcash/src/checkpoints.cpp @@ -0,0 +1,89 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "checkpoints.h" + +#include "chainparams.h" +#include "main.h" +#include "reverse_iterator.h" +#include "uint256.h" + +#include + + +namespace Checkpoints { + + /** + * How many times slower we expect checking transactions after the last + * checkpoint to be (from checking signatures, which is skipped up to the + * last checkpoint). This number is a compromise, as it can't be accurate + * for every system. When reindexing from a fast disk with a slow CPU, it + * can be up to 20, while when downloading from a slow network with a + * fast multicore CPU, it won't be much higher than 1. + */ + static const double SIGCHECK_VERIFICATION_FACTOR = 5.0; + + //! Guess how far we are in the verification process at the given block index + double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) { + if (pindex==NULL) + return 0.0; + + int64_t nNow = time(NULL); + + double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0; + double fWorkBefore = 0.0; // Amount of work done before pindex + double fWorkAfter = 0.0; // Amount of work left after pindex (estimated) + // Work is defined as: 1.0 per transaction before the last checkpoint, and + // fSigcheckVerificationFactor per transaction after. + + if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) { + double nCheapBefore = pindex->nChainTx; + double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx; + double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay; + fWorkBefore = nCheapBefore; + fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor; + } else { + double nCheapBefore = data.nTransactionsLastCheckpoint; + double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint; + double nExpensiveAfter = (nNow - pindex->GetBlockTime())/86400.0*data.fTransactionsPerDay; + fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor; + fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor; + } + + return std::min(fWorkBefore / (fWorkBefore + fWorkAfter), 1.0); + } + + int GetTotalBlocksEstimate(const CCheckpointData& data) + { + const MapCheckpoints& checkpoints = data.mapCheckpoints; + + if (checkpoints.empty()) + return 0; + + return checkpoints.rbegin()->first; + } + + CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) + { + const MapCheckpoints& checkpoints = data.mapCheckpoints; + + for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints)) + { + const uint256& hash = i.second; + BlockMap::const_iterator t = mapBlockIndex.find(hash); + if (t != mapBlockIndex.end()) + return t->second; + } + return NULL; + } + + bool IsAncestorOfLastCheckpoint(const CCheckpointData& data, const CBlockIndex* pindex) + { + CBlockIndex *pindexLastCheckpoint = GetLastCheckpoint(data); + return pindexLastCheckpoint && pindexLastCheckpoint->GetAncestor(pindex->nHeight) == pindex; + } + + + +} // namespace Checkpoints diff --git a/depend/zcash/src/checkpoints.h b/depend/zcash/src/checkpoints.h new file mode 100644 index 000000000..b62b43280 --- /dev/null +++ b/depend/zcash/src/checkpoints.h @@ -0,0 +1,33 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CHECKPOINTS_H +#define BITCOIN_CHECKPOINTS_H + +#include "uint256.h" + +#include + +class CBlockIndex; +struct CCheckpointData; + +/** + * Block-chain checkpoints are compiled-in sanity checks. + * They are updated every release or three. + */ +namespace Checkpoints +{ + +//! Return conservative estimate of total number of blocks, 0 if unknown +int GetTotalBlocksEstimate(const CCheckpointData& data); + +//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint +CBlockIndex* GetLastCheckpoint(const CCheckpointData& data); + +double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); + +bool IsAncestorOfLastCheckpoint(const CCheckpointData& data, const CBlockIndex* pindex); +} //namespace Checkpoints + +#endif // BITCOIN_CHECKPOINTS_H diff --git a/depend/zcash/src/checkqueue.h b/depend/zcash/src/checkqueue.h new file mode 100644 index 000000000..d6476e8ca --- /dev/null +++ b/depend/zcash/src/checkqueue.h @@ -0,0 +1,218 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CHECKQUEUE_H +#define BITCOIN_CHECKQUEUE_H + +#include +#include + +#include +#include +#include + +#include "sync.h" + +template +class CCheckQueueControl; + +/** + * Queue for verifications that have to be performed. + * The verifications are represented by a type T, which must provide an + * operator(), returning a bool. + * + * One thread (the master) is assumed to push batches of verifications + * onto the queue, where they are processed by N-1 worker threads. When + * the master is done adding work, it temporarily joins the worker pool + * as an N'th worker, until all jobs are done. + */ +template +class CCheckQueue +{ +private: + //! Mutex to protect the inner state + boost::mutex mutex; + + //! Worker threads block on this when out of work + boost::condition_variable condWorker; + + //! Master thread blocks on this when out of work + boost::condition_variable condMaster; + + //! The queue of elements to be processed. + //! As the order of booleans doesn't matter, it is used as a LIFO (stack) + std::vector queue; + + //! The number of workers (including the master) that are idle. + int nIdle; + + //! The total number of workers (including the master). + int nTotal; + + //! The temporary evaluation result. + bool fAllOk; + + /** + * Number of verifications that haven't completed yet. + * This includes elements that are no longer queued, but still in the + * worker's own batches. + */ + unsigned int nTodo; + + //! Whether we're shutting down. + bool fQuit; + + //! The maximum number of elements to be processed in one batch + unsigned int nBatchSize; + + /** Internal function that does bulk of the verification work. */ + bool Loop(bool fMaster = false) + { + boost::condition_variable& cond = fMaster ? condMaster : condWorker; + std::vector vChecks; + vChecks.reserve(nBatchSize); + unsigned int nNow = 0; + bool fOk = true; + do { + { + boost::unique_lock lock(mutex); + // first do the clean-up of the previous loop run (allowing us to do it in the same critsect) + if (nNow) { + fAllOk &= fOk; + nTodo -= nNow; + if (nTodo == 0 && !fMaster) + // We processed the last element; inform the master it can exit and return the result + condMaster.notify_one(); + } else { + // first iteration + nTotal++; + } + // logically, the do loop starts here + while (queue.empty()) { + if ((fMaster || fQuit) && nTodo == 0) { + nTotal--; + bool fRet = fAllOk; + // reset the status for new work later + if (fMaster) + fAllOk = true; + // return the current status + return fRet; + } + nIdle++; + cond.wait(lock); // wait + nIdle--; + } + // Decide how many work units to process now. + // * Do not try to do everything at once, but aim for increasingly smaller batches so + // all workers finish approximately simultaneously. + // * Try to account for idle jobs which will instantly start helping. + // * Don't do batches smaller than 1 (duh), or larger than nBatchSize. + nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1))); + vChecks.resize(nNow); + for (unsigned int i = 0; i < nNow; i++) { + // We want the lock on the mutex to be as short as possible, so swap jobs from the global + // queue to the local batch vector instead of copying. + vChecks[i].swap(queue.back()); + queue.pop_back(); + } + // Check whether we need to do work at all + fOk = fAllOk; + } + // execute work + for (T& check : vChecks) + if (fOk) + fOk = check(); + vChecks.clear(); + } while (true); + } + +public: + //! Mutex to ensure only one concurrent CCheckQueueControl + boost::mutex ControlMutex; + + //! Create a new check queue + CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} + + //! Worker thread + void Thread() + { + Loop(); + } + + //! Wait until execution finishes, and return whether all evaluations were successful. + bool Wait() + { + return Loop(true); + } + + //! Add a batch of checks to the queue + void Add(std::vector& vChecks) + { + boost::unique_lock lock(mutex); + for (T& check : vChecks) { + queue.push_back(T()); + check.swap(queue.back()); + } + nTodo += vChecks.size(); + if (vChecks.size() == 1) + condWorker.notify_one(); + else if (vChecks.size() > 1) + condWorker.notify_all(); + } + + ~CCheckQueue() + { + } + +}; + +/** + * RAII-style controller object for a CCheckQueue that guarantees the passed + * queue is finished before continuing. + */ +template +class CCheckQueueControl +{ +private: + CCheckQueue * const pqueue; + bool fDone; + +public: + CCheckQueueControl() = delete; + CCheckQueueControl(const CCheckQueueControl&) = delete; + CCheckQueueControl& operator=(const CCheckQueueControl&) = delete; + explicit CCheckQueueControl(CCheckQueue * const pqueueIn) : pqueue(pqueueIn), fDone(false) + { + // passed queue is supposed to be unused, or NULL + if (pqueue != NULL) { + ENTER_CRITICAL_SECTION(pqueue->ControlMutex); + } + } + + bool Wait() + { + if (pqueue == NULL) + return true; + bool fRet = pqueue->Wait(); + fDone = true; + return fRet; + } + + void Add(std::vector& vChecks) + { + if (pqueue != NULL) + pqueue->Add(vChecks); + } + + ~CCheckQueueControl() + { + if (!fDone) + Wait(); + if (pqueue != NULL) { + LEAVE_CRITICAL_SECTION(pqueue->ControlMutex); + } + } +}; + +#endif // BITCOIN_CHECKQUEUE_H diff --git a/depend/zcash/src/clientversion.cpp b/depend/zcash/src/clientversion.cpp new file mode 100644 index 000000000..ef8961ea5 --- /dev/null +++ b/depend/zcash/src/clientversion.cpp @@ -0,0 +1,138 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "clientversion.h" + +#include "tinyformat.h" + +#include + +#include +#include +#include +#include +#include + +/** + * Name of client reported in the 'version' message. Report the same name + * for both bitcoind and bitcoin-core, to make it harder for attackers to + * target servers or GUI users specifically. + */ +const std::string CLIENT_NAME("MagicBean"); + +/** + * Client version number + */ +#define CLIENT_VERSION_SUFFIX "" + + +/** + * The following part of the code determines the CLIENT_BUILD variable. + * Several mechanisms are used for this: + * * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is + * generated by the build environment, possibly containing the output + * of git-describe in a macro called BUILD_DESC + * * secondly, if this is an exported version of the code, GIT_ARCHIVE will + * be defined (automatically using the export-subst git attribute), and + * GIT_COMMIT will contain the commit id. + * * then, three options exist for determining CLIENT_BUILD: + * * if BUILD_DESC is defined, use that literally (output of git-describe) + * * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit] + * * otherwise, use v[maj].[min].[rev].[build]-unk + * finally CLIENT_VERSION_SUFFIX is added + */ + +//! First, include build.h if requested +#ifdef HAVE_BUILD_INFO +#include "build.h" +#endif + +//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$ +#ifdef GIT_ARCHIVE +#define GIT_COMMIT_ID "$Format:%h$" +#define GIT_COMMIT_DATE "$Format:%cD$" +#endif + +#define RENDER_BETA_STRING(num) "-beta" DO_STRINGIZE(num) +#define RENDER_RC_STRING(num) "-rc" DO_STRINGIZE(num) +#define RENDER_DEV_STRING(num) "-" DO_STRINGIZE(num) + +#define RENDER_BUILD(build) \ + BOOST_PP_IF( \ + BOOST_PP_LESS(build, 25), \ + RENDER_BETA_STRING(BOOST_PP_ADD(build, 1)), \ + BOOST_PP_IF( \ + BOOST_PP_LESS(build, 50), \ + RENDER_RC_STRING(BOOST_PP_SUB(build, 24)), \ + BOOST_PP_IF( \ + BOOST_PP_EQUAL(build, 50), \ + "", \ + RENDER_DEV_STRING(BOOST_PP_SUB(build, 50))))) + +#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) RENDER_BUILD(build) "-" DO_STRINGIZE(suffix) + +#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) RENDER_BUILD(build) "-g" commit + +#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \ + "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) RENDER_BUILD(build) "-unk" + +#ifndef BUILD_DESC +#ifdef BUILD_SUFFIX +#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX) +#elif defined(GIT_COMMIT_ID) +#define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID) +#else +#define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD) +#endif +#endif + +#ifndef BUILD_DATE +#ifdef GIT_COMMIT_DATE +#define BUILD_DATE GIT_COMMIT_DATE +#else +#define BUILD_DATE __DATE__ ", " __TIME__ +#endif +#endif + +const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); +const std::string CLIENT_DATE(BUILD_DATE); + +std::string FormatVersion(int nVersion) +{ + if (nVersion % 100 < 25) + return strprintf("%d.%d.%d-beta%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, (nVersion % 100)+1); + if (nVersion % 100 < 50) + return strprintf("%d.%d.%d-rc%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, (nVersion % 100)-24); + else if (nVersion % 100 == 50) + return strprintf("%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100); + else + return strprintf("%d.%d.%d-%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, (nVersion % 100)-50); +} + +std::string FormatFullVersion() +{ + return CLIENT_BUILD; +} + +/** + * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) + */ +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) +{ + std::ostringstream ss; + ss << "/"; + ss << name << ":" << FormatVersion(nClientVersion); + if (!comments.empty()) + { + std::vector::const_iterator it(comments.begin()); + ss << "(" << *it; + for(++it; it != comments.end(); ++it) + ss << "; " << *it; + ss << ")"; + } + ss << "/"; + return ss.str(); +} diff --git a/depend/zcash/src/clientversion.h b/depend/zcash/src/clientversion.h new file mode 100644 index 000000000..8c436b625 --- /dev/null +++ b/depend/zcash/src/clientversion.h @@ -0,0 +1,72 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2016-2022 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CLIENTVERSION_H +#define BITCOIN_CLIENTVERSION_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#else + +/** + * client versioning and copyright year + */ + +//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it +#define CLIENT_VERSION_MAJOR 5 +#define CLIENT_VERSION_MINOR 0 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 50 + +//! Set to true for release, false for prerelease or test build +#define CLIENT_VERSION_IS_RELEASE true + +/** + * Copyright year (2009-this) + * Todo: update this when changing our copyright comments in the source + */ +#define COPYRIGHT_YEAR 2022 + +#endif //HAVE_CONFIG_H + +/** + * Converts the parameter X to a string after macro replacement on X has been performed. + * Don't merge these into one macro! + */ +#define STRINGIZE(X) DO_STRINGIZE(X) +#define DO_STRINGIZE(X) #X + +//! Copyright string used in Windows .rc files +#define COPYRIGHT_STR "2009-" STRINGIZE(COPYRIGHT_YEAR) " The Bitcoin Core Developers and The Zcash developers" + +/** + * bitcoind-res.rc includes this file, but it cannot cope with real c++ code. + * WINDRES_PREPROC is defined to indicate that its pre-processor is running. + * Anything other than a define should be guarded below. + */ + +#if !defined(WINDRES_PREPROC) + +#include +#include + +static const int CLIENT_VERSION = + 1000000 * CLIENT_VERSION_MAJOR + + 10000 * CLIENT_VERSION_MINOR + + 100 * CLIENT_VERSION_REVISION + + 1 * CLIENT_VERSION_BUILD; + +extern const std::string CLIENT_NAME; +extern const std::string CLIENT_BUILD; +extern const std::string CLIENT_DATE; + + +std::string FormatVersion(int nVersion); +std::string FormatFullVersion(); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); + +#endif // WINDRES_PREPROC + +#endif // BITCOIN_CLIENTVERSION_H diff --git a/depend/zcash/src/coincontrol.h b/depend/zcash/src/coincontrol.h new file mode 100644 index 000000000..1adc84757 --- /dev/null +++ b/depend/zcash/src/coincontrol.h @@ -0,0 +1,68 @@ +// Copyright (c) 2011-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COINCONTROL_H +#define BITCOIN_COINCONTROL_H + +#include "primitives/transaction.h" + +/** Coin Control Features. */ +class CCoinControl +{ +public: + CTxDestination destChange; + //! If false, allows unselected inputs, but requires all selected inputs be used + bool fAllowOtherInputs; + //! Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria + bool fAllowWatchOnly; + + CCoinControl() + { + SetNull(); + } + + void SetNull() + { + destChange = CNoDestination(); + fAllowOtherInputs = false; + fAllowWatchOnly = false; + setSelected.clear(); + } + + bool HasSelected() const + { + return (setSelected.size() > 0); + } + + bool IsSelected(const uint256& hash, unsigned int n) const + { + COutPoint outpt(hash, n); + return (setSelected.count(outpt) > 0); + } + + void Select(const COutPoint& output) + { + setSelected.insert(output); + } + + void UnSelect(const COutPoint& output) + { + setSelected.erase(output); + } + + void UnSelectAll() + { + setSelected.clear(); + } + + void ListSelected(std::vector& vOutpoints) const + { + vOutpoints.assign(setSelected.begin(), setSelected.end()); + } + +private: + std::set setSelected; +}; + +#endif // BITCOIN_COINCONTROL_H diff --git a/depend/zcash/src/coins.cpp b/depend/zcash/src/coins.cpp new file mode 100644 index 000000000..eae717c7b --- /dev/null +++ b/depend/zcash/src/coins.cpp @@ -0,0 +1,1158 @@ +// Copyright (c) 2012-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "coins.h" + +#include "memusage.h" +#include "random.h" +#include "version.h" +#include "policy/fees.h" + +#include + +#include + +/** + * calculate number of bytes for the bitmask, and its number of non-zero bytes + * each bit in the bitmask represents the availability of one output, but the + * availabilities of the first two outputs are encoded separately + */ +void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const { + unsigned int nLastUsedByte = 0; + for (unsigned int b = 0; 2+b*8 < vout.size(); b++) { + bool fZero = true; + for (unsigned int i = 0; i < 8 && 2+b*8+i < vout.size(); i++) { + if (!vout[2+b*8+i].IsNull()) { + fZero = false; + continue; + } + } + if (!fZero) { + nLastUsedByte = b + 1; + nNonzeroBytes++; + } + } + nBytes += nLastUsedByte; +} + +bool CCoins::Spend(uint32_t nPos) +{ + if (nPos >= vout.size() || vout[nPos].IsNull()) + return false; + vout[nPos].SetNull(); + 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::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &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; } +bool CCoinsView::HaveCoins(const uint256 &txid) const { return false; } +uint256 CCoinsView::GetBestBlock() const { return uint256(); } +uint256 CCoinsView::GetBestAnchor(ShieldedType type) const { return uint256(); }; +HistoryIndex CCoinsView::GetHistoryLength(uint32_t epochId) const { return 0; } +HistoryNode CCoinsView::GetHistoryAt(uint32_t epochId, HistoryIndex index) const { return HistoryNode(); } +uint256 CCoinsView::GetHistoryRoot(uint32_t epochId) const { return uint256(); } + +bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + const uint256 &hashOrchardAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMap) { return false; } +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::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { return base->GetOrchardAnchorAt(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); } +bool CCoinsViewBacked::HaveCoins(const uint256 &txid) const { return base->HaveCoins(txid); } +uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); } +uint256 CCoinsViewBacked::GetBestAnchor(ShieldedType type) const { return base->GetBestAnchor(type); } +HistoryIndex CCoinsViewBacked::GetHistoryLength(uint32_t epochId) const { return base->GetHistoryLength(epochId); } +HistoryNode CCoinsViewBacked::GetHistoryAt(uint32_t epochId, HistoryIndex index) const { return base->GetHistoryAt(epochId, index); } +uint256 CCoinsViewBacked::GetHistoryRoot(uint32_t epochId) const { return base->GetHistoryRoot(epochId); } +void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } +bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + const uint256 &hashOrchardAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMap) { + return base->BatchWrite(mapCoins, hashBlock, + hashSproutAnchor, hashSaplingAnchor, hashOrchardAnchor, + mapSproutAnchors, mapSaplingAnchors, mapOrchardAnchors, + mapSproutNullifiers, mapSaplingNullifiers, mapOrchardNullifiers, + historyCacheMap); +} +bool CCoinsViewBacked::GetStats(CCoinsStats &stats) const { return base->GetStats(stats); } + +SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits::max())), k1(GetRand(std::numeric_limits::max())) {} + +CCoinsViewCache::CCoinsViewCache(CCoinsView *baseIn) : CCoinsViewBacked(baseIn), hasModifier(false), cachedCoinsUsage(0) { } + +CCoinsViewCache::~CCoinsViewCache() +{ + assert(!hasModifier); +} + +size_t CCoinsViewCache::DynamicMemoryUsage() const { + return memusage::DynamicUsage(cacheCoins) + + memusage::DynamicUsage(cacheSproutAnchors) + + memusage::DynamicUsage(cacheSaplingAnchors) + + memusage::DynamicUsage(cacheOrchardAnchors) + + memusage::DynamicUsage(cacheSproutNullifiers) + + memusage::DynamicUsage(cacheSaplingNullifiers) + + memusage::DynamicUsage(cacheOrchardNullifiers) + + memusage::DynamicUsage(historyCacheMap) + + cachedCoinsUsage; +} + +CCoinsMap::const_iterator CCoinsViewCache::FetchCoins(const uint256 &txid) const { + CCoinsMap::iterator it = cacheCoins.find(txid); + if (it != cacheCoins.end()) + return it; + CCoins tmp; + if (!base->GetCoins(txid, tmp)) + return cacheCoins.end(); + CCoinsMap::iterator ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())).first; + tmp.swap(ret->second.coins); + if (ret->second.coins.IsPruned()) { + // The parent only has an empty entry for this txid; we can consider our + // version as fresh. + ret->second.flags = CCoinsCacheEntry::FRESH; + } + cachedCoinsUsage += ret->second.coins.DynamicMemoryUsage(); + 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()) { + if (it->second.entered) { + tree = it->second.tree; + return true; + } else { + return false; + } + } + + if (!base->GetSaplingAnchorAt(rt, tree)) { + return false; + } + + CAnchorsSaplingMap::iterator ret = cacheSaplingAnchors.insert(std::make_pair(rt, CAnchorsSaplingCacheEntry())).first; + ret->second.entered = true; + ret->second.tree = tree; + cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); + + return true; +} + +bool CCoinsViewCache::GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const { + CAnchorsOrchardMap::const_iterator it = cacheOrchardAnchors.find(rt); + if (it != cacheOrchardAnchors.end()) { + if (it->second.entered) { + tree = it->second.tree; + return true; + } else { + return false; + } + } + + if (!base->GetOrchardAnchorAt(rt, tree)) { + return false; + } + + CAnchorsOrchardMap::iterator ret = cacheOrchardAnchors.insert(std::make_pair(rt, CAnchorsOrchardCacheEntry())).first; + ret->second.entered = true; + ret->second.tree = tree; + cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); + + return true; +} + +bool CCoinsViewCache::GetNullifier(const uint256 &nullifier, ShieldedType type) const { + CNullifiersMap* cacheToUse; + switch (type) { + case SPROUT: + cacheToUse = &cacheSproutNullifiers; + break; + case SAPLING: + cacheToUse = &cacheSaplingNullifiers; + break; + case ORCHARD: + cacheToUse = &cacheOrchardNullifiers; + break; + default: + throw std::runtime_error("Unknown shielded type"); + } + CNullifiersMap::iterator it = cacheToUse->find(nullifier); + if (it != cacheToUse->end()) + return it->second.entered; + + CNullifiersCacheEntry entry; + bool tmp = base->GetNullifier(nullifier, type); + entry.entered = tmp; + + cacheToUse->insert(std::make_pair(nullifier, entry)); + + return tmp; +} + +HistoryIndex CCoinsViewCache::GetHistoryLength(uint32_t epochId) const { + HistoryCache& historyCache = SelectHistoryCache(epochId); + return historyCache.length; +} + +HistoryNode CCoinsViewCache::GetHistoryAt(uint32_t epochId, HistoryIndex index) const { + HistoryCache& historyCache = SelectHistoryCache(epochId); + + if (index >= historyCache.length) { + // Caller should ensure that it is limiting history + // request to 0..GetHistoryLength(epochId)-1 range + throw std::runtime_error("Invalid history request"); + } + + if (index >= historyCache.updateDepth) { + return historyCache.appends[index]; + } + + return base->GetHistoryAt(epochId, index); +} + +uint256 CCoinsViewCache::GetHistoryRoot(uint32_t epochId) const { + return SelectHistoryCache(epochId).root; +} + +template +void CCoinsViewCache::AbstractPushAnchor( + const Tree &tree, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash +) +{ + uint256 newrt = tree.root(); + + auto currentRoot = GetBestAnchor(type); + + // We don't want to overwrite an anchor we already have. + // This occurs when a block doesn't modify mapAnchors at all, + // because there are no joinsplits. We could get around this a + // different way (make all blocks modify mapAnchors somehow) + // but this is simpler to reason about. + if (currentRoot != newrt) { + auto insertRet = cacheAnchors.insert(std::make_pair(newrt, CacheEntry())); + CacheIterator ret = insertRet.first; + + ret->second.entered = true; + ret->second.tree = tree; + ret->second.flags = CacheEntry::DIRTY; + + if (insertRet.second) { + // An insert took place + cachedCoinsUsage += ret->second.tree.DynamicMemoryUsage(); + } + + hash = newrt; + } +} + +template<> void CCoinsViewCache::PushAnchor(const SproutMerkleTree &tree) +{ + AbstractPushAnchor( + tree, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); +} + +template<> void CCoinsViewCache::PushAnchor(const SaplingMerkleTree &tree) +{ + AbstractPushAnchor( + tree, + SAPLING, + cacheSaplingAnchors, + hashSaplingAnchor + ); +} + +template<> void CCoinsViewCache::PushAnchor(const OrchardMerkleFrontier &tree) +{ + AbstractPushAnchor( + tree, + ORCHARD, + cacheOrchardAnchors, + hashOrchardAnchor + ); +} + +template<> +void CCoinsViewCache::BringBestAnchorIntoCache( + const uint256 ¤tRoot, + SproutMerkleTree &tree +) +{ + assert(GetSproutAnchorAt(currentRoot, tree)); +} + +template<> +void CCoinsViewCache::BringBestAnchorIntoCache( + const uint256 ¤tRoot, + SaplingMerkleTree &tree +) +{ + assert(GetSaplingAnchorAt(currentRoot, tree)); +} + +template<> +void CCoinsViewCache::BringBestAnchorIntoCache( + const uint256 ¤tRoot, + OrchardMerkleFrontier &tree +) +{ + assert(GetOrchardAnchorAt(currentRoot, tree)); +} + +void draftMMRNode(std::vector &indices, + std::vector &entries, + HistoryNode nodeData, + uint32_t alt, + uint32_t peak_pos) +{ + HistoryEntry newEntry = alt == 0 + ? libzcash::LeafToEntry(nodeData) + // peak_pos - (1 << alt) is the array position of left child. + // peak_pos - 1 is the array position of right child. + : libzcash::NodeToEntry(nodeData, peak_pos - (1 << alt), peak_pos - 1); + + indices.push_back(peak_pos); + entries.push_back(newEntry); +} + +// Computes floor(log2(x)). +static inline uint32_t floor_log2(uint32_t x) { + assert(x > 0); + int log = 0; + while (x >>= 1) { ++log; } + return log; +} + +// Computes the altitude of the largest subtree for an MMR with n nodes, +// which is floor(log2(n + 1)) - 1. +static inline uint32_t altitude(uint32_t n) { + return floor_log2(n + 1) - 1; +} + +uint32_t CCoinsViewCache::PreloadHistoryTree(uint32_t epochId, bool extra, std::vector &entries, std::vector &entry_indices) { + auto treeLength = GetHistoryLength(epochId); + + if (treeLength <= 0) { + throw std::runtime_error("Invalid PreloadHistoryTree state called - tree should exist"); + } else if (treeLength == 1) { + entries.push_back(libzcash::LeafToEntry(GetHistoryAt(epochId, 0))); + entry_indices.push_back(0); + return 1; + } + + uint32_t last_peak_pos = 0; + uint32_t last_peak_alt = 0; + uint32_t alt = 0; + uint32_t peak_pos = 0; + uint32_t total_peaks = 0; + + // Assume the following example peak layout with 14 leaves, and 25 stored nodes in + // total (the "tree length"): + // + // P + // /\ + // / \ + // / \ \ + // / \ \ Altitude + // _A_ \ \ 3 + // _/ \_ B \ 2 + // / \ / \ / \ C 1 + // /\ /\ /\ /\ /\ /\ /\ 0 + // + // We start by determining the altitude of the highest peak (A). + alt = altitude(treeLength); + + // We determine the position of the highest peak (A) by pretending it is the right + // sibling in a tree, and its left-most leaf has position 0. Then the left sibling + // of (A) has position -1, and so we can "jump" to the peak's position by computing + // -1 + 2^(alt + 1) - 1. + peak_pos = (1 << (alt + 1)) - 2; + + // Now that we have the position and altitude of the highest peak (A), we collect + // the remaining peaks (B, C). We navigate the peaks as if they were nodes in this + // Merkle tree (with additional imaginary nodes 1 and 2, that have positions beyond + // the MMR's length): + // + // / \ + // / \ + // / \ + // / \ + // A ==========> 1 + // / \ // \ + // _/ \_ B ==> 2 + // /\ /\ /\ // + // / \ / \ / \ C + // /\ /\ /\ /\ /\ /\ /\ + // + while (alt != 0) { + // If peak_pos is out of bounds of the tree, we compute the position of its left + // child, and drop down one level in the tree. + if (peak_pos >= treeLength) { + // left child, -2^alt + peak_pos = peak_pos - (1 << alt); + alt = alt - 1; + } + + // If the peak exists, we take it and then continue with its right sibling. + if (peak_pos < treeLength) { + draftMMRNode(entry_indices, entries, GetHistoryAt(epochId, peak_pos), alt, peak_pos); + + last_peak_pos = peak_pos; + last_peak_alt = alt; + + // right sibling + peak_pos = peak_pos + (1 << (alt + 1)) - 1; + } + } + + total_peaks = entries.size(); + + // Return early if we don't require extra nodes. + if (!extra) return total_peaks; + + alt = last_peak_alt; + peak_pos = last_peak_pos; + + + // P + // /\ + // / \ + // / \ \ + // / \ \ + // _A_ \ \ + // _/ \_ B \ + // / \ / \ / \ C + // /\ /\ /\ /\ /\ /\ /\ + // D E + // + // For extra peaks needed for deletion, we do extra pass on right slope of the last peak + // and add those nodes + their siblings. Extra would be (D, E) for the picture above. + while (alt > 0) { + uint32_t left_pos = peak_pos - (1 << alt); + uint32_t right_pos = peak_pos - 1; + alt = alt - 1; + + // drafting left child + draftMMRNode(entry_indices, entries, GetHistoryAt(epochId, left_pos), alt, left_pos); + + // drafting right child + draftMMRNode(entry_indices, entries, GetHistoryAt(epochId, right_pos), alt, right_pos); + + // continuing on right slope + peak_pos = right_pos; + } + + return total_peaks; +} + +HistoryCache& CCoinsViewCache::SelectHistoryCache(uint32_t epochId) const { + auto entry = historyCacheMap.find(epochId); + + if (entry != historyCacheMap.end()) { + return entry->second; + } else { + auto cache = HistoryCache( + base->GetHistoryLength(epochId), + base->GetHistoryRoot(epochId), + epochId + ); + return historyCacheMap.insert({epochId, cache}).first->second; + } +} + +void CCoinsViewCache::PushHistoryNode(uint32_t epochId, const HistoryNode node) { + HistoryCache& historyCache = SelectHistoryCache(epochId); + + if (historyCache.length == 0) { + // special case, it just goes into the cache right away + historyCache.Extend(node); + + if (librustzcash_mmr_hash_node(epochId, &node, historyCache.root.begin()) != 0) { + throw std::runtime_error("hashing node failed"); + }; + + return; + } + + std::vector entries; + std::vector entry_indices; + + PreloadHistoryTree(epochId, false, entries, entry_indices); + + uint256 newRoot; + std::array appendBuf = {}; + + uint32_t appends = librustzcash_mmr_append( + epochId, + historyCache.length, + entry_indices.data(), + entries.data(), + entry_indices.size(), + &node, + newRoot.begin(), + appendBuf.data() + ); + + for (size_t i = 0; i < appends; i++) { + historyCache.Extend(appendBuf[i]); + } + + historyCache.root = newRoot; +} + +void CCoinsViewCache::PopHistoryNode(uint32_t epochId) { + HistoryCache& historyCache = SelectHistoryCache(epochId); + uint256 newRoot; + + switch (historyCache.length) { + case 0: + { + // Caller is generally not expected to pop from empty tree! Caller + // should switch to previous epoch and pop history from there. + + // If we are doing an expected rollback that changes the consensus + // branch ID for some upgrade (or introduces one that wasn't present + // at the equivalent height) this will occur because + // `SelectHistoryCache` selects the tree for the new consensus + // branch ID, not the one that existed on the chain being rolled + // back. + + // Sensible action is to truncate the history cache: + } + case 1: + { + // Just resetting tree to empty + historyCache.Truncate(0); + historyCache.root = uint256(); + return; + } + case 2: + { + // - A tree with one leaf has length 1. + // - A tree with two leaves has length 3. + throw std::runtime_error("a history tree cannot have two nodes"); + } + case 3: + { + const HistoryNode tmpHistoryRoot = GetHistoryAt(epochId, 0); + // After removing a leaf from a tree with two leaves, we are left + // with a single-node tree, whose root is just the hash of that + // node. + if (librustzcash_mmr_hash_node( + epochId, + &tmpHistoryRoot, + newRoot.begin() + ) != 0) { + throw std::runtime_error("hashing node failed"); + } + historyCache.Truncate(1); + historyCache.root = newRoot; + return; + } + default: + { + // This is a non-elementary pop, so use the full tree logic. + std::vector entries; + std::vector entry_indices; + + uint32_t peak_count = PreloadHistoryTree(epochId, true, entries, entry_indices); + + uint32_t numberOfDeletes = librustzcash_mmr_delete( + epochId, + historyCache.length, + entry_indices.data(), + entries.data(), + peak_count, + entries.size() - peak_count, + newRoot.begin() + ); + + historyCache.Truncate(historyCache.length - numberOfDeletes); + historyCache.root = newRoot; + return; + } + } +} + +template +void CCoinsViewCache::AbstractPopAnchor( + const uint256 &newrt, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash +) +{ + auto currentRoot = GetBestAnchor(type); + + // Blocks might not change the commitment tree, in which + // case restoring the "old" anchor during a reorg must + // have no effect. + if (currentRoot != newrt) { + // Bring the current best anchor into our local cache + // so that its tree exists in memory. + { + Tree tree; + BringBestAnchorIntoCache(currentRoot, tree); + } + + // Mark the anchor as unentered, removing it from view + cacheAnchors[currentRoot].entered = false; + + // Mark the cache entry as dirty so it's propagated + cacheAnchors[currentRoot].flags = CacheEntry::DIRTY; + + // Mark the new root as the best anchor + hash = newrt; + } +} + +void CCoinsViewCache::PopAnchor(const uint256 &newrt, ShieldedType type) { + switch (type) { + case SPROUT: + AbstractPopAnchor( + newrt, + SPROUT, + cacheSproutAnchors, + hashSproutAnchor + ); + break; + case SAPLING: + AbstractPopAnchor( + newrt, + SAPLING, + cacheSaplingAnchors, + hashSaplingAnchor + ); + break; + case ORCHARD: + AbstractPopAnchor( + newrt, + ORCHARD, + cacheOrchardAnchors, + hashOrchardAnchor + ); + break; + default: + throw std::runtime_error("Unknown shielded type"); + } +} + +void CCoinsViewCache::SetNullifiers(const CTransaction& tx, bool spent) { + for (const JSDescription &joinsplit : tx.vJoinSplit) { + for (const uint256 &nullifier : joinsplit.nullifiers) { + std::pair ret = cacheSproutNullifiers.insert(std::make_pair(nullifier, CNullifiersCacheEntry())); + ret.first->second.entered = spent; + ret.first->second.flags |= CNullifiersCacheEntry::DIRTY; + } + } + for (const SpendDescription &spendDescription : tx.vShieldedSpend) { + std::pair ret = cacheSaplingNullifiers.insert(std::make_pair(spendDescription.nullifier, CNullifiersCacheEntry())); + ret.first->second.entered = spent; + ret.first->second.flags |= CNullifiersCacheEntry::DIRTY; + } + for (const uint256& nf : tx.GetOrchardBundle().GetNullifiers()) { + std::pair ret = cacheOrchardNullifiers.insert(std::make_pair(nf, CNullifiersCacheEntry())); + ret.first->second.entered = spent; + ret.first->second.flags |= CNullifiersCacheEntry::DIRTY; + } +} + +bool CCoinsViewCache::GetCoins(const uint256 &txid, CCoins &coins) const { + CCoinsMap::const_iterator it = FetchCoins(txid); + if (it != cacheCoins.end()) { + coins = it->second.coins; + return true; + } + return false; +} + +CCoinsModifier CCoinsViewCache::ModifyCoins(const uint256 &txid) { + assert(!hasModifier); + std::pair ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); + size_t cachedCoinUsage = 0; + if (ret.second) { + if (!base->GetCoins(txid, ret.first->second.coins)) { + // The parent view does not have this entry; mark it as fresh. + ret.first->second.coins.Clear(); + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } else if (ret.first->second.coins.IsPruned()) { + // The parent view only has a pruned entry for this; mark it as fresh. + ret.first->second.flags = CCoinsCacheEntry::FRESH; + } + } else { + cachedCoinUsage = ret.first->second.coins.DynamicMemoryUsage(); + } + // Assume that whenever ModifyCoins is called, the entry will be modified. + ret.first->second.flags |= CCoinsCacheEntry::DIRTY; + return CCoinsModifier(*this, ret.first, cachedCoinUsage); +} + +CCoinsModifier CCoinsViewCache::ModifyNewCoins(const uint256 &txid) { + assert(!hasModifier); + std::pair ret = cacheCoins.insert(std::make_pair(txid, CCoinsCacheEntry())); + ret.first->second.coins.Clear(); + ret.first->second.flags = CCoinsCacheEntry::FRESH; + ret.first->second.flags |= CCoinsCacheEntry::DIRTY; + return CCoinsModifier(*this, ret.first, 0); +} + +const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { + CCoinsMap::const_iterator it = FetchCoins(txid); + if (it == cacheCoins.end()) { + return NULL; + } else { + return &it->second.coins; + } +} + +bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { + CCoinsMap::const_iterator it = FetchCoins(txid); + // We're using vtx.empty() instead of IsPruned here for performance reasons, + // as we only care about the case where a transaction was replaced entirely + // in a reorganization (which wipes vout entirely, as opposed to spending + // which just cleans individual outputs). + return (it != cacheCoins.end() && !it->second.coins.vout.empty()); +} + +uint256 CCoinsViewCache::GetBestBlock() const { + if (hashBlock.IsNull()) + hashBlock = base->GetBestBlock(); + return hashBlock; +} + + +uint256 CCoinsViewCache::GetBestAnchor(ShieldedType type) const { + switch (type) { + case SPROUT: + if (hashSproutAnchor.IsNull()) + hashSproutAnchor = base->GetBestAnchor(type); + return hashSproutAnchor; + break; + case SAPLING: + if (hashSaplingAnchor.IsNull()) + hashSaplingAnchor = base->GetBestAnchor(type); + return hashSaplingAnchor; + break; + case ORCHARD: + if (hashOrchardAnchor.IsNull()) + hashOrchardAnchor = base->GetBestAnchor(type); + return hashOrchardAnchor; + break; + default: + throw std::runtime_error("Unknown shielded type"); + } +} + +void CCoinsViewCache::SetBestBlock(const uint256 &hashBlockIn) { + hashBlock = hashBlockIn; +} + +void BatchWriteNullifiers(CNullifiersMap &mapNullifiers, CNullifiersMap &cacheNullifiers) +{ + 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); + + if (parent_it == cacheNullifiers.end()) { + CNullifiersCacheEntry& entry = cacheNullifiers[child_it->first]; + entry.entered = child_it->second.entered; + entry.flags = CNullifiersCacheEntry::DIRTY; + } else { + if (parent_it->second.entered != child_it->second.entered) { + parent_it->second.entered = child_it->second.entered; + parent_it->second.flags |= CNullifiersCacheEntry::DIRTY; + } + } + } + child_it = mapNullifiers.erase(child_it); + } +} + +template +void BatchWriteAnchors( + Map &mapAnchors, + Map &cacheAnchors, + size_t &cachedCoinsUsage +) +{ + for (MapIterator child_it = mapAnchors.begin(); child_it != mapAnchors.end();) + { + if (child_it->second.flags & MapEntry::DIRTY) { + MapIterator parent_it = cacheAnchors.find(child_it->first); + + if (parent_it == cacheAnchors.end()) { + MapEntry& entry = cacheAnchors[child_it->first]; + entry.entered = child_it->second.entered; + entry.tree = child_it->second.tree; + entry.flags = MapEntry::DIRTY; + + cachedCoinsUsage += entry.tree.DynamicMemoryUsage(); + } else { + if (parent_it->second.entered != child_it->second.entered) { + // The parent may have removed the entry. + parent_it->second.entered = child_it->second.entered; + parent_it->second.flags |= MapEntry::DIRTY; + } + } + } + + child_it = mapAnchors.erase(child_it); + } +} + +void BatchWriteHistory(CHistoryCacheMap& historyCacheMap, CHistoryCacheMap& historyCacheMapIn) { + for (auto nextHistoryCache = historyCacheMapIn.begin(); nextHistoryCache != historyCacheMapIn.end(); nextHistoryCache++) { + auto historyCacheIn = nextHistoryCache->second; + auto epochId = nextHistoryCache->first; + + auto historyCache = historyCacheMap.find(epochId); + if (historyCache != historyCacheMap.end()) { + // delete old entries since updateDepth + historyCache->second.Truncate(historyCacheIn.updateDepth); + + // Replace/append new/updated entries. HistoryCache.Extend + // auto-indexes the nodes, so we need to extend in the same order as + // this cache is indexed. + for (size_t i = historyCacheIn.updateDepth; i < historyCacheIn.length; i++) { + historyCache->second.Extend(historyCacheIn.appends[i]); + } + + // the lengths should now match + assert(historyCache->second.length == historyCacheIn.length); + + // write current root + historyCache->second.root = historyCacheIn.root; + } else { + // Just insert the history cache into its parent + historyCacheMap.insert({epochId, historyCacheIn}); + } + } +} + +bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlockIn, + const uint256 &hashSproutAnchorIn, + const uint256 &hashSaplingAnchorIn, + const uint256 &hashOrchardAnchorIn, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMapIn) { + assert(!hasModifier); + for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) { + if (it->second.flags & CCoinsCacheEntry::DIRTY) { // Ignore non-dirty entries (optimization). + CCoinsMap::iterator itUs = cacheCoins.find(it->first); + if (itUs == cacheCoins.end()) { + if (!it->second.coins.IsPruned()) { + // The parent cache does not have an entry, while the child + // cache does have (a non-pruned) one. Move the data up, and + // mark it as fresh (if the grandparent did have it, we + // would have pulled it in at first GetCoins). + assert(it->second.flags & CCoinsCacheEntry::FRESH); + CCoinsCacheEntry& entry = cacheCoins[it->first]; + entry.coins.swap(it->second.coins); + cachedCoinsUsage += entry.coins.DynamicMemoryUsage(); + entry.flags = CCoinsCacheEntry::DIRTY | CCoinsCacheEntry::FRESH; + } + } else { + if ((itUs->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { + // The grandparent does not have an entry, and the child is + // modified and being pruned. This means we can just delete + // it from the parent. + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); + cacheCoins.erase(itUs); + } else { + // A normal modification. + cachedCoinsUsage -= itUs->second.coins.DynamicMemoryUsage(); + itUs->second.coins.swap(it->second.coins); + cachedCoinsUsage += itUs->second.coins.DynamicMemoryUsage(); + itUs->second.flags |= CCoinsCacheEntry::DIRTY; + } + } + } + it = mapCoins.erase(it); + } + + ::BatchWriteAnchors(mapSproutAnchors, cacheSproutAnchors, cachedCoinsUsage); + ::BatchWriteAnchors(mapSaplingAnchors, cacheSaplingAnchors, cachedCoinsUsage); + ::BatchWriteAnchors(mapOrchardAnchors, cacheOrchardAnchors, cachedCoinsUsage); + + ::BatchWriteNullifiers(mapSproutNullifiers, cacheSproutNullifiers); + ::BatchWriteNullifiers(mapSaplingNullifiers, cacheSaplingNullifiers); + ::BatchWriteNullifiers(mapOrchardNullifiers, cacheOrchardNullifiers); + + ::BatchWriteHistory(historyCacheMap, historyCacheMapIn); + + hashSproutAnchor = hashSproutAnchorIn; + hashSaplingAnchor = hashSaplingAnchorIn; + hashOrchardAnchor = hashOrchardAnchorIn; + hashBlock = hashBlockIn; + return true; +} + +bool CCoinsViewCache::Flush() { + bool fOk = base->BatchWrite(cacheCoins, + hashBlock, + hashSproutAnchor, + hashSaplingAnchor, + hashOrchardAnchor, + cacheSproutAnchors, + cacheSaplingAnchors, + cacheOrchardAnchors, + cacheSproutNullifiers, + cacheSaplingNullifiers, + cacheOrchardNullifiers, + historyCacheMap); + cacheCoins.clear(); + cacheSproutAnchors.clear(); + cacheSaplingAnchors.clear(); + cacheOrchardAnchors.clear(); + cacheSproutNullifiers.clear(); + cacheSaplingNullifiers.clear(); + cacheOrchardNullifiers.clear(); + historyCacheMap.clear(); + cachedCoinsUsage = 0; + return fOk; +} + +unsigned int CCoinsViewCache::GetCacheSize() const { + return cacheCoins.size(); +} + +const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const +{ + const CCoins* coins = AccessCoins(input.prevout.hash); + assert(coins && coins->IsAvailable(input.prevout.n)); + return coins->vout[input.prevout.n]; +} + +CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const +{ + if (tx.IsCoinBase()) + return 0; + + CAmount nResult = 0; + for (unsigned int i = 0; i < tx.vin.size(); i++) + nResult += GetOutputFor(tx.vin[i]).nValue; + + nResult += tx.GetShieldedValueIn(); + + return nResult; +} + +std::optional CCoinsViewCache::HaveShieldedRequirements(const CTransaction& tx) const +{ + boost::unordered_map intermediates; + + for (const JSDescription &joinsplit : tx.vJoinSplit) + { + for (const uint256& nullifier : joinsplit.nullifiers) + { + if (GetNullifier(nullifier, SPROUT)) { + // If the nullifier is set, this transaction + // double-spends! + auto txid = tx.GetHash().ToString(); + auto nf = nullifier.ToString(); + TracingWarn("consensus", "Sprout double-spend detected", + "txid", txid.c_str(), + "nf", nf.c_str()); + return UnsatisfiedShieldedReq::SproutDuplicateNullifier; + } + } + + SproutMerkleTree tree; + auto it = intermediates.find(joinsplit.anchor); + if (it != intermediates.end()) { + tree = it->second; + } else if (!GetSproutAnchorAt(joinsplit.anchor, tree)) { + auto txid = tx.GetHash().ToString(); + auto anchor = joinsplit.anchor.ToString(); + TracingWarn("consensus", "Transaction uses unknown Sprout anchor", + "txid", txid.c_str(), + "anchor", anchor.c_str()); + return UnsatisfiedShieldedReq::SproutUnknownAnchor; + } + + for (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 + auto txid = tx.GetHash().ToString(); + auto nf = spendDescription.nullifier.ToString(); + TracingWarn("consensus", "Sapling double-spend detected", + "txid", txid.c_str(), + "nf", nf.c_str()); + return UnsatisfiedShieldedReq::SaplingDuplicateNullifier; + } + + SaplingMerkleTree tree; + if (!GetSaplingAnchorAt(spendDescription.anchor, tree)) { + auto txid = tx.GetHash().ToString(); + auto anchor = spendDescription.anchor.ToString(); + TracingWarn("consensus", "Transaction uses unknown Sapling anchor", + "txid", txid.c_str(), + "anchor", anchor.c_str()); + return UnsatisfiedShieldedReq::SaplingUnknownAnchor; + } + } + + for (const uint256 &nullifier : tx.GetOrchardBundle().GetNullifiers()) { + if (GetNullifier(nullifier, ORCHARD)) { // Prevent double spends + auto txid = tx.GetHash().ToString(); + auto nf = nullifier.ToString(); + TracingWarn("consensus", "Orchard double-spend detected", + "txid", txid.c_str(), + "nf", nf.c_str()); + return UnsatisfiedShieldedReq::OrchardDuplicateNullifier; + } + } + + std::optional root = tx.GetOrchardBundle().GetAnchor(); + if (root) { + OrchardMerkleFrontier tree; + if (!GetOrchardAnchorAt(root.value(), tree)) { + auto txid = tx.GetHash().ToString(); + auto anchor = root.value().ToString(); + TracingWarn("consensus", "Transaction uses unknown Orchard anchor", + "txid", txid.c_str(), + "anchor", anchor.c_str()); + return UnsatisfiedShieldedReq::OrchardUnknownAnchor; + } + } + + return std::nullopt; +} + +bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const +{ + if (!tx.IsCoinBase()) { + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const COutPoint &prevout = tx.vin[i].prevout; + const CCoins* coins = AccessCoins(prevout.hash); + if (!coins || !coins->IsAvailable(prevout.n)) { + return false; + } + } + } + return true; +} + +double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const +{ + if (tx.IsCoinBase()) + return 0.0; + + // Shielded transfers do not reveal any information about the value or age of a note, so we + // cannot apply the priority algorithm used for transparent utxos. Instead, we just + // use the maximum priority for all (partially or fully) shielded transactions. + // (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.) + + if (tx.vJoinSplit.size() > 0 || + tx.vShieldedSpend.size() > 0 || + tx.vShieldedOutput.size() > 0 || + tx.GetOrchardBundle().IsPresent()) + { + return MAX_PRIORITY; + } + + // FIXME: this logic is partially duplicated between here and CreateNewBlock in miner.cpp. + double dResult = 0.0; + for (const CTxIn& txin : tx.vin) + { + const CCoins* coins = AccessCoins(txin.prevout.hash); + assert(coins); + if (!coins->IsAvailable(txin.prevout.n)) continue; + if (coins->nHeight < nHeight) { + dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); + } + } + + return tx.ComputePriority(dResult); +} + +CCoinsModifier::CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage) : cache(cache_), it(it_), cachedCoinUsage(usage) { + assert(!cache.hasModifier); + cache.hasModifier = true; +} + +CCoinsModifier::~CCoinsModifier() +{ + assert(cache.hasModifier); + cache.hasModifier = false; + it->second.coins.Cleanup(); + cache.cachedCoinsUsage -= cachedCoinUsage; // Subtract the old usage + if ((it->second.flags & CCoinsCacheEntry::FRESH) && it->second.coins.IsPruned()) { + cache.cacheCoins.erase(it); + } else { + // If the coin still exists after the modification, add the new usage + cache.cachedCoinsUsage += it->second.coins.DynamicMemoryUsage(); + } +} diff --git a/depend/zcash/src/coins.h b/depend/zcash/src/coins.h new file mode 100644 index 000000000..c318d65d3 --- /dev/null +++ b/depend/zcash/src/coins.h @@ -0,0 +1,672 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COINS_H +#define BITCOIN_COINS_H + +#include "compressor.h" +#include "core_memusage.h" +#include "hash.h" +#include "memusage.h" +#include "serialize.h" +#include "uint256.h" + +#include +#include + +#include +#include "zcash/History.hpp" +#include "zcash/IncrementalMerkleTree.hpp" + +/** + * Pruned version of CTransaction: only retains metadata and unspent transaction outputs + * + * Serialized format: + * - VARINT(nVersion) + * - VARINT(nCode) + * - unspentness bitvector, for vout[2] and further; least significant byte first + * - the non-spent CTxOuts (via CTxOutCompressor) + * - VARINT(nHeight) + * + * The nCode value consists of: + * - bit 1: IsCoinBase() + * - bit 2: vout[0] is not spent + * - bit 4: vout[1] is not spent + * - The higher bits encode N, the number of non-zero bytes in the following bitvector. + * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at + * least one non-spent output). + * + * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e + * <><><--------------------------------------------><----> + * | \ | / + * version code vout[1] height + * + * - version = 1 + * - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow) + * - unspentness bitvector: as 0 non-zero bytes follow, it has length 0 + * - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35 + * * 8358: compact amount representation for 60000000000 (600 BTC) + * * 00: special txout type pay-to-pubkey-hash + * * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160 + * - height = 203998 + * + * + * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b + * <><><--><--------------------------------------------------><----------------------------------------------><----> + * / \ \ | | / + * version code unspentness vout[4] vout[16] height + * + * - version = 1 + * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent, + * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow) + * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent + * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee + * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC) + * * 00: special txout type pay-to-pubkey-hash + * * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160 + * - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4 + * * bbd123: compact amount representation for 110397 (0.001 BTC) + * * 00: special txout type pay-to-pubkey-hash + * * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160 + * - height = 120891 + */ +class CCoins +{ +public: + //! whether transaction is a coinbase + bool fCoinBase; + + //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped + std::vector vout; + + //! at which height this transaction was included in the active block chain + int nHeight; + + //! version of the CTransaction; accesses to this value should probably check for nHeight as well, + //! as new tx version will probably only be introduced at certain heights + int nVersion; + + void FromTx(const CTransaction &tx, int nHeightIn) { + fCoinBase = tx.IsCoinBase(); + vout = tx.vout; + nHeight = nHeightIn; + nVersion = tx.nVersion; + ClearUnspendable(); + } + + //! construct a CCoins from a CTransaction, at a given height + CCoins(const CTransaction &tx, int nHeightIn) { + FromTx(tx, nHeightIn); + } + + void Clear() { + fCoinBase = false; + std::vector().swap(vout); + nHeight = 0; + nVersion = 0; + } + + //! empty constructor + CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { } + + //!remove spent outputs at the end of vout + void Cleanup() { + while (vout.size() > 0 && vout.back().IsNull()) + vout.pop_back(); + if (vout.empty()) + std::vector().swap(vout); + } + + void ClearUnspendable() { + for (CTxOut &txout : vout) { + if (txout.scriptPubKey.IsUnspendable()) + txout.SetNull(); + } + Cleanup(); + } + + void swap(CCoins &to) { + std::swap(to.fCoinBase, fCoinBase); + to.vout.swap(vout); + std::swap(to.nHeight, nHeight); + std::swap(to.nVersion, nVersion); + } + + //! equality test + friend bool operator==(const CCoins &a, const CCoins &b) { + // Empty CCoins objects are always equal. + if (a.IsPruned() && b.IsPruned()) + return true; + return a.fCoinBase == b.fCoinBase && + a.nHeight == b.nHeight && + a.nVersion == b.nVersion && + a.vout == b.vout; + } + friend bool operator!=(const CCoins &a, const CCoins &b) { + return !(a == b); + } + + void CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const; + + bool IsCoinBase() const { + return fCoinBase; + } + + template + void Serialize(Stream &s) const { + unsigned int nMaskSize = 0, nMaskCode = 0; + CalcMaskSize(nMaskSize, nMaskCode); + bool fFirst = vout.size() > 0 && !vout[0].IsNull(); + bool fSecond = vout.size() > 1 && !vout[1].IsNull(); + assert(fFirst || fSecond || nMaskCode); + unsigned int nCode = 8*(nMaskCode - (fFirst || fSecond ? 0 : 1)) + (fCoinBase ? 1 : 0) + (fFirst ? 2 : 0) + (fSecond ? 4 : 0); + // version + ::Serialize(s, VARINT(this->nVersion)); + // header code + ::Serialize(s, VARINT(nCode)); + // spentness bitmask + for (unsigned int b = 0; b + void Unserialize(Stream &s) { + unsigned int nCode = 0; + // version + ::Unserialize(s, VARINT(this->nVersion)); + // header code + ::Unserialize(s, VARINT(nCode)); + fCoinBase = nCode & 1; + std::vector vAvail(2, false); + vAvail[0] = (nCode & 2) != 0; + vAvail[1] = (nCode & 4) != 0; + unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1); + // spentness bitmask + while (nMaskCode > 0) { + unsigned char chAvail = 0; + ::Unserialize(s, chAvail); + for (unsigned int p = 0; p < 8; p++) { + bool f = (chAvail & (1 << p)) != 0; + vAvail.push_back(f); + } + if (chAvail != 0) + nMaskCode--; + } + // txouts themself + vout.assign(vAvail.size(), CTxOut()); + for (unsigned int i = 0; i < vAvail.size(); i++) { + if (vAvail[i]) + ::Unserialize(s, REF(CTxOutCompressor(vout[i]))); + } + // coinbase height + ::Unserialize(s, VARINT(nHeight)); + Cleanup(); + } + + //! mark a vout spent + bool Spend(uint32_t nPos); + + //! check whether a particular output is still available + bool IsAvailable(unsigned int nPos) const { + return (nPos < vout.size() && !vout[nPos].IsNull()); + } + + //! check whether the entire CCoins is spent + //! note that only !IsPruned() CCoins can be serialized + bool IsPruned() const { + for (const CTxOut &out : vout) + if (!out.IsNull()) + return false; + return true; + } + + size_t DynamicMemoryUsage() const { + size_t ret = memusage::DynamicUsage(vout); + for (const CTxOut &out : vout) { + ret += RecursiveDynamicUsage(out.scriptPubKey); + } + return ret; + } +}; + +class SaltedTxidHasher +{ +private: + /** Salt */ + const uint64_t k0, k1; + +public: + SaltedTxidHasher(); + + /** + * This *must* return size_t. With Boost 1.46 on 32-bit systems the + * unordered_map will behave unpredictably if the custom hasher returns a + * uint64_t, resulting in failures when syncing the chain (#4634). + */ + size_t operator()(const uint256& txid) const { + return SipHashUint256(k0, k1, txid); + } +}; + +struct CCoinsCacheEntry +{ + CCoins coins; // The actual cached data. + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned). + }; + + CCoinsCacheEntry() : coins(), flags(0) {} +}; + +struct CAnchorsSproutCacheEntry +{ + bool entered; // This will be false if the anchor is removed from the cache + SproutMerkleTree tree; // The tree itself + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + }; + + CAnchorsSproutCacheEntry() : entered(false), flags(0) {} +}; + +struct CAnchorsSaplingCacheEntry +{ + bool entered; // This will be false if the anchor is removed from the cache + SaplingMerkleTree tree; // The tree itself + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + }; + + CAnchorsSaplingCacheEntry() : entered(false), flags(0) {} +}; + +struct CAnchorsOrchardCacheEntry +{ + bool entered; // This will be false if the anchor is removed from the cache + OrchardMerkleFrontier tree; // The tree itself + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + }; + + CAnchorsOrchardCacheEntry() : entered(false), flags(0) {} +}; + +struct CNullifiersCacheEntry +{ + bool entered; // If the nullifier is spent or not + unsigned char flags; + + enum Flags { + DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view. + }; + + CNullifiersCacheEntry() : entered(false), flags(0) {} +}; + +/// These identify the value pool, and as such, Canopy (for example) +/// isn't here, since value created during the Canopy network upgrade +/// is part of the Sapling pool. +enum ShieldedType +{ + SPROUT, + SAPLING, + ORCHARD, +}; + +typedef boost::unordered_map CCoinsMap; +typedef boost::unordered_map CAnchorsSproutMap; +typedef boost::unordered_map CAnchorsSaplingMap; +typedef boost::unordered_map CAnchorsOrchardMap; +typedef boost::unordered_map CNullifiersMap; +typedef boost::unordered_map CHistoryCacheMap; + +struct CCoinsStats +{ + int nHeight; + uint256 hashBlock; + uint64_t nTransactions; + uint64_t nTransactionOutputs; + uint64_t nSerializedSize; + uint256 hashSerialized; + CAmount nTotalAmount; + + CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), nTotalAmount(0) {} +}; + + +/** Abstract view on the open txout dataset. */ +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; + + //! Retrieve the tree (Orchard) at a particular anchored root in the chain + virtual bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const; + + //! Determine whether a nullifier is spent or not + virtual bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; + + //! Retrieve the CCoins (unspent transaction outputs) for a given txid + virtual bool GetCoins(const uint256 &txid, CCoins &coins) const; + + //! Just check whether we have data for a given txid. + //! This may (but cannot always) return true for fully spent transactions + virtual bool HaveCoins(const uint256 &txid) const; + + //! Retrieve the block hash whose state this CCoinsView currently represents + virtual uint256 GetBestBlock() const; + + //! Get the current "tip" or the latest anchored tree root in the chain + virtual uint256 GetBestAnchor(ShieldedType type) const; + + //! Get the current chain history length (which should be roughly chain height x2) + virtual HistoryIndex GetHistoryLength(uint32_t epochId) const; + + //! Get history node at specified index + virtual HistoryNode GetHistoryAt(uint32_t epochId, HistoryIndex index) const; + + //! Get current history root + virtual uint256 GetHistoryRoot(uint32_t epochId) const; + + //! Do a bulk modification (multiple CCoins changes + BestBlock change). + //! The passed mapCoins can be modified. + virtual bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + const uint256 &hashOrchardAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMap); + + //! Calculate statistics about the unspent transaction output set + virtual bool GetStats(CCoinsStats &stats) const; + + //! As we use CCoinsViews polymorphically, have a virtual destructor + virtual ~CCoinsView() {} +}; + + +/** CCoinsView backed by another CCoinsView */ +class CCoinsViewBacked : public CCoinsView +{ +protected: + CCoinsView *base; + +public: + CCoinsViewBacked(CCoinsView *viewIn); + bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; + bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; + bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const; + bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; + bool GetCoins(const uint256 &txid, CCoins &coins) const; + bool HaveCoins(const uint256 &txid) const; + uint256 GetBestBlock() const; + uint256 GetBestAnchor(ShieldedType type) const; + HistoryIndex GetHistoryLength(uint32_t epochId) const; + HistoryNode GetHistoryAt(uint32_t epochId, HistoryIndex index) const; + uint256 GetHistoryRoot(uint32_t epochId) const; + void SetBackend(CCoinsView &viewIn); + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + const uint256 &hashOrchardAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMap); + bool GetStats(CCoinsStats &stats) const; +}; + + +class CCoinsViewCache; + +/** + * A reference to a mutable cache entry. Encapsulating it allows us to run + * cleanup code after the modification is finished, and keeping track of + * concurrent modifications. + */ +class CCoinsModifier +{ +private: + CCoinsViewCache& cache; + CCoinsMap::iterator it; + size_t cachedCoinUsage; // Cached memory usage of the CCoins object before modification + CCoinsModifier(CCoinsViewCache& cache_, CCoinsMap::iterator it_, size_t usage); + +public: + CCoins* operator->() { return &it->second.coins; } + CCoins& operator*() { return it->second.coins; } + ~CCoinsModifier(); + friend class CCoinsViewCache; +}; + +/** The set of shielded requirements that might be unsatisfied. */ +enum class UnsatisfiedShieldedReq { + SproutDuplicateNullifier, + SproutUnknownAnchor, + SaplingDuplicateNullifier, + SaplingUnknownAnchor, + OrchardDuplicateNullifier, + OrchardUnknownAnchor, +}; + +/** CCoinsView that adds a memory cache for transactions to another CCoinsView */ +class CCoinsViewCache : public CCoinsViewBacked +{ +protected: + /* Whether this cache has an active modifier. */ + bool hasModifier; + + + /** + * Make mutable so that we can "fill the cache" even from Get-methods + * declared as "const". + */ + mutable uint256 hashBlock; + mutable CCoinsMap cacheCoins; + mutable uint256 hashSproutAnchor; + mutable uint256 hashSaplingAnchor; + mutable uint256 hashOrchardAnchor; + mutable CAnchorsSproutMap cacheSproutAnchors; + mutable CAnchorsSaplingMap cacheSaplingAnchors; + mutable CAnchorsOrchardMap cacheOrchardAnchors; + mutable CNullifiersMap cacheSproutNullifiers; + mutable CNullifiersMap cacheSaplingNullifiers; + mutable CNullifiersMap cacheOrchardNullifiers; + mutable CHistoryCacheMap historyCacheMap; + + /* Cached dynamic memory usage for the inner CCoins objects. */ + mutable size_t cachedCoinsUsage; + +public: + CCoinsViewCache(CCoinsView *baseIn); + ~CCoinsViewCache(); + + // Standard CCoinsView methods + bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; + bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; + bool GetOrchardAnchorAt(const uint256 &rt, OrchardMerkleFrontier &tree) const; + bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; + bool GetCoins(const uint256 &txid, CCoins &coins) const; + bool HaveCoins(const uint256 &txid) const; + uint256 GetBestBlock() const; + uint256 GetBestAnchor(ShieldedType type) const; + HistoryIndex GetHistoryLength(uint32_t epochId) const; + HistoryNode GetHistoryAt(uint32_t epochId, HistoryIndex index) const; + uint256 GetHistoryRoot(uint32_t epochId) const; + void SetBestBlock(const uint256 &hashBlock); + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashSproutAnchor, + const uint256 &hashSaplingAnchor, + const uint256 &hashOrchardAnchor, + CAnchorsSproutMap &mapSproutAnchors, + CAnchorsSaplingMap &mapSaplingAnchors, + CAnchorsOrchardMap &mapOrchardAnchors, + CNullifiersMap &mapSproutNullifiers, + CNullifiersMap &mapSaplingNullifiers, + CNullifiersMap &mapOrchardNullifiers, + CHistoryCacheMap &historyCacheMap); + + // Adds the tree to mapSproutAnchors, mapSaplingAnchors, or mapOrchardAnchors + // based on the type of tree and sets the current commitment root to this root. + template void PushAnchor(const Tree &tree); + + // Removes the current commitment root from mapAnchors and sets + // the new current root. + void PopAnchor(const uint256 &rt, ShieldedType type); + + // Marks nullifiers for a given transaction as spent or not. + void SetNullifiers(const CTransaction& tx, bool spent); + + // Push MMR node history at the end of the history tree + void PushHistoryNode(uint32_t epochId, const HistoryNode node); + + // Pop MMR node history from the end of the history tree + void PopHistoryNode(uint32_t epochId); + + /** + * Return a pointer to CCoins in the cache, or NULL if not found. This is + * more efficient than GetCoins. Modifications to other cache entries are + * allowed while accessing the returned pointer. + */ + const CCoins* AccessCoins(const uint256 &txid) const; + + /** + * Return a modifiable reference to a CCoins. If no entry with the given + * txid exists, a new one is created. Simultaneous modifications are not + * allowed. + */ + CCoinsModifier ModifyCoins(const uint256 &txid); + + /** + * Return a modifiable reference to a CCoins. Assumes that no entry with the given + * txid exists and creates a new one. This saves a database access in the case where + * the coins were to be wiped out by FromTx anyway. We rely on Zcash-derived block chains + * having no duplicate transactions, since BIP 30 and (except for the genesis block) + * BIP 34 have been enforced since launch. See the Zcash protocol specification, section + * "Bitcoin Improvement Proposals". Simultaneous modifications are not allowed. + */ + CCoinsModifier ModifyNewCoins(const uint256 &txid); + + /** + * Push the modifications applied to this cache to its base. + * Failure to call this method before destruction will cause the changes to be forgotten. + * If false is returned, the state of this cache (and its backing view) will be undefined. + */ + bool Flush(); + + //! Calculate the size of the cache (in number of transactions) + unsigned int GetCacheSize() const; + + //! Calculate the size of the cache (in bytes) + size_t DynamicMemoryUsage() const; + + /** + * Amount of bitcoins 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. + * + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs), (positive valueBalance or zero) and JoinSplit vpub_new + */ + CAmount GetValueIn(const CTransaction& tx) const; + + //! 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 and sapling spend requirements (anchors/nullifiers) are satisfied + std::optional HaveShieldedRequirements(const CTransaction& tx) const; + + //! Return priority of tx at height nHeight + double GetPriority(const CTransaction &tx, int nHeight) const; + + const CTxOut &GetOutputFor(const CTxIn& input) const; + + friend class CCoinsModifier; + +private: + CCoinsMap::iterator FetchCoins(const uint256 &txid); + CCoinsMap::const_iterator FetchCoins(const uint256 &txid) const; + + /** + * By making the copy constructor private, we prevent accidentally using it + * when one intends to create a cache on top of a base cache. + */ + CCoinsViewCache(const CCoinsViewCache &); + + //! Generalized interface for popping anchors + template + void AbstractPopAnchor( + const uint256 &newrt, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash + ); + + //! Generalized interface for pushing anchors + template + void AbstractPushAnchor( + const Tree &tree, + ShieldedType type, + Cache &cacheAnchors, + uint256 &hash + ); + + //! Interface for bringing an anchor into the cache. + template + void BringBestAnchorIntoCache( + const uint256 ¤tRoot, + Tree &tree + ); + + //! Preload history tree for further update. + //! + //! If extra = true, extra nodes for deletion are also preloaded. + //! This will allow to delete tail entries from preloaded tree without + //! any further database lookups. + //! + //! Returns number of peaks, not total number of loaded nodes. + uint32_t PreloadHistoryTree(uint32_t epochId, bool extra, std::vector &entries, std::vector &entry_indices); + + //! Selects history cache for specified epoch. + HistoryCache& SelectHistoryCache(uint32_t epochId) const; +}; + +#endif // BITCOIN_COINS_H diff --git a/depend/zcash/src/compat.h b/depend/zcash/src/compat.h new file mode 100644 index 000000000..5cab5a8c7 --- /dev/null +++ b/depend/zcash/src/compat.h @@ -0,0 +1,107 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COMPAT_H +#define BITCOIN_COMPAT_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#ifdef WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#ifdef FD_SETSIZE +#undef FD_SETSIZE // prevent redefinition compiler warning +#endif +#define FD_SETSIZE 1024 // max number of fds in fd_set + +#include // Must be included before mswsock.h and windows.h + +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef WIN32 +#define MSG_DONTWAIT 0 +#else +typedef u_int SOCKET; +#include "errno.h" +#define WSAGetLastError() errno +#define WSAEINVAL EINVAL +#define WSAEALREADY EALREADY +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define WSAENOTSOCK EBADF +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 +#endif + +#ifdef WIN32 +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif +#else +#define MAX_PATH 1024 +#endif +#ifdef _MSC_VER +#if !defined(ssize_t) +#ifdef _WIN64 +typedef int64_t ssize_t; +#else +typedef int32_t ssize_t; +#endif +#endif +#endif + +// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0 +#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL 0 +#endif + +#ifndef WIN32 +// PRIO_MAX is not defined on Solaris +#ifndef PRIO_MAX +#define PRIO_MAX 20 +#endif +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL (-2) +#endif + +#if HAVE_DECL_STRNLEN == 0 +size_t strnlen( const char *start, size_t max_len); +#endif // HAVE_DECL_STRNLEN + +bool static inline IsSelectableSocket(SOCKET s) { +#ifdef WIN32 + return true; +#else + return (s < FD_SETSIZE); +#endif +} + +#endif // BITCOIN_COMPAT_H diff --git a/depend/zcash/src/compat/byteswap.h b/depend/zcash/src/compat/byteswap.h new file mode 100644 index 000000000..f5cbc9f7e --- /dev/null +++ b/depend/zcash/src/compat/byteswap.h @@ -0,0 +1,47 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COMPAT_BYTESWAP_H +#define BITCOIN_COMPAT_BYTESWAP_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#if defined(HAVE_BYTESWAP_H) +#include +#endif + +#if HAVE_DECL_BSWAP_16 == 0 +inline uint16_t bswap_16(uint16_t x) +{ + return (x >> 8) | ((x & 0x00ff) << 8); +} +#endif // HAVE_DECL_BSWAP16 + +#if HAVE_DECL_BSWAP_32 == 0 +inline uint32_t bswap_32(uint32_t x) +{ + return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) | + ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24)); +} +#endif // HAVE_DECL_BSWAP32 + +#if HAVE_DECL_BSWAP_64 == 0 +inline uint64_t bswap_64(uint64_t x) +{ + return (((x & 0xff00000000000000ull) >> 56) + | ((x & 0x00ff000000000000ull) >> 40) + | ((x & 0x0000ff0000000000ull) >> 24) + | ((x & 0x000000ff00000000ull) >> 8) + | ((x & 0x00000000ff000000ull) << 8) + | ((x & 0x0000000000ff0000ull) << 24) + | ((x & 0x000000000000ff00ull) << 40) + | ((x & 0x00000000000000ffull) << 56)); +} +#endif // HAVE_DECL_BSWAP64 + +#endif // BITCOIN_COMPAT_BYTESWAP_H diff --git a/depend/zcash/src/compat/endian.h b/depend/zcash/src/compat/endian.h new file mode 100644 index 000000000..31c5d534a --- /dev/null +++ b/depend/zcash/src/compat/endian.h @@ -0,0 +1,241 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COMPAT_ENDIAN_H +#define BITCOIN_COMPAT_ENDIAN_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#include "compat/byteswap.h" + +#if defined(HAVE_ENDIAN_H) +#include +#elif defined(HAVE_SYS_ENDIAN_H) +#include +#endif + +#ifndef HAVE_CONFIG_H +// While not technically a supported configuration, defaulting to defining these +// DECLs when we were compiled without autotools makes it easier for other build +// systems to build things like libbitcoinconsensus for strange targets. +#ifdef htobe16 +#define HAVE_DECL_HTOBE16 1 +#endif +#ifdef htole16 +#define HAVE_DECL_HTOLE16 1 +#endif +#ifdef be16toh +#define HAVE_DECL_BE16TOH 1 +#endif +#ifdef le16toh +#define HAVE_DECL_LE16TOH 1 +#endif + +#ifdef htobe32 +#define HAVE_DECL_HTOBE32 1 +#endif +#ifdef htole32 +#define HAVE_DECL_HTOLE32 1 +#endif +#ifdef be32toh +#define HAVE_DECL_BE32TOH 1 +#endif +#ifdef le32toh +#define HAVE_DECL_LE32TOH 1 +#endif + +#ifdef htobe64 +#define HAVE_DECL_HTOBE64 1 +#endif +#ifdef htole64 +#define HAVE_DECL_HTOLE64 1 +#endif +#ifdef be64toh +#define HAVE_DECL_BE64TOH 1 +#endif +#ifdef le64toh +#define HAVE_DECL_LE64TOH 1 +#endif + +#endif // HAVE_CONFIG_H + +#if defined(WORDS_BIGENDIAN) + +#if HAVE_DECL_HTOBE16 == 0 +inline uint16_t htobe16(uint16_t host_16bits) +{ + return host_16bits; +} +#endif // HAVE_DECL_HTOBE16 + +#if HAVE_DECL_HTOLE16 == 0 +inline uint16_t htole16(uint16_t host_16bits) +{ + return bswap_16(host_16bits); +} +#endif // HAVE_DECL_HTOLE16 + +#if HAVE_DECL_BE16TOH == 0 +inline uint16_t be16toh(uint16_t big_endian_16bits) +{ + return big_endian_16bits; +} +#endif // HAVE_DECL_BE16TOH + +#if HAVE_DECL_LE16TOH == 0 +inline uint16_t le16toh(uint16_t little_endian_16bits) +{ + return bswap_16(little_endian_16bits); +} +#endif // HAVE_DECL_LE16TOH + +#if HAVE_DECL_HTOBE32 == 0 +inline uint32_t htobe32(uint32_t host_32bits) +{ + return host_32bits; +} +#endif // HAVE_DECL_HTOBE32 + +#if HAVE_DECL_HTOLE32 == 0 +inline uint32_t htole32(uint32_t host_32bits) +{ + return bswap_32(host_32bits); +} +#endif // HAVE_DECL_HTOLE32 + +#if HAVE_DECL_BE32TOH == 0 +inline uint32_t be32toh(uint32_t big_endian_32bits) +{ + return big_endian_32bits; +} +#endif // HAVE_DECL_BE32TOH + +#if HAVE_DECL_LE32TOH == 0 +inline uint32_t le32toh(uint32_t little_endian_32bits) +{ + return bswap_32(little_endian_32bits); +} +#endif // HAVE_DECL_LE32TOH + +#if HAVE_DECL_HTOBE64 == 0 +inline uint64_t htobe64(uint64_t host_64bits) +{ + return host_64bits; +} +#endif // HAVE_DECL_HTOBE64 + +#if HAVE_DECL_HTOLE64 == 0 +inline uint64_t htole64(uint64_t host_64bits) +{ + return bswap_64(host_64bits); +} +#endif // HAVE_DECL_HTOLE64 + +#if HAVE_DECL_BE64TOH == 0 +inline uint64_t be64toh(uint64_t big_endian_64bits) +{ + return big_endian_64bits; +} +#endif // HAVE_DECL_BE64TOH + +#if HAVE_DECL_LE64TOH == 0 +inline uint64_t le64toh(uint64_t little_endian_64bits) +{ + return bswap_64(little_endian_64bits); +} +#endif // HAVE_DECL_LE64TOH + +#else // WORDS_BIGENDIAN + +#if HAVE_DECL_HTOBE16 == 0 +inline uint16_t htobe16(uint16_t host_16bits) +{ + return bswap_16(host_16bits); +} +#endif // HAVE_DECL_HTOBE16 + +#if HAVE_DECL_HTOLE16 == 0 +inline uint16_t htole16(uint16_t host_16bits) +{ + return host_16bits; +} +#endif // HAVE_DECL_HTOLE16 + +#if HAVE_DECL_BE16TOH == 0 +inline uint16_t be16toh(uint16_t big_endian_16bits) +{ + return bswap_16(big_endian_16bits); +} +#endif // HAVE_DECL_BE16TOH + +#if HAVE_DECL_LE16TOH == 0 +inline uint16_t le16toh(uint16_t little_endian_16bits) +{ + return little_endian_16bits; +} +#endif // HAVE_DECL_LE16TOH + +#if HAVE_DECL_HTOBE32 == 0 +inline uint32_t htobe32(uint32_t host_32bits) +{ + return bswap_32(host_32bits); +} +#endif // HAVE_DECL_HTOBE32 + +#if HAVE_DECL_HTOLE32 == 0 +inline uint32_t htole32(uint32_t host_32bits) +{ + return host_32bits; +} +#endif // HAVE_DECL_HTOLE32 + +#if HAVE_DECL_BE32TOH == 0 +inline uint32_t be32toh(uint32_t big_endian_32bits) +{ + return bswap_32(big_endian_32bits); +} +#endif // HAVE_DECL_BE32TOH + +#if HAVE_DECL_LE32TOH == 0 +inline uint32_t le32toh(uint32_t little_endian_32bits) +{ + return little_endian_32bits; +} +#endif // HAVE_DECL_LE32TOH + +#if HAVE_DECL_HTOBE64 == 0 +inline uint64_t htobe64(uint64_t host_64bits) +{ + return bswap_64(host_64bits); +} +#endif // HAVE_DECL_HTOBE64 + +#if HAVE_DECL_HTOLE64 == 0 +inline uint64_t htole64(uint64_t host_64bits) +{ + return host_64bits; +} +#endif // HAVE_DECL_HTOLE64 + +#if HAVE_DECL_BE64TOH == 0 +inline uint64_t be64toh(uint64_t big_endian_64bits) +{ + return bswap_64(big_endian_64bits); +} +#endif // HAVE_DECL_BE64TOH + +#if HAVE_DECL_LE64TOH == 0 +inline uint64_t le64toh(uint64_t little_endian_64bits) +{ + return little_endian_64bits; +} +#endif // HAVE_DECL_LE64TOH + +#endif // WORDS_BIGENDIAN + +#endif // BITCOIN_COMPAT_ENDIAN_H diff --git a/depend/zcash/src/compat/glibc_compat.cpp b/depend/zcash/src/compat/glibc_compat.cpp new file mode 100644 index 000000000..a80137cd8 --- /dev/null +++ b/depend/zcash/src/compat/glibc_compat.cpp @@ -0,0 +1,29 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#if defined(HAVE_SYS_SELECT_H) +#include +#endif + +// Prior to GLIBC_2.14, memcpy was aliased to memmove. +extern "C" void* memmove(void* a, const void* b, size_t c); +extern "C" void* memcpy(void* a, const void* b, size_t c) +{ + return memmove(a, b, c); +} + +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); +extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a) +{ + if (a >= FD_SETSIZE) + __chk_fail(); + return a / __NFDBITS; +} +extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn"))); diff --git a/depend/zcash/src/compat/glibc_sanity.cpp b/depend/zcash/src/compat/glibc_sanity.cpp new file mode 100644 index 000000000..71402559d --- /dev/null +++ b/depend/zcash/src/compat/glibc_sanity.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#if defined(HAVE_SYS_SELECT_H) +#include +#endif + +extern "C" void* memcpy(void* a, const void* b, size_t c); +void* memcpy_int(void* a, const void* b, size_t c) +{ + return memcpy(a, b, c); +} + +namespace +{ +// trigger: Use the memcpy_int wrapper which calls our internal memcpy. +// A direct call to memcpy may be optimized away by the compiler. +// test: Fill an array with a sequence of integers. memcpy to a new empty array. +// Verify that the arrays are equal. Use an odd size to decrease the odds of +// the call being optimized away. +template +bool sanity_test_memcpy() +{ + unsigned int memcpy_test[T]; + unsigned int memcpy_verify[T] = {}; + for (unsigned int i = 0; i != T; ++i) + memcpy_test[i] = i; + + memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test)); + + for (unsigned int i = 0; i != T; ++i) { + if (memcpy_verify[i] != i) + return false; + } + return true; +} + +#if defined(HAVE_SYS_SELECT_H) +// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined +// as >0 and optimizations must be set to at least -O2. +// test: Add a file descriptor to an empty fd_set. Verify that it has been +// correctly added. +bool sanity_test_fdelt() +{ + fd_set fds; + FD_ZERO(&fds); + FD_SET(0, &fds); + return FD_ISSET(0, &fds); +} +#endif + +} // anon namespace + +bool glibc_sanity_test() +{ +#if defined(HAVE_SYS_SELECT_H) + if (!sanity_test_fdelt()) + return false; +#endif + return sanity_test_memcpy<1025>(); +} diff --git a/depend/zcash/src/compat/glibcxx_sanity.cpp b/depend/zcash/src/compat/glibcxx_sanity.cpp new file mode 100644 index 000000000..bbba438ea --- /dev/null +++ b/depend/zcash/src/compat/glibcxx_sanity.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include +#include +#include + +namespace +{ +// trigger: use ctype::widen to trigger ctype::_M_widen_init(). +// test: convert a char from narrow to wide and back. Verify that the result +// matches the original. +bool sanity_test_widen(char testchar) +{ + const std::ctype& test(std::use_facet >(std::locale())); + return test.narrow(test.widen(testchar), 'b') == testchar; +} + +// trigger: use list::push_back and list::pop_back to trigger _M_hook and +// _M_unhook. +// test: Push a sequence of integers into a list. Pop them off and verify that +// they match the original sequence. +bool sanity_test_list(unsigned int size) +{ + std::list test; + for (unsigned int i = 0; i != size; ++i) + test.push_back(i + 1); + + if (test.size() != size) + return false; + + while (!test.empty()) { + if (test.back() != test.size()) + return false; + test.pop_back(); + } + return true; +} + +} // anon namespace + +// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt. +// test: force std::string to throw an out_of_range exception. Verify that +// it's caught correctly. +bool sanity_test_range_fmt() +{ + std::string test; + try { + test.at(1); + } catch (const std::out_of_range&) { + return true; + } catch (...) { + } + return false; +} + +bool glibcxx_sanity_test() +{ + return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt(); +} diff --git a/depend/zcash/src/compat/sanity.h b/depend/zcash/src/compat/sanity.h new file mode 100644 index 000000000..64dcade78 --- /dev/null +++ b/depend/zcash/src/compat/sanity.h @@ -0,0 +1,11 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COMPAT_SANITY_H +#define BITCOIN_COMPAT_SANITY_H + +bool glibc_sanity_test(); +bool glibcxx_sanity_test(); + +#endif // BITCOIN_COMPAT_SANITY_H diff --git a/depend/zcash/src/compat/strnlen.cpp b/depend/zcash/src/compat/strnlen.cpp new file mode 100644 index 000000000..1a56310af --- /dev/null +++ b/depend/zcash/src/compat/strnlen.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include + +#if HAVE_DECL_STRNLEN == 0 +size_t strnlen( const char *start, size_t max_len) +{ + const char *end = (const char *)memchr(start, '\0', max_len); + + return end ? (size_t)(end - start) : max_len; +} +#endif // HAVE_DECL_STRNLEN diff --git a/depend/zcash/src/compressor.cpp b/depend/zcash/src/compressor.cpp new file mode 100644 index 000000000..e91897149 --- /dev/null +++ b/depend/zcash/src/compressor.cpp @@ -0,0 +1,185 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#include "compressor.h" + +#include "hash.h" +#include "pubkey.h" +#include "script/standard.h" + +bool CScriptCompressor::IsToKeyID(CKeyID &hash) const +{ + if (script.size() == 25 && script[0] == OP_DUP && script[1] == OP_HASH160 + && script[2] == 20 && script[23] == OP_EQUALVERIFY + && script[24] == OP_CHECKSIG) { + memcpy(&hash, &script[3], 20); + return true; + } + return false; +} + +bool CScriptCompressor::IsToScriptID(CScriptID &hash) const +{ + if (script.size() == 23 && script[0] == OP_HASH160 && script[1] == 20 + && script[22] == OP_EQUAL) { + memcpy(&hash, &script[2], 20); + return true; + } + return false; +} + +bool CScriptCompressor::IsToPubKey(CPubKey &pubkey) const +{ + if (script.size() == 35 && script[0] == 33 && script[34] == OP_CHECKSIG + && (script[1] == 0x02 || script[1] == 0x03)) { + pubkey.Set(&script[1], &script[34]); + return true; + } + if (script.size() == 67 && script[0] == 65 && script[66] == OP_CHECKSIG + && script[1] == 0x04) { + pubkey.Set(&script[1], &script[66]); + return pubkey.IsFullyValid(); // if not fully valid, a case that would not be compressible + } + return false; +} + +bool CScriptCompressor::Compress(std::vector &out) const +{ + CKeyID keyID; + if (IsToKeyID(keyID)) { + out.resize(21); + out[0] = 0x00; + memcpy(&out[1], &keyID, 20); + return true; + } + CScriptID scriptID; + if (IsToScriptID(scriptID)) { + out.resize(21); + out[0] = 0x01; + memcpy(&out[1], &scriptID, 20); + return true; + } + CPubKey pubkey; + if (IsToPubKey(pubkey)) { + out.resize(33); + memcpy(&out[1], &pubkey[1], 32); + if (pubkey[0] == 0x02 || pubkey[0] == 0x03) { + out[0] = pubkey[0]; + return true; + } else if (pubkey[0] == 0x04) { + out[0] = 0x04 | (pubkey[64] & 0x01); + return true; + } + } + return false; +} + +unsigned int CScriptCompressor::GetSpecialSize(unsigned int nSize) const +{ + if (nSize == 0 || nSize == 1) + return 20; + if (nSize == 2 || nSize == 3 || nSize == 4 || nSize == 5) + return 32; + return 0; +} + +bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector &in) +{ + switch(nSize) { + case 0x00: + script.resize(25); + script[0] = OP_DUP; + script[1] = OP_HASH160; + script[2] = 20; + memcpy(&script[3], &in[0], 20); + script[23] = OP_EQUALVERIFY; + script[24] = OP_CHECKSIG; + return true; + case 0x01: + script.resize(23); + script[0] = OP_HASH160; + script[1] = 20; + memcpy(&script[2], &in[0], 20); + script[22] = OP_EQUAL; + return true; + case 0x02: + case 0x03: + script.resize(35); + script[0] = 33; + script[1] = nSize; + memcpy(&script[2], &in[0], 32); + script[34] = OP_CHECKSIG; + return true; + case 0x04: + case 0x05: + unsigned char vch[33] = {}; + vch[0] = nSize - 2; + memcpy(&vch[1], &in[0], 32); + CPubKey pubkey(&vch[0], &vch[33]); + if (!pubkey.Decompress()) + return false; + assert(pubkey.size() == 65); + script.resize(67); + script[0] = 65; + memcpy(&script[1], pubkey.begin(), 65); + script[66] = OP_CHECKSIG; + return true; + } + return false; +} + +// Amount compression: +// * If the amount is 0, output 0 +// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) +// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10) +// * call the result n +// * output 1 + 10*(9*n + d - 1) + e +// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9 +// (this is decodable, as d is in [1-9] and e is in [0-9]) + +uint64_t CTxOutCompressor::CompressAmount(uint64_t n) +{ + if (n == 0) + return 0; + int e = 0; + while (((n % 10) == 0) && e < 9) { + n /= 10; + e++; + } + if (e < 9) { + int d = (n % 10); + assert(d >= 1 && d <= 9); + n /= 10; + return 1 + (n*9 + d - 1)*10 + e; + } else { + return 1 + (n - 1)*10 + 9; + } +} + +uint64_t CTxOutCompressor::DecompressAmount(uint64_t x) +{ + // x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 + if (x == 0) + return 0; + x--; + // x = 10*(9*n + d - 1) + e + int e = x % 10; + x /= 10; + uint64_t n = 0; + if (e < 9) { + // x = 9*n + d - 1 + int d = (x % 9) + 1; + x /= 9; + // x = n + n = x*10 + d; + } else { + n = x+1; + } + while (e) { + n *= 10; + e--; + } + return n; +} diff --git a/depend/zcash/src/compressor.h b/depend/zcash/src/compressor.h new file mode 100644 index 000000000..e9c2cbdbb --- /dev/null +++ b/depend/zcash/src/compressor.h @@ -0,0 +1,121 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_COMPRESSOR_H +#define BITCOIN_COMPRESSOR_H + +#include "primitives/transaction.h" +#include "script/script.h" +#include "serialize.h" + +class CKeyID; +class CPubKey; +class CScriptID; + +/** Compact serializer for scripts. + * + * It detects common cases and encodes them much more efficiently. + * 3 special cases are defined: + * * Pay to pubkey hash (encoded as 21 bytes) + * * Pay to script hash (encoded as 21 bytes) + * * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes) + * + * Other scripts up to 121 bytes require 1 byte + script length. Above + * that, scripts up to 16505 bytes require 2 bytes + script length. + */ +class CScriptCompressor +{ +private: + /** + * make this static for now (there are only 6 special scripts defined) + * this can potentially be extended together with a new nVersion for + * transactions, in which case this value becomes dependent on nVersion + * and nHeight of the enclosing transaction. + */ + static const unsigned int nSpecialScripts = 6; + + CScript &script; +protected: + /** + * These check for scripts for which a special case with a shorter encoding is defined. + * They are implemented separately from the CScript test, as these test for exact byte + * sequence correspondences, and are more strict. For example, IsToPubKey also verifies + * whether the public key is valid (as invalid ones cannot be represented in compressed + * form). + */ + bool IsToKeyID(CKeyID &hash) const; + bool IsToScriptID(CScriptID &hash) const; + bool IsToPubKey(CPubKey &pubkey) const; + + bool Compress(std::vector &out) const; + unsigned int GetSpecialSize(unsigned int nSize) const; + bool Decompress(unsigned int nSize, const std::vector &out); +public: + CScriptCompressor(CScript &scriptIn) : script(scriptIn) { } + + template + void Serialize(Stream &s) const { + std::vector compr; + if (Compress(compr)) { + s << CFlatData(compr); + return; + } + unsigned int nSize = script.size() + nSpecialScripts; + s << VARINT(nSize); + s << CFlatData(script); + } + + template + void Unserialize(Stream &s) { + unsigned int nSize = 0; + s >> VARINT(nSize); + if (nSize < nSpecialScripts) { + std::vector vch(GetSpecialSize(nSize), 0x00); + s >> REF(CFlatData(vch)); + Decompress(nSize, vch); + return; + } + nSize -= nSpecialScripts; + if (nSize > MAX_SCRIPT_SIZE) { + // Overly long script, replace with a short invalid one + script << OP_RETURN; + s.ignore(nSize); + } else { + script.resize(nSize); + s >> REF(CFlatData(script)); + } + } +}; + +/** wrapper for CTxOut that provides a more compact serialization */ +class CTxOutCompressor +{ +private: + CTxOut &txout; + +public: + static uint64_t CompressAmount(uint64_t nAmount); + static uint64_t DecompressAmount(uint64_t nAmount); + + CTxOutCompressor(CTxOut &txoutIn) : txout(txoutIn) { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + if (!ser_action.ForRead()) { + uint64_t nVal = CompressAmount(txout.nValue); + READWRITE(VARINT(nVal)); + } else { + uint64_t nVal = 0; + READWRITE(VARINT(nVal)); + txout.nValue = DecompressAmount(nVal); + } + CScriptCompressor cscript(REF(txout.scriptPubKey)); + READWRITE(cscript); + } +}; + +#endif // BITCOIN_COMPRESSOR_H diff --git a/depend/zcash/src/config/.empty b/depend/zcash/src/config/.empty new file mode 100644 index 000000000..e69de29bb diff --git a/depend/zcash/src/consensus/consensus.h b/depend/zcash/src/consensus/consensus.h new file mode 100644 index 000000000..7a1981bdd --- /dev/null +++ b/depend/zcash/src/consensus/consensus.h @@ -0,0 +1,50 @@ +// 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 https://www.opensource.org/licenses/mit-license.php . + +#ifndef BITCOIN_CONSENSUS_CONSENSUS_H +#define BITCOIN_CONSENSUS_CONSENSUS_H + +#include + +/** The minimum allowed block version (network rule) */ +static const int32_t MIN_BLOCK_VERSION = 4; +/** The minimum allowed transaction version (network rule) */ +static const int32_t SPROUT_MIN_TX_VERSION = 1; +/** The minimum allowed Overwinter transaction version (network rule) */ +static const int32_t OVERWINTER_MIN_TX_VERSION = 3; +/** The maximum allowed Overwinter transaction version (network rule) */ +static const int32_t OVERWINTER_MAX_TX_VERSION = 3; +/** The minimum allowed Sapling transaction version (network rule) */ +static const int32_t SAPLING_MIN_TX_VERSION = 4; +/** The maximum allowed Sapling transaction version (network rule) */ +static const int32_t SAPLING_MAX_TX_VERSION = 4; +/** The minimum allowed ZIP225 transaction version (network rule) */ +static const int32_t ZIP225_MIN_TX_VERSION = 5; +/** The maximum allowed ZIP225 transaction version (network rule) */ +static const int32_t ZIP225_MAX_TX_VERSION = 5; +/** The maximum allowed size for a serialized block, in bytes (network rule) */ +static const unsigned int MAX_BLOCK_SIZE = 2000000; +/** The maximum allowed number of signature check operations in a block (network rule) */ +static const unsigned int MAX_BLOCK_SIGOPS = 20000; +/** The maximum size of a transaction (network rule) */ +static const unsigned int MAX_TX_SIZE_BEFORE_SAPLING = 100000; +static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = MAX_BLOCK_SIZE; +/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ +static const int COINBASE_MATURITY = 100; +/** The minimum value which is invalid for expiry height, used by CTransaction and CMutableTransaction */ +static constexpr uint32_t TX_EXPIRY_HEIGHT_THRESHOLD = 500000000; +/** The number of blocks after Canopy activation after which v1 plaintexts will be rejected */ +static const unsigned int ZIP212_GRACE_PERIOD = 32256; + +/** Flags for LockTime() */ +enum { + /* Use GetMedianTimePast() instead of nTime for end point timestamp. */ + LOCKTIME_MEDIAN_TIME_PAST = (1 << 1), +}; + +/** Used as the flags parameter to CheckFinalTx() in non-consensus code */ +static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_MEDIAN_TIME_PAST; + +#endif // BITCOIN_CONSENSUS_CONSENSUS_H diff --git a/depend/zcash/src/consensus/funding.cpp b/depend/zcash/src/consensus/funding.cpp new file mode 100644 index 000000000..7cec13080 --- /dev/null +++ b/depend/zcash/src/consensus/funding.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2020 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include + +namespace Consensus +{ +/** + * General information about each funding stream. + * Ordered by Consensus::FundingStreamIndex. + */ +constexpr struct FSInfo FundingStreamInfo[Consensus::MAX_FUNDING_STREAMS] = { + { + .recipient = "Electric Coin Company", + .specification = "https://zips.z.cash/zip-0214", + .valueNumerator = 7, + .valueDenominator = 100, + }, + { + .recipient = "Zcash Foundation", + .specification = "https://zips.z.cash/zip-0214", + .valueNumerator = 5, + .valueDenominator = 100, + }, + { + .recipient = "Major Grants", + .specification = "https://zips.z.cash/zip-0214", + .valueNumerator = 8, + .valueDenominator = 100, + } +}; + +static constexpr bool validateFundingStreamInfo(uint32_t idx) { + return (idx >= Consensus::MAX_FUNDING_STREAMS || ( + FundingStreamInfo[idx].valueNumerator < FundingStreamInfo[idx].valueDenominator && + FundingStreamInfo[idx].valueNumerator < (INT64_MAX / MAX_MONEY) && + validateFundingStreamInfo(idx + 1))); +} +static_assert( + validateFundingStreamInfo(Consensus::FIRST_FUNDING_STREAM), + "Invalid FundingStreamInfo"); + +CAmount FSInfo::Value(CAmount blockSubsidy) const +{ + // Integer division is floor division for nonnegative integers in C++ + return CAmount((blockSubsidy * valueNumerator) / valueDenominator); +} + +std::set GetActiveFundingStreamElements( + int nHeight, + CAmount blockSubsidy, + const Consensus::Params& params) +{ + std::set> requiredElements; + + // Funding streams are disabled if Canopy is not active. + if (params.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_CANOPY)) { + for (uint32_t idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) { + // The following indexed access is safe as Consensus::MAX_FUNDING_STREAMS is used + // in the definition of vFundingStreams. + auto fs = params.vFundingStreams[idx]; + // Funding period is [startHeight, endHeight) + if (fs && nHeight >= fs.value().GetStartHeight() && nHeight < fs.value().GetEndHeight()) { + requiredElements.insert(std::make_pair( + fs.value().RecipientAddress(params, nHeight), + FundingStreamInfo[idx].Value(blockSubsidy))); + } + } + } + + return requiredElements; +}; + +std::vector GetActiveFundingStreams( + int nHeight, + const Consensus::Params& params) +{ + std::vector activeStreams; + + // Funding streams are disabled if Canopy is not active. + if (params.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_CANOPY)) { + for (uint32_t idx = Consensus::FIRST_FUNDING_STREAM; idx < Consensus::MAX_FUNDING_STREAMS; idx++) { + auto fs = params.vFundingStreams[idx]; + if (fs && nHeight >= fs.value().GetStartHeight() && nHeight < fs.value().GetEndHeight()) { + activeStreams.push_back(FundingStreamInfo[idx]); + } + } + } + + return activeStreams; +}; + +} // namespace Consensus diff --git a/depend/zcash/src/consensus/funding.h b/depend/zcash/src/consensus/funding.h new file mode 100644 index 000000000..91230db2b --- /dev/null +++ b/depend/zcash/src/consensus/funding.h @@ -0,0 +1,45 @@ +// Copyright (c) 2020 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#ifndef ZCASH_CONSENSUS_FUNDING_H +#define ZCASH_CONSENSUS_FUNDING_H + +#include +#include + + +namespace Consensus +{ + +struct FSInfo { + const char* recipient; + const char* specification; + uint64_t valueNumerator; + uint64_t valueDenominator; + + /** + * Returns the inherent value of this funding stream. + * + * For the active funding streams at a given height, use + * GetActiveFundingStreams() or GetActiveFundingStreamElements(). + */ + CAmount Value(CAmount blockSubsidy) const; +}; + +extern const struct FSInfo FundingStreamInfo[]; + +typedef std::pair FundingStreamElement; + +std::set GetActiveFundingStreamElements( + int nHeight, + CAmount blockSubsidy, + const Consensus::Params& params); + +std::vector GetActiveFundingStreams( + int nHeight, + const Consensus::Params& params); + +} // namespace Consensus + +#endif // ZCASH_CONSENSUS_FUNDING_H diff --git a/depend/zcash/src/consensus/params.cpp b/depend/zcash/src/consensus/params.cpp new file mode 100644 index 000000000..53c257a86 --- /dev/null +++ b/depend/zcash/src/consensus/params.cpp @@ -0,0 +1,249 @@ +// Copyright (c) 2019 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +#include "params.h" + +#include +#include +#include