diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a025e66ac..d73d84b67 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,10 +1,8 @@ -This issue tracker is only for technical issues related to zcashd. +This issue tracker is only for technical issues related to komodod -General Zcash questions and/or support requests and are best directed to the [Zcash Forums](https://forum.z.cash) or [Community Rocket.Chat](https://chat.zcashcommunity.com). - -For reporting security vulnerabilities or for sensitive discussions with our security team, please contact [security@z.cash](mailto:security@z.cash). You can use the [GPG key](https://z.cash/gpg-pubkeys/security.asc) (fingerprint: `AF85 0445 546C 18B7 86F9 2C62 88FB 8B86 D8B5 A68C`) to send an encrypted message. The key and fingerprint are duplicated on our [Public Keys page](https://z.cash/support/pubkeys.html). +General Komodo questions and/or support requests and are best directed to [Discord](https://komodoplatform.com/discord) ### Describe the issue Please provide a general summary of the issue you're experiencing @@ -21,8 +19,8 @@ Tell us what should happen ### Actual behaviour + errors Tell us what happens instead including any noticable 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 +### The version of Komodo you were using: +Run `komodod --version` to find out ### Machine specs: - OS name + version: @@ -34,9 +32,9 @@ Run `zcashd --version` to find out - Compiler version (gcc -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. +This includes the relevant contents of `~/.komodo/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. +### Do you have a backup of `~/.komodo` directory and/or take a VM snapshot? +- Backing up / making a copy of the `~/.komodo` directory might help make the problem reproducible. Please redact appropriately. - Taking a VM snapshot is really helpful for interactively testing fixes diff --git a/.gitignore b/.gitignore index 1f2b2537d..01e45a168 100644 --- a/.gitignore +++ b/.gitignore @@ -7,10 +7,6 @@ src/zcash-gtest src/zcash-tx src/test/test_bitcoin -# Zcash utilities -src/zcash/GenerateParams -src/zcash/CreateJoinSplit - *zcashTest.pk *zcashTest.vk diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ebaf34ea2..8941fdcfc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,13 +3,15 @@ stages: - test - deploy + variables: - VERSION: 0.3.13 + VERSION: 0.3.14 VERUS_CLI_LINUX: "Verus-CLI-Linux-v${VERSION}-beta.tar.gz" VERUS_CLI_WINDOWS: "Verus-CLI-Windows-v${VERSION}-beta.zip" VERUS_CLI_MACOS: "Verus-CLI-MacOS-v${VERSION}-beta.tar.gz" POST_COMMENT: "Branch and Commit: ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA} $'\n'MD5: " + build:linux: image: asherd/veruscoin-cross-compiler:linux variables: @@ -19,7 +21,7 @@ build:linux: - rm -rf /root/.ccache || true - mv .ccache /root/ || true script: - - zcutil/build.sh -j4 + - zcutil/build.sh -j$(nproc) - cp src/komodod src/komodo-cli kmd/linux/verus-cli - chmod +x kmd/linux/verus-cli/komodod - chmod +x kmd/linux/verus-cli/komodo-cli @@ -30,6 +32,13 @@ build:linux: - cd kmd/linux/ - tar -czvf $VERUS_CLI_LINUX verus-cli - mv $VERUS_CLI_LINUX ../.. + - cd ../.. + - export VERUS_CLI_LINUX_MD5=$(md5sum $VERUS_CLI_LINUX | cut -d " " -f 1) + - curl -F file=@"$VERUS_CLI_LINUX" + -F channels="$CLI_POST_CHANNEL" + -F initial_comment="${POST_COMMENT}$VERUS_CLI_LINUX_MD5" + -H "${SLACK_BOT_AUTH}" + "https://slack.com/api/files.upload" after_script: - mv /root/.ccache ./ || true cache: @@ -61,11 +70,18 @@ build:windows: - mkdir .cargo || echo .cargo exists - ln -s $PWD/.cargo /root/.cargo script: - - zcutil/build-win.sh -j4 + - zcutil/build-win.sh -j$(nproc) - cp src/komodod.exe src/komodo-cli.exe src/komodo-tx.exe kmd/windows/verus-cli - cd kmd/windows/ - zip -r $VERUS_CLI_WINDOWS verus-cli - mv $VERUS_CLI_WINDOWS ../.. + - cd ../.. + - export VERUS_CLI_WINDOWS_MD5=$(md5sum $VERUS_CLI_WINDOWS | cut -d " " -f 1) + - curl -F file=@"$VERUS_CLI_WINDOWS" + -F channels="$CLI_POST_CHANNEL" + -F initial_comment="${POST_COMMENT}$VERUS_CLI_WINDOWS_MD5" + -H "${SLACK_BOT_AUTH}" + "https://slack.com/api/files.upload" artifacts: paths: [$VERUS_CLI_WINDOWS] expire_in: 1 week @@ -80,10 +96,16 @@ build:mac: - depends/built script: - brew bundle - - zcutil/build-mac.sh -j6 | xcpretty + - zcutil/build-mac.sh -j$(sysctl -n hw.physicalcpu) | xcpretty - ./makeReleaseMac.sh - dos2unix kmd/mac/verus-cli/README.txt - tar -C kmd/mac/ -czvf $VERUS_CLI_MACOS verus-cli ./ + - export VERUS_CLI_MACOS_MD5=$(md5sum $VERUS_CLI_MACOS | cut -d " " -f 1) + - curl -F file=@"$VERUS_CLI_MACOS" + -F channels="$CLI_POST_CHANNEL" + -F initial_comment="${POST_COMMENT}$VERUS_CLI_MACOS_MD5" + -H "${SLACK_BOT_AUTH}" + "https://slack.com/api/files.upload" artifacts: paths: [$VERUS_CLI_MACOS] expire_in: 1 week @@ -125,7 +147,6 @@ build:mac: paths: [gl-sast-report.json] - .license_management: image: docker:stable variables: @@ -243,27 +264,7 @@ deploy: - build:linux - build:windows - build:mac - before_script: - - export VERUS_CLI_LINUX_MD5=$(md5sum $VERUS_CLI_LINUX | cut -d " " -f 1) - - export VERUS_CLI_WINDOWS_MD5=$(md5sum $VERUS_CLI_WINDOWS | cut -d " " -f 1) - - export VERUS_CLI_MACOS_MD5=$(md5sum $VERUS_CLI_MACOS | cut -d " " -f 1) script: - - export VERUS_CLI_LINUX_MD5=$(md5sum $VERUS_CLI_LINUX | cut -d " " -f 1) - - curl -F file=@"$VERUS_CLI_LINUX" - -F channels="$CLI_POST_CHANNEL" - -F initial_comment="${POST_COMMENT}$VERUS_CLI_LINUX_MD5" - -H "${SLACK_BOT_AUTH}" - "https://slack.com/api/files.upload" - - curl -F file=@"$VERUS_CLI_WINDOWS" - -F channels="$CLI_POST_CHANNEL" - -F initial_comment="${POST_COMMENT}$VERUS_CLI_WINDOWS_MD5" - -H "${SLACK_BOT_AUTH}" - "https://slack.com/api/files.upload" - - curl -F file=@"$VERUS_CLI_MACOS" - -F channels="$CLI_POST_CHANNEL" - -F initial_comment="${POST_COMMENT}$VERUS_CLI_MACOS_MD5" - -H "${SLACK_BOT_AUTH}" - "https://slack.com/api/files.upload" - mkdir Windows && mkdir Linux && mkdir MacOS && mv $VERUS_CLI_WINDOWS Windows && mv $VERUS_CLI_LINUX Linux && @@ -280,4 +281,3 @@ deploy: -F variables\[VERUS_CLI_WINDOWS\]="$VERUS_CLI_WINDOWS" -F variables\[VERUS_CLI_MACOS\]="$VERUS_CLI_MACOS" "https://gitlab.com/api/v4/projects/8018592/trigger/pipeline" - diff --git a/.travis.yml b/.travis.yml index 107a3827f..d9237a104 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,67 +1,46 @@ -sudo: required -os: linux -dist: xenial language: cpp + +matrix: + include: + - os: linux + dist: xenial + sudo: required + - os: osx + osx_image: xcode8 compiler: - gcc -env: - global: - - CCACHE_SIZE=100M - - CCACHE_TEMPDIR=/tmp/.ccache-temp - - CCACHE_COMPRESS=1 - - STORAGE_DEST=gs://$BUCKET/$PROJECT/$TRAVIS_BRANCH/ -cache: - apt: true - directories: - - depends/built - - depends/sdk-sources - - "$HOME/google-cloud-sdk/" - - "$HOME/.ccache" -matrix: - fast_finish: true - include: - - compiler: ": Linux" - env: BUILD_SCRIPT=build.sh - PACKAGES="build-essential pkg-config libc6-dev m4 g++-multilib - autoconf libtool ncurses-dev unzip python zlib1g-dev wget bsdmainutils automake - libssl-dev libprotobuf-dev protobuf-compiler libqrencode-dev libdb++-dev software-properties-common - libcurl4-openssl-dev curl" - PACKAGE_NAME=verus-cli-linux.tar.gz - PACKAGING_MATRIX="cp src/komodod src/komodo-cli kmd/linux/verus-cli && chmod +x kmd/linux/verus-cli/komodod && chmod +x kmd/linux/verus-cli/komodo-cli && cd kmd/linux && tar -czf $PACKAGE_NAME verus-cli && ls" - - compiler: ": Windows" - env: RUST_TARGET=x86_64-pc-windows-gnu - BUILD_SCRIPT=build-win.sh - PACKAGES="build-essential pkg-config libcurl3-gnutls-dev - libc6-dev libevent-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git - python zlib1g-dev wget bsdmainutils automake libssl-dev libprotobuf-dev protobuf-compiler - libdb++-dev ntp ntpdate mingw-w64 wine bc" - PACKAGE_NAME=verus-cli-windows.zip - PACKAGING_MATRIX="cp src/komodod.exe src/komodo-cli.exe src/komodo-tx.exe kmd/windows/verus-cli && - cd kmd/windows && zip -r9 $PACKAGE_NAME verus-cli && ls" - exclude: - - compiler: gcc -install: -- sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list -- travis_retry sudo apt-get -y update && travis_retry sudo apt-get -y install -qq $PACKAGES -- if [ -n "$RUST_TARGET" ]; then curl -sSf https://build.travis-ci.org/files/rustup-init.sh - | sh -s -- --default-toolchain stable -y && export PATH=$PATH:$HOME/.cargo/bin:$PATH && rustup target add $RUST_TARGET; fi -before_script: -- unset CC; unset CXX -script: -- "./zcutil/fetch-params.sh" -- "./zcutil/$BUILD_SCRIPT -j2" -after_script: -- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then eval "${PACKAGING_MATRIX}" && - gsutil cp $PACKAGE_NAME $STORAGE_DEST; fi -notifications: - slack: - secure: FiVlFhSw5xnDu1Cx2yAo3J7miFCSRyuzR/2+8LKFjdWl5+fyIGvQ9x5vgUg6dWbv3UP9iIMqQuWfotsg8H+NE8pYRZQ0zDVxZ5h9+PA028qGb3OF4TMFNcltP5DGtAZ6AqrMNRZ4ltatPUm5H9ig1bhzjsx+3pqlqQuVXTXPjaUryB5s/fk2CjrsV6zTLfPHiI30jeMjmQrJJLik1vSWF70sB6HkQhvaT6jymkO4Vuh+cja418W1xIgkkoRsOXiZ/JK4hIypFo/sBkmIOprGqoFUahFqJlsBoSrp9iAzkwbDItIqqvNCHTEeN7lj6kK43ZK72E4etjjNc0CXWeleXBJBCj5Prq2lEkQ4NwuDTos3KLyyr2vI7f54xhb5+wjzY9dByHXGuG5UaNz0+uukuJinAdazGaNmmfesv1wg9p3jGa/TLsfHLMcUti875DzkUHnenivP5cXrc6/uuZyyQNq5+Gn/3DA8k0y7d1e23nm3nDjCNfATAn3yu1jieYY2yYI6CYGEXcD+UbP61uG6no+mm/lkQbQosyDfE0sADqGryqXswRste+R0sSVMBQtTipAZOUoYNbEmhN4+L78SSp3zpmgkrIxAw7le8oj6Evp2ofvE2Kvh+Z0MVoEJx6mtZI6hheIFSS38NeUZr/HBfRSpaElOYTN/ZNf8QwThCWo= before_install: -- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then openssl aes-256-cbc -K $encrypted_11153c0bb86c_key -iv $encrypted_11153c0bb86c_iv - -in AUTH_KEY.json.enc -out AUTH_KEY.json -d; fi -- if [ ! -d "$HOME/google-cloud-sdk/bin" ]; then rm -rf $HOME/google-cloud-sdk; export - CLOUDSDK_CORE_DISABLE_PROMPTS=1; curl https://sdk.cloud.google.com | bash; fi -- source /home/travis/google-cloud-sdk/path.bash.inc -- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then gcloud auth activate-service-account --key-file AUTH_KEY.json; fi -- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then rm AUTH_KEY.json; fi -- rm AUTH_KEY.json.enc +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa; fi +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; fi +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install libgnutls28-dev; fi +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install build-essential pkg-config libcurl3-gnutls-dev libc6-dev libevent-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python zlib1g-dev wget bsdmainutils automake libssl-dev libprotobuf-dev protobuf-compiler libdb++-dev ntp ntpdate; fi +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then rm '/usr/local/include/c++'; fi +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gcc@6; fi +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link --overwrite gcc@6; fi +script: +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./zcutil/build.sh -j 5; fi +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./zcutil/build-mac.sh -j 5; fi +notifications: + irc: + channels: + - chat.freenode.net#komodoplatform + template: + - "%{repository}/%{branch} (%{commit} - %{author}): %{message}" + - 'Alt Message : %{repository_slug} - (%{commit} - %{author}): %{message}, Build + Time: %{duration}' + - 'Change view : %{compare_url}' + - 'Build details : %{build_url}' +before_deploy: + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git tag "linux-$(date +'%Y%m%d%H%M')-$(git log --format=%h -1)"; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then git tag "osx-$(date +'%Y%m%d%H%M')-$(git log --format=%h -1)"; fi +deploy: + provider: releases + api_key: + secure: Jms7dz5GMZmuXUCHl5u6iZUtAybv86oW3x36DCJfdzbDiO4B9EWB04z7zA0qvoomefyujHTmQUHxyOKfd4h9/rVMFFv9hgmUxWkrcg7KyLNisOQRaovVOuNtu2lRNXTOSF16Cy+xFGkVh1ObBRhAoMsVKPhMl6PCDiKhNWIekRR9pBtjafKsClQ2ieknUYfqhuvgj7zmqCedeyVaVQyt2W/J65leD0BkfCUESTpANSprHs4bQB65VuQIKKMi+URKx2VgpDdUcWJySt9jAHVPIbI5cT5maAT6RUMnE4oha7Ca1Ox8StBqjQ/hkkMyDbN0keIlN7RjZlwdZQf/qUnT/dPQhsyUCdPXOxmEJ2jekezEK/LGr4Fb+v+vjd9dhLNkD5nVn9zp36biGSCjiMpffQ3fjMeM0YGmVEVRP9kZXLWVRYQoVKrzjyzg5dY8iChbiQEfYpTeBuU+e2rqj4mns+Jvy0zjUbMy6Tyva+iqdZ/PdsBDbiB7c+FIgB1IUTVOD+GgKx6dhCtBZEccn5EyWFwZF9IdQJHZCYV4PA7nuzfm1Ol9SDdZkGHd2OgRCqK/sTwyfTHv8exNqZ1k+epGJp2a0q4IOEknc9aPCAF+m9pHahk7s7VO5gmhO6pvbvuKoeEtEXRZHRzCkGkXfzJlBk+23X5gBexKb6inRdBlj6M= + file: + - src/komodod + - src/komodo-cli + skip_cleanup: true + on: + repo: KomodoPlatform/komodo diff --git a/COPYING b/COPYING index 02509fbc9..7c046110d 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,7 @@ -Copyright (c) 2016-2018 The Komodo developers -Copyright (c) 2016-2017 The Zcash developers Copyright (c) 2009-2017 The Bitcoin Core developers +Copyright (c) 2009-2018 Bitcoin Developers +Copyright (c) 2016-2017 The Zcash developers +Copyright (c) 2016-2018 The Komodo developers Copyright (c) 2018 The VerusCoin developers Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/Makefile.am b/Makefile.am index ccd884dd3..51d0430ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,7 @@ BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ $(top_srcdir)/contrib/devtools/security-check.py + WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp diff --git a/README.md b/README.md index 78a4e0596..7f400f9f5 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,20 @@ The wallet downloads and stores the block chain or asset chain of the coin you s - Mail: [info@komodoplatform.com](mailto:info@komodoplatform.com) - Support: [https://support.komodoplatform.com/support/home](https://support.komodoplatform.com/support/home) - Knowledgebase & How-to: [https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages](https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages) -- API references: [http://docs.supernet.org/](http://docs.supernet.org/) #Not up to date. -- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/06/Komodo-Whitepaper-June-3.pdf) +- API references: [http://docs.komodoplatform.com/](http://docs.komodoplatform.com/) +- Blog: [http://blog.komodoplatform.com/](http://blog.komodoplatform.com/) +- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/03/2018-03-12-Komodo-White-Paper-Full.pdf) - Komodo Platform public material: [Komodo Platform public material](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) ## List of Komodo Platform Technologies -- Delayed Proof of Work (dPoW) - Additional security layer. -- zk-SNARKs - Komodo Platform's privacy technology + +- Delayed Proof of Work (dPoW) - Additional security layer and Komodos own consensus algorithm. +- zk-SNARKs - Komodo Platform's privacy technology for shielded transactions +- Tokens/Assets Technology - create "colored coins" on the Komodo Platform and use them as a layer for securites +- Reward API - Komodo CC technology for securities +- CC - Crypto Conditions to realize "smart contract" logic on top of the Komodo Platform - Jumblr - Decentralized tumbler for KMD and other cryptocurrencies -- Assetchains - Easy way to fork Komodo coin +- Assetchains - Create your own Blockchain that inherits all Komodo Platform functionalities and blockchain interoperability - Pegged Assets - Chains that maintain a peg to fiat currencies - Peerchains - Scalability solution where sibling chains form a network of blockchains - More in depth covered [here](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) @@ -40,14 +45,14 @@ The wallet downloads and stores the block chain or asset chain of the coin you s - Max Supply: 200 million KMD. - Block Time: 1M 2s - Block Reward: 3KMD -- Mining Algorithm: Equihash +- Mining Algorithm: Equihash ## About this Project -Komodo is based on Zcash and has been by our innovative consensus algorithm called dPoW which utilizes Bitcoin's hashrate to store Komodo blockchain information into the Bitcoin blockchain. Other new and native Komodo features are the privacy technology called JUMBLR or our assetchain capabilities (one click plug and play blockchain solutions). More details are available under https://komodoplatform.com/. +Komodo is based on Zcash and has been extended by our innovative consensus algorithm called dPoW which utilizes Bitcoin's hashrate to store Komodo blockchain information into the Bitcoin blockchain. Other new and native Komodo features are the privacy technology called JUMBLR, our assetchain capabilities (one click plug and play blockchain solutions) and a set of financial decentralization and interoperability technologies. More details are available under https://komodoplatform.com/ and https://blog.komodoplatform.com. ## Getting started -Dependencies ------------- + +### Dependencies ```shell #The following packages are needed: @@ -76,15 +81,17 @@ Building for Windows: ``` VerusCoin ------ -We develop on dev and some other branches and produce releases of of the master branch, using pull requests to manage what goes into master. +We develop on dev and some other branches and produce releases of of the master branch, using pull requests to manage what goes into master. The dev branch is considered the bleeding edge codebase, and may even be oncompatible from time to time, while the master-branch is considered tested (unit tests, runtime tests, functionality). At no point of time do the Komodo Platform developers or Verus Developers take any responsbility for any damage out of the usage of this software. +Verus builds for all operating systems out of the same codebase. Follow the OS specific instructions from below. +#### Linux ```shell git clone https://github.com/VerusCoin/VerusCoin cd VerusCoin #you might want to: git checkout ; git pull ./zcutil/fetch-params.sh -# -j8 uses 8 threads - replace 8 with number of threads you want to use +# -j8 = using 8 threads for the compilation - replace 8 with number of threads you want to use ./zcutil/build.sh -j8 #This can take some time. ``` @@ -101,67 +108,37 @@ Note that this directory is correct for Linux, not Mac or Windows ./src/komodo-cli help **Zcash is unfinished and highly experimental.** Use at your own risk. -Where do I begin? ------------------ -We have a guide for joining the main Zcash network: -https://github.com/zcash/zcash/wiki/1.0-User-Guide +#### :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 time period. The automatic feature is based on block +height. #Older Komodo Details The remaining text is from the komodo source we forked when creating VerusCoin/Veruscoin. + **To change modes:** a) backup all privkeys (launch komodod with `-exportdir=` and `dumpwallet`) - b) start a totally new sync including `wallet.dat`, launch with same `exportdir` - c) stop it before it gets too far and import all the privkeys from a) using `komodo-cli importwallet filename` - d) resume sync till it gets to chaintip For example: ```shell -./komodod -exportdir=/tmp & -./komodo-cli dumpwallet example -./komodo-cli stop -mv ~/.komodo ~/.komodo.old && mkdir ~/.komodo && cp ~/.komodo.old/komodo.conf ~/.komodo.old/peers.dat ~/.komodo -./komodod -exchange -exportdir=/tmp & -./komodo-cli importwallet /tmp/example +./verusd -exportdir=/tmp & +./verus dumpwallet example +./verus stop +mv ~/.komodo/VRSC ~/.komodo/VRSC.old && mkdir ~/.komodo/VRSC && cp ~/.komodo/VRSC.old/VRSC.conf ~/.komodo/VRSC.old/peers.dat ~/.komodo/VRSC +./verusd -exchange -exportdir=/tmp & +./verus importwallet /tmp/example ``` +--- -## JUMBLR -komodod now has `jumblr_deposit` and `jumblr_secret` RPC calls. -Jumblr works like described previously where all the nodes with jumblr active synchronize their tx activity during the same block to maximize the mixing effect. However, unlike all other mixers/tumblers, you never give up control of your coins to anybody else. JUMBLR uses a one to many allocation of funds, ie. one deposit address and many secret addresses. You can always run multiple komodod daemons to get multiple active deposit addresses. +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: -JUMBLR implements t -> z, z -> z and z -> t transactions to maximize privacy of the destination t (transparent) address. So while it is transparent, its first activity is funds coming from an untracable z address. +The above copyright notices and this permission notice shall be included in all copies or substantial portions of the Software. -Which of the three stages is done is randomly selected at each turn. Also when there is more than one possible transaction at the selected stage, a random one is selected. This randomization prevents analyzing incoming z ->t transactions by its size to correlate it to the originating address. - -`jumblr_deposit ` designates the deposit address as the jumblr deposit address for that session. You can select an address that already has funds in it and it will immediately start jumblr process. If there are no funds, it will wait until you send funds to it. - -There are three sizes of a jumblr transaction: 10 KMD, 100 KMD and 1000 KMD. There is also a fixed interval of blocks where all jumblr nodes are active. Currently it is set to be 10, but this is subject to change. Only during every 10*10 blocks are the largest 1000 KMD transactions processed, so this concentrates all the large transactions every N*N blocks. - -`jumblr_secret ` notifies JUMBLR where to send the final z -> t transactions. In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported. Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected. - -#### Practical Advice: -Obtaining privacy used to be very difficult. JUMBLR makes it as simple as issuing two command line calls. Higher level layers can be added to help manage the addresses, ie. linking them at the passphrase level. Such matters are left to each implementation. - -Once obtained, it is very easy to lose all the privacy. With a single errant transaction that combines some previously used address and the secretaddress, well, the secretaddress is no longer so private. - -The advice is to setup a totally separate node! - -This might seem a bit drastic, but if you want to maintain privacy, it is best to make it look like all the transactions are coming from a different node. The easiest way for most people to do this is to actually have a different node. - -It can be a dedicated laptop (recommended) or a VPS (for smaller amounts) with a totally fresh komodod wallet. Generate an address on this wallet and use that as the jumblr_secret address on your main node. As the JUMBLR operates funds will teleport into your secret node's address. If you are careful and never use the same IP address for both your nodes, you will be able to maintain very good privacy. - -Of course, don't send emails that link the two accounts together! Dont use secret address funds for home delivery purchases! Etc. There are many ways to lose the privacy, just think about what linkages can be dont at the IP and blockchain level and that should be a useful preparation. - -What if you have 100,000 KMD and you dont want others to know you are such a whale? -Instead of generating 1 secret address, generate 100 and make a script file with: -```shell -./komodo-cli jumblr_secret -./komodo-cli jumblr_secret -... -./komodo-cli jumblr_secret -``` -And make sure to delete all traces of this when the JUMBLR is finished. You will end up with 100 addresses that have an average of 1000 KMD each. So as long as you are careful and dont do a 10,000 KMD transaction (that will link 10 of your secret addresses together), you can appear as 100 different people each with 1000 KMD. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/code_of_conduct.md b/code_of_conduct.md index d8f622351..c4592cc32 100644 --- a/code_of_conduct.md +++ b/code_of_conduct.md @@ -24,7 +24,9 @@ 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. +threatening, offensive, or harmful. Note that contributors may be volunteers +who do not represent Zcash 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 diff --git a/configure.ac b/configure.ac index eda8fa433..6a29e5287 100644 --- a/configure.ac +++ b/configure.ac @@ -1,9 +1,9 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) -define(_CLIENT_VERSION_MAJOR, 1) +define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 0) define(_CLIENT_VERSION_REVISION, 15) -define(_CLIENT_VERSION_BUILD, 50) +define(_CLIENT_VERSION_BUILD, 25) 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) @@ -96,12 +96,6 @@ AC_ARG_ENABLE([mining], [enable_mining=$enableval], [enable_mining=yes]) -AC_ARG_ENABLE([rust], - [AS_HELP_STRING([--enable-rust], - [enable rust (default is yes)])], - [enable_rust=$enableval], - [enable_rust=yes]) - AC_ARG_ENABLE([proton], [AS_HELP_STRING([--disable-proton], [disable Proton (AMQP messaging)])], @@ -238,9 +232,9 @@ AC_ARG_WITH([utils], AC_ARG_WITH([libs], [AS_HELP_STRING([--with-libs], - [build libraries (default=yes)])], + [build libraries (default=no)])], [build_bitcoin_libs=$withval], - [build_bitcoin_libs=yes]) + [build_bitcoin_libs=no]) AC_ARG_WITH([daemon], [AS_HELP_STRING([--with-daemon], @@ -772,15 +766,20 @@ fi #AC_CHECK_HEADER([libsnark/gadgetlib1/gadget.hpp],,AC_MSG_ERROR(libsnark headers missing)) #AC_CHECK_LIB([snark],[main],LIBSNARK_LIBS=-lsnark, [AC_MSG_ERROR(libsnark missing)], [-lgmpxx]) -RUST_LIBS="" -if test x$enable_rust != xno; then - RUST_LIBS="-lrustzcash" -fi +RUST_LIBS="-lrustzcash" +case $host in + *mingw*) + ;; + *) + RUST_LIBS="$RUST_LIBS -ldl" + ;; +esac dnl Check for OpenMP support AX_OPENMP( [AC_DEFINE(HAVE_OPENMP, 1, [Define if OpenMP is enabled]) AM_CONDITIONAL([HAVE_OPENMP], [true]) + CPPFLAGS="$CPPFLAGS -DMULTICORE" CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS"], [AC_MSG_WARN([OpenMP not supported, disabling multithreading]) AC_DEFINE(HAVE_OPENMP, 0, [Define if OpenMP is enabled]) @@ -799,7 +798,7 @@ AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) -LIBZCASH_LIBS="-lgmp -lgmpxx -lboost_system -lcrypto -lsodium $RUST_LIBS" +LIBZCASH_LIBS="-lgmp -lgmpxx $BOOST_SYSTEM_LIB -lcrypto -lsodium $RUST_LIBS" AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) @@ -859,16 +858,6 @@ else AC_MSG_RESULT(no) fi -dnl enable rust -AC_MSG_CHECKING([if rust should be enabled]) -if test x$enable_rust != xno; then - AC_MSG_RESULT(yes) - AC_DEFINE(ENABLE_RUST, 1, [Define to 1 to enable Rust language dependent functions]) - -else - AC_MSG_RESULT(no) -fi - AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) AM_CONDITIONAL([ENABLE_PROTON], [test "x$use_proton" = "xyes"]) @@ -898,7 +887,6 @@ 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_RUST],[test x$enable_rust = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) @@ -991,7 +979,6 @@ esac echo echo "Options used to compile and link:" echo " with wallet = $enable_wallet" -echo " with rust = $enable_rust" echo " with proton = $use_proton" echo " with zmq = $use_zmq" echo " with test = $use_tests" diff --git a/contrib/ci-workers/README.md b/contrib/ci-workers/README.md index 37f7ad833..8ce9dc764 100644 --- a/contrib/ci-workers/README.md +++ b/contrib/ci-workers/README.md @@ -5,29 +5,29 @@ 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 or if we anticipate many users will use - a platform, we may pre-emptively add an unsupported worker for it. +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. +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 -- Add a regular (non-latent) worker to the master.cfg for dev-ci.z.cash, and - deploy the changes. +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. -- Start a basic EC2 instance using the template AMI for the target OS. +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. -- Figure out which user to log into the instance with. +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 @@ -35,28 +35,28 @@ c. When adding workers start by adding workers for the "most common" Ansible protocol is balking. Try manually logging in with the same credentials to diagnose. -- Create `inventory/hosts` containing the following: +4. Create `inventory/hosts` containing the following: [zcash-ci-worker-unix] some-name ansible_host= ansible_ssh_user= -- 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. +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. -- Create an AMI from the instance. This is the worker AMI to put into the - master.cfg for dev-ci.z.cash. +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. -- SSH into the instance, and edit the worker config to connect to ci.z.cash. +7. SSH into the instance, and edit the worker config to connect to ci.z.cash. -- Create an AMI from the instance. This is the worker AMI to put into the - master.cfg for 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. -- Delete the instance (it is no longer needed). +9. Delete the instance (it is no longer needed). -- 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. +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/contrib/ci-workers/files/bashrc b/contrib/ci-workers/files/bashrc new file mode 100644 index 000000000..aaad18b92 --- /dev/null +++ b/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/contrib/ci-workers/tasks/install-brew.yml b/contrib/ci-workers/tasks/install-brew.yml new file mode 100644 index 000000000..5faedad0b --- /dev/null +++ b/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/contrib/ci-workers/templates/buildbot-worker.plist.j2 b/contrib/ci-workers/templates/buildbot-worker.plist.j2 new file mode 100644 index 000000000..225c73b8a --- /dev/null +++ b/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/contrib/ci-workers/templates/buildbot-worker.service.j2 b/contrib/ci-workers/templates/buildbot-worker.service.j2 index ffe497bcf..625323be6 100644 --- a/contrib/ci-workers/templates/buildbot-worker.service.j2 +++ b/contrib/ci-workers/templates/buildbot-worker.service.j2 @@ -5,11 +5,11 @@ After=network.target [Service] Type=forking -PIDFile=/home/{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/twistd.pid -WorkingDirectory=/home/{{ buildbot_worker_user }} -ExecStart={{ pip_bin_dir }}/buildbot-worker start {{ buildbot_worker_name }} -ExecReload={{ pip_bin_dir }}/buildbot-worker restart {{ buildbot_worker_name }} -ExecStop={{ pip_bin_dir }}/buildbot-worker stop {{ buildbot_worker_name }} +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 }} diff --git a/contrib/ci-workers/templates/host.j2 b/contrib/ci-workers/templates/host.j2 index 3a5abb0c2..65c4cb709 100644 --- a/contrib/ci-workers/templates/host.j2 +++ b/contrib/ci-workers/templates/host.j2 @@ -1,3 +1,3 @@ OS: {{ ansible_distribution }} {{ ansible_distribution_version }} Memory: {{ ansible_memtotal_mb }} MB -CPU: {{ ansible_processor[1] }} +CPU: {{ ansible_processor if ansible_processor is string else ansible_processor[1] }} ({{ ansible_processor_cores }} cores) diff --git a/contrib/ci-workers/unix.yml b/contrib/ci-workers/unix.yml index 6e6cc49c4..cbb693401 100644 --- a/contrib/ci-workers/unix.yml +++ b/contrib/ci-workers/unix.yml @@ -50,6 +50,7 @@ - name: Gathering Facts setup: + tags: deps - name: Fail if Python is the wrong version fail: @@ -66,34 +67,44 @@ - "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] + - name: Install pip [CentOS, MacOSX] include: tasks/install-pip.yml - when: ansible_distribution == 'CentOS' + when: ansible_distribution in ['CentOS', 'MacOSX'] - - name: Install required Python modules + - name: Install required Python system modules pip: name: "{{ item }}" state: latest - with_items: "{{ python_modules }}" - notify: restart buildbot-worker + executable: "{{ '/usr/local/bin/pip' if ansible_distribution == 'MacOSX' else omit }}" + with_items: "{{ system_modules }}" - name: Set up the Buildbot worker user user: @@ -102,9 +113,28 @@ 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 create-worker ~/{{ buildbot_worker_name }} + ~{{ 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: @@ -116,7 +146,7 @@ content: "{{ buildbot_worker_admin }}" dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/admin" owner: "{{ buildbot_worker_user }}" - group: "{{ buildbot_worker_user }}" + group: "{{ omit if ansible_distribution == 'MacOSX' else buildbot_worker_user }}" mode: "0644" - name: Set host details for Buildbot worker @@ -124,7 +154,15 @@ src: "{{ buildbot_worker_host_template }}" dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/host" owner: "{{ buildbot_worker_user }}" - group: "{{ 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 @@ -134,13 +172,32 @@ owner: root group: root mode: "0644" + when: ansible_distribution != 'MacOSX' notify: reload systemd - - name: Start Buildbot worker. + - 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 diff --git a/contrib/ci-workers/vars/Archlinux.yml b/contrib/ci-workers/vars/Archlinux.yml index ac4a44e5b..50e5577c3 100644 --- a/contrib/ci-workers/vars/Archlinux.yml +++ b/contrib/ci-workers/vars/Archlinux.yml @@ -2,6 +2,6 @@ buildbot_deps: - python2-pip build_deps: + - cmake - multilib/gcc - make -pip_bin_dir: /usr/bin diff --git a/contrib/ci-workers/vars/CentOS.yml b/contrib/ci-workers/vars/CentOS.yml index 7e09b0717..f577af5c0 100644 --- a/contrib/ci-workers/vars/CentOS.yml +++ b/contrib/ci-workers/vars/CentOS.yml @@ -2,6 +2,7 @@ buildbot_deps: [] # Empty to remove python-pip build_deps: - bzip2 + - cmake - gcc - gcc-c++ - make @@ -10,4 +11,3 @@ dist_deps: - pkgconfig # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in - python-devel - redhat-rpm-config -pip_bin_dir: /usr/bin diff --git a/contrib/ci-workers/vars/Debian.yml b/contrib/ci-workers/vars/Debian.yml index 992224721..b6a46f0cd 100644 --- a/contrib/ci-workers/vars/Debian.yml +++ b/contrib/ci-workers/vars/Debian.yml @@ -1,6 +1,6 @@ --- build_deps: - build-essential # Depends on g++, libc6-dev, make + - cmake dist_deps: - - pkg-config # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in - python-dev diff --git a/contrib/ci-workers/vars/Fedora.yml b/contrib/ci-workers/vars/Fedora.yml index 1c6b0e0f3..2a7351c69 100644 --- a/contrib/ci-workers/vars/Fedora.yml +++ b/contrib/ci-workers/vars/Fedora.yml @@ -1,5 +1,6 @@ --- build_deps: + - cmake - gcc - gcc-c++ - make diff --git a/contrib/ci-workers/vars/FreeBSD.yml b/contrib/ci-workers/vars/FreeBSD.yml index 65909d71d..4b1f01997 100644 --- a/contrib/ci-workers/vars/FreeBSD.yml +++ b/contrib/ci-workers/vars/FreeBSD.yml @@ -2,6 +2,7 @@ buildbot_deps: - py27-pip build_deps: + - cmake - gcc - gmake dist_deps: diff --git a/contrib/ci-workers/vars/MacOSX.yml b/contrib/ci-workers/vars/MacOSX.yml new file mode 100644 index 000000000..80b1ae608 --- /dev/null +++ b/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/contrib/ci-workers/vars/Ubuntu.yml b/contrib/ci-workers/vars/Ubuntu.yml index 4acca499b..0d0f584b4 100644 --- a/contrib/ci-workers/vars/Ubuntu.yml +++ b/contrib/ci-workers/vars/Ubuntu.yml @@ -1,5 +1,4 @@ --- build_deps: - build-essential # Depends on g++, libc6-dev, make -dist_deps: - - pkg-config # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - cmake diff --git a/contrib/ci-workers/vars/default.yml b/contrib/ci-workers/vars/default.yml index 38c5afc8e..a0b0da9e6 100644 --- a/contrib/ci-workers/vars/default.yml +++ b/contrib/ci-workers/vars/default.yml @@ -7,6 +7,7 @@ buildbot_deps: # Dependencies required to download files fetch_deps: + - curl # For depends/ - git - wget # For zcutil/fetch-params.sh @@ -15,9 +16,11 @@ conf_deps: - autoconf - automake - m4 + - pkg-config # Dependencies required to compile Zcash build_deps: + - cmake - g++ - gcc - make @@ -34,6 +37,10 @@ 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 @@ -44,6 +51,3 @@ buildbot_modules: rpc_test_modules: - pyblake2 - pyzmq - -# Environment variables -pip_bin_dir: /usr/local/bin diff --git a/contrib/debian/changelog b/contrib/debian/changelog index c0b1d157f..d36688954 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,63 @@ +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. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index 3fbaa848b..7b0f72fce 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -4,8 +4,9 @@ Upstream-Contact: Zcash Company Source: https://github.com/zcash/zcash Files: * -Copyright: 2016-2017, The Zcash developers - 2009-2017, Bitcoin Core developers +Copyright: 2016-2018, The Zcash developers + 2009-2018, Bitcoin Core developers + 2009-2018, 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. diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index bee8f3cc1..43c825bde 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/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. @@ -6,6 +6,7 @@ Otherwise the exit status will be 1 and it will log which executables failed whi Needs `readelf` (for ELF) and `objdump` (for PE). ''' from __future__ import division,print_function,unicode_literals +import struct import subprocess import sys import os @@ -171,6 +172,8 @@ CHECKS = { ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_PE_NX) +], +'MachO64': [ ] } @@ -181,6 +184,8 @@ def identify_executable(executable): return 'PE' elif magic.startswith(b'\x7fELF'): return 'ELF' + elif struct.unpack('I', magic)[0] == 0xFEEDFACF: + return 'MachO64' return None if __name__ == '__main__': diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 900a80dcf..52b48ef74 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python # Copyright (c) 2014 Wladimir J. van der Laan # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index fed7626aa..324b7bcd8 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python2 ''' Test script for security-check.py ''' diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index de9e405e1..aab968337 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "zcash-1.0.15" +name: "zcash-2.0.1-rc1" enable_cache: true distro: "debian" suites: @@ -124,7 +124,8 @@ script: | 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 {} \; - find ${DISTNAME}/lib -type f -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 ../../ diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index b08bd9c3b..44fc4e356 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -150,7 +150,8 @@ script: | 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 {} \; - find ${DISTNAME}/lib -type f -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 ../../ diff --git a/contrib/linearize/linearize-data.py b/contrib/linearize/linearize-data.py index 0f6fde2a6..8badb4b31 100755 --- a/contrib/linearize/linearize-data.py +++ b/contrib/linearize/linearize-data.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # linearize-data.py: Construct a linear, no-fork version of the chain. # diff --git a/contrib/linearize/linearize-hashes.py b/contrib/linearize/linearize-hashes.py index bed9cc307..7e9cf8898 100755 --- a/contrib/linearize/linearize-hashes.py +++ b/contrib/linearize/linearize-hashes.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # linearize-hashes.py: List blocks in a linear, no-fork version of the chain. # diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 4e23bb111..c6a2ce636 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -1,5 +1,5 @@ -#!/usr/bin/python -# Copyright (c) 2014 Wladmir J. van der Laan +#!/usr/bin/env python +# Copyright (c) 2014 Wladimir J. van der Laan # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' diff --git a/depends/Makefile b/depends/Makefile index 472d87885..e58dd510f 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -14,6 +14,7 @@ BASEDIR = $(CURDIR) HASH_LENGTH:=11 DOWNLOAD_CONNECT_TIMEOUT:=10 DOWNLOAD_RETRIES:=3 +CRATE_REGISTRY:=vendored-sources host:=$(BUILD) ifneq ($(HOST),) @@ -72,15 +73,14 @@ include builders/$(build_os).mk include builders/default.mk include packages/packages.mk -rust_packages_$(NO_RUST) = $(rust_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) proton_packages_$(NO_PROTON) = $(proton_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages_) $(proton_packages_) $(wallet_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages) $(proton_packages_) $(wallet_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) all_packages = $(packages) $(native_packages) -meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk +meta_depends = Makefile funcs.mk builders/default.mk hosts/default.mk hosts/$(host_os).mk builders/$(build_os).mk cargo-checksum.sh $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) diff --git a/depends/cargo-checksum.sh b/depends/cargo-checksum.sh new file mode 100755 index 000000000..535cc0bfd --- /dev/null +++ b/depends/cargo-checksum.sh @@ -0,0 +1,13 @@ +echo "{\"files\":{$( +find . -type f | # Get list of file paths +grep -v $1 | # Exclude Makefile hashes +grep -v '[.]stamp_' | # Exclude Makefile stamps +sed 's|^[.]/||' | # Remove leading ./ +sort | # Sort (for uniformity) +xargs $2 | # Get SHA256 hashes (assumes standard 'H(A) A' format) +awk -v OFS='":"' '{print $2, $1}' | # 'H(A) A' -> 'A":"H(A)' +sed 's|^|"|' | # 'A":"H(A)' -> '"A":"H(A)' +sed 's|$|"|' | # '"A":"H(A)' -> '"A":"H(A)"' +tr '\n' ',' | # Concatenate lines with commas +sed 's|,$||' # Remove any trailing comma (to fit JSON spec) +)},\"package\":$3}" > .cargo-checksum.json diff --git a/depends/funcs.mk b/depends/funcs.mk index df305a74a..3d89de8a7 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -30,6 +30,21 @@ define fetch_file rm -rf $$($(1)_download_dir) )) endef +define generate_crate_checksum +$(BASEDIR)/cargo-checksum.sh "$($(1)_file_name)" "$(build_SHA256SUM)" "\"$($(1)_sha256_hash)\"" +endef + +define generate_unpackaged_crate_checksum +$(BASEDIR)/cargo-checksum.sh "$($(1)_file_name)" "$(build_SHA256SUM)" "null" +endef + +define vendor_crate_source +mkdir -p $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY) && \ +cp -r $($(1)_extract_dir) $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY)/$($(1)_crate_name) && \ +cd $($(1)_staging_prefix_dir)/$(CRATE_REGISTRY)/$($(1)_crate_versioned_name) && \ +rm -r `basename $($(1)_patch_dir)` .stamp_* .$($(1)_file_name).hash +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)) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 5eaeddc26..d01e8b5a3 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -8,7 +8,7 @@ darwin_CXX=g++-6 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysro darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) -darwin_release_CFLAGS=-O2 +darwin_release_CFLAGS=-O1 darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index 65ab1702b..b217bfdb5 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -3,7 +3,7 @@ mingw32_CXX=x86_64-w64-mingw32-g++-posix mingw32_CFLAGS=-pipe -std=c11 mingw32_CXXFLAGS=$(mingw32_CFLAGS) -std=c++11 -mingw32_release_CFLAGS=-O2 +mingw32_release_CFLAGS=-O1 mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS) mingw32_debug_CFLAGS=-O1 diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 3ff5a7bd9..404d94c51 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -1,6 +1,6 @@ package=bdb $(package)_version=6.2.23 -$(package)_download_path=http://download.oracle.com/berkeley-db +$(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 @@ -13,6 +13,7 @@ $(package)_cxxflags=-std=c++11 endef define $(package)_preprocess_cmds + sed -i.old 's/WinIoCtl.h/winioctl.h/g' src/dbinc/win_db.h && \ sed -i.old 's/__atomic_compare_exchange\\(/__atomic_compare_exchange_db(/' src/dbinc/atomic.h && \ sed -i.old 's/atomic_init/atomic_init_db/' src/dbinc/atomic.h src/mp/mp_region.c src/mp/mp_mvcc.c src/mp/mp_fget.c src/mutex/mut_method.c src/mutex/mut_tas.c endef diff --git a/depends/packages/crate_aes.mk b/depends/packages/crate_aes.mk new file mode 100644 index 000000000..e53d72679 --- /dev/null +++ b/depends/packages/crate_aes.mk @@ -0,0 +1,15 @@ +package=crate_aes +$(package)_crate_name=aes +$(package)_version=0.2.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=e6fb1737cdc8da3db76e90ca817a194249a38fcb500c2e6ecec39b29448aa873 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_aes_soft.mk b/depends/packages/crate_aes_soft.mk new file mode 100644 index 000000000..bd5a9b585 --- /dev/null +++ b/depends/packages/crate_aes_soft.mk @@ -0,0 +1,15 @@ +package=crate_aes_soft +$(package)_crate_name=aes-soft +$(package)_version=0.2.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_aesni.mk b/depends/packages/crate_aesni.mk new file mode 100644 index 000000000..6f93d155f --- /dev/null +++ b/depends/packages/crate_aesni.mk @@ -0,0 +1,15 @@ +package=crate_aesni +$(package)_crate_name=aesni +$(package)_version=0.4.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=f2838c142db62c0c6aea0a24054c46d35488532fdaea0f51dbeba430f0985df5 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_arrayvec.mk b/depends/packages/crate_arrayvec.mk new file mode 100644 index 000000000..7de373351 --- /dev/null +++ b/depends/packages/crate_arrayvec.mk @@ -0,0 +1,15 @@ +package=crate_arrayvec +$(package)_crate_name=arrayvec +$(package)_version=0.4.7 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_bellman.mk b/depends/packages/crate_bellman.mk new file mode 100644 index 000000000..5c7d904ca --- /dev/null +++ b/depends/packages/crate_bellman.mk @@ -0,0 +1,15 @@ +package=crate_bellman +$(package)_crate_name=bellman +$(package)_version=0.1.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=eae372472c7ea8f7c8fc6a62f7d5535db8302de7f1aafda2e13a97c4830d3bcf +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_bit_vec.mk b/depends/packages/crate_bit_vec.mk new file mode 100644 index 000000000..40575088e --- /dev/null +++ b/depends/packages/crate_bit_vec.mk @@ -0,0 +1,15 @@ +package=crate_bit_vec +$(package)_crate_name=bit-vec +$(package)_version=0.4.4 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_bitflags.mk b/depends/packages/crate_bitflags.mk new file mode 100644 index 000000000..844ec37e8 --- /dev/null +++ b/depends/packages/crate_bitflags.mk @@ -0,0 +1,15 @@ +package=crate_bitflags +$(package)_crate_name=bitflags +$(package)_version=1.0.1 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_blake2_rfc.mk b/depends/packages/crate_blake2_rfc.mk new file mode 100644 index 000000000..73ef7edde --- /dev/null +++ b/depends/packages/crate_blake2_rfc.mk @@ -0,0 +1,16 @@ +package=crate_blake2_rfc +$(package)_crate_name=blake2-rfc +$(package)_download_path=https://github.com/gtank/$($(package)_crate_name)/archive/ +$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz +$(package)_download_file=$($(package)_git_commit).tar.gz +$(package)_sha256_hash=8a873cc41f02e669e8071ab5919931dd4263f050becf0c19820b0497c07b0ca3 +$(package)_git_commit=7a5b5fc99ae483a0043db7547fb79a6fa44b88a9 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_unpackaged_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_block_cipher_trait.mk b/depends/packages/crate_block_cipher_trait.mk new file mode 100644 index 000000000..a2ef96576 --- /dev/null +++ b/depends/packages/crate_block_cipher_trait.mk @@ -0,0 +1,15 @@ +package=crate_block_cipher_trait +$(package)_crate_name=block-cipher-trait +$(package)_version=0.5.3 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_byte_tools.mk b/depends/packages/crate_byte_tools.mk new file mode 100644 index 000000000..03edeeb70 --- /dev/null +++ b/depends/packages/crate_byte_tools.mk @@ -0,0 +1,15 @@ +package=crate_byte_tools +$(package)_crate_name=byte-tools +$(package)_version=0.2.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_byteorder.mk b/depends/packages/crate_byteorder.mk new file mode 100644 index 000000000..0df286920 --- /dev/null +++ b/depends/packages/crate_byteorder.mk @@ -0,0 +1,15 @@ +package=crate_byteorder +$(package)_crate_name=byteorder +$(package)_version=1.2.2 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_constant_time_eq.mk b/depends/packages/crate_constant_time_eq.mk new file mode 100644 index 000000000..b782dfb22 --- /dev/null +++ b/depends/packages/crate_constant_time_eq.mk @@ -0,0 +1,15 @@ +package=crate_constant_time_eq +$(package)_crate_name=constant_time_eq +$(package)_version=0.1.3 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_crossbeam.mk b/depends/packages/crate_crossbeam.mk new file mode 100644 index 000000000..3b31aa53b --- /dev/null +++ b/depends/packages/crate_crossbeam.mk @@ -0,0 +1,15 @@ +package=crate_crossbeam +$(package)_crate_name=crossbeam +$(package)_version=0.3.2 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_digest.mk b/depends/packages/crate_digest.mk new file mode 100644 index 000000000..029ccd7bd --- /dev/null +++ b/depends/packages/crate_digest.mk @@ -0,0 +1,15 @@ +package=crate_digest +$(package)_crate_name=digest +$(package)_version=0.7.2 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_fpe.mk b/depends/packages/crate_fpe.mk new file mode 100644 index 000000000..ba6e344ac --- /dev/null +++ b/depends/packages/crate_fpe.mk @@ -0,0 +1,15 @@ +package=crate_fpe +$(package)_crate_name=fpe +$(package)_version=0.1.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ce3371c82bfbd984f624cab093f55e7336f5a6e589f8518e1258f54f011b89ad +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_fuchsia_zircon.mk b/depends/packages/crate_fuchsia_zircon.mk new file mode 100644 index 000000000..f8e10aa55 --- /dev/null +++ b/depends/packages/crate_fuchsia_zircon.mk @@ -0,0 +1,15 @@ +package=crate_fuchsia_zircon +$(package)_crate_name=fuchsia-zircon +$(package)_version=0.3.3 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_fuchsia_zircon_sys.mk b/depends/packages/crate_fuchsia_zircon_sys.mk new file mode 100644 index 000000000..bc978bbb2 --- /dev/null +++ b/depends/packages/crate_fuchsia_zircon_sys.mk @@ -0,0 +1,15 @@ +package=crate_fuchsia_zircon_sys +$(package)_crate_name=fuchsia-zircon-sys +$(package)_version=0.3.3 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_futures.mk b/depends/packages/crate_futures.mk new file mode 100644 index 000000000..3e0e6f990 --- /dev/null +++ b/depends/packages/crate_futures.mk @@ -0,0 +1,15 @@ +package=crate_futures +$(package)_crate_name=futures +$(package)_version=0.1.21 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_futures_cpupool.mk b/depends/packages/crate_futures_cpupool.mk new file mode 100644 index 000000000..0ff2069ed --- /dev/null +++ b/depends/packages/crate_futures_cpupool.mk @@ -0,0 +1,15 @@ +package=crate_futures_cpupool +$(package)_crate_name=futures-cpupool +$(package)_version=0.1.8 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_generic_array.mk b/depends/packages/crate_generic_array.mk new file mode 100644 index 000000000..ab4a566ee --- /dev/null +++ b/depends/packages/crate_generic_array.mk @@ -0,0 +1,15 @@ +package=crate_generic_array +$(package)_crate_name=generic-array +$(package)_version=0.9.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_lazy_static.mk b/depends/packages/crate_lazy_static.mk new file mode 100644 index 000000000..208dc1dad --- /dev/null +++ b/depends/packages/crate_lazy_static.mk @@ -0,0 +1,15 @@ +package=crate_lazy_static +$(package)_crate_name=lazy_static +$(package)_version=1.0.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_libc.mk b/depends/packages/crate_libc.mk new file mode 100644 index 000000000..2e1a2c074 --- /dev/null +++ b/depends/packages/crate_libc.mk @@ -0,0 +1,15 @@ +package=crate_libc +$(package)_crate_name=libc +$(package)_version=0.2.40 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_nodrop.mk b/depends/packages/crate_nodrop.mk new file mode 100644 index 000000000..1997574c0 --- /dev/null +++ b/depends/packages/crate_nodrop.mk @@ -0,0 +1,15 @@ +package=crate_nodrop +$(package)_crate_name=nodrop +$(package)_version=0.1.12 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_num_bigint.mk b/depends/packages/crate_num_bigint.mk new file mode 100644 index 000000000..bc1ff4a32 --- /dev/null +++ b/depends/packages/crate_num_bigint.mk @@ -0,0 +1,15 @@ +package=crate_num_bigint +$(package)_crate_name=num-bigint +$(package)_version=0.2.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=3eceac7784c5dc97c2d6edf30259b4e153e6e2b42b3c85e9a6e9f45d06caef6e +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_num_cpus.mk b/depends/packages/crate_num_cpus.mk new file mode 100644 index 000000000..fdaebe4db --- /dev/null +++ b/depends/packages/crate_num_cpus.mk @@ -0,0 +1,15 @@ +package=crate_num_cpus +$(package)_crate_name=num_cpus +$(package)_version=1.8.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_num_integer.mk b/depends/packages/crate_num_integer.mk new file mode 100644 index 000000000..ea479e8e7 --- /dev/null +++ b/depends/packages/crate_num_integer.mk @@ -0,0 +1,15 @@ +package=crate_num_integer +$(package)_crate_name=num-integer +$(package)_version=0.1.39 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_num_traits.mk b/depends/packages/crate_num_traits.mk new file mode 100644 index 000000000..f0ffbe5a1 --- /dev/null +++ b/depends/packages/crate_num_traits.mk @@ -0,0 +1,15 @@ +package=crate_num_traits +$(package)_crate_name=num-traits +$(package)_version=0.2.5 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_opaque_debug.mk b/depends/packages/crate_opaque_debug.mk new file mode 100644 index 000000000..7d7a5e914 --- /dev/null +++ b/depends/packages/crate_opaque_debug.mk @@ -0,0 +1,15 @@ +package=crate_opaque_debug +$(package)_crate_name=opaque-debug +$(package)_version=0.1.1 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_pairing.mk b/depends/packages/crate_pairing.mk new file mode 100644 index 000000000..c81e23bed --- /dev/null +++ b/depends/packages/crate_pairing.mk @@ -0,0 +1,15 @@ +package=crate_pairing +$(package)_crate_name=pairing +$(package)_version=0.14.2 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ceda21136251c6d5a422d3d798d8ac22515a6e8d3521bb60c59a8349d36d0d57 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_rand.mk b/depends/packages/crate_rand.mk new file mode 100644 index 000000000..16fb81753 --- /dev/null +++ b/depends/packages/crate_rand.mk @@ -0,0 +1,15 @@ +package=crate_rand +$(package)_crate_name=rand +$(package)_version=0.4.2 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_sapling_crypto.mk b/depends/packages/crate_sapling_crypto.mk new file mode 100644 index 000000000..2da5e2406 --- /dev/null +++ b/depends/packages/crate_sapling_crypto.mk @@ -0,0 +1,16 @@ +package=crate_sapling_crypto +$(package)_crate_name=sapling-crypto +$(package)_download_path=https://github.com/zcash-hackworks/$($(package)_crate_name)/archive/ +$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz +$(package)_download_file=$($(package)_git_commit).tar.gz +$(package)_sha256_hash=ae3a122b1f1ce97b4e80e0e8542e19aa1516e99e6c72875688c886af1a881558 +$(package)_git_commit=21084bde2019c04bd34208e63c3560fe2c02fb0e +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_unpackaged_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_stream_cipher.mk b/depends/packages/crate_stream_cipher.mk new file mode 100644 index 000000000..6429a6179 --- /dev/null +++ b/depends/packages/crate_stream_cipher.mk @@ -0,0 +1,15 @@ +package=crate_stream_cipher +$(package)_crate_name=stream-cipher +$(package)_version=0.1.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ac49bc6cb2847200d18bfb738ce89448570f4aa1c34ac0348db6205ee69a0777 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_typenum.mk b/depends/packages/crate_typenum.mk new file mode 100644 index 000000000..bc5a235a8 --- /dev/null +++ b/depends/packages/crate_typenum.mk @@ -0,0 +1,15 @@ +package=crate_typenum +$(package)_crate_name=typenum +$(package)_version=1.10.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_winapi.mk b/depends/packages/crate_winapi.mk new file mode 100644 index 000000000..6aafb0251 --- /dev/null +++ b/depends/packages/crate_winapi.mk @@ -0,0 +1,15 @@ +package=crate_winapi +$(package)_crate_name=winapi +$(package)_version=0.3.4 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_winapi_i686_pc_windows_gnu.mk b/depends/packages/crate_winapi_i686_pc_windows_gnu.mk new file mode 100644 index 000000000..ff8c5e76f --- /dev/null +++ b/depends/packages/crate_winapi_i686_pc_windows_gnu.mk @@ -0,0 +1,15 @@ +package=crate_winapi_i686_pc_windows_gnu +$(package)_crate_name=winapi-i686-pc-windows-gnu +$(package)_version=0.4.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_winapi_x86_64_pc_windows_gnu.mk b/depends/packages/crate_winapi_x86_64_pc_windows_gnu.mk new file mode 100644 index 000000000..725baf00f --- /dev/null +++ b/depends/packages/crate_winapi_x86_64_pc_windows_gnu.mk @@ -0,0 +1,15 @@ +package=crate_winapi_x86_64_pc_windows_gnu +$(package)_crate_name=winapi-x86_64-pc-windows-gnu +$(package)_version=0.4.0 +$(package)_download_path=https://static.crates.io/crates/$($(package)_crate_name) +$(package)_file_name=$($(package)_crate_name)-$($(package)_version).crate +$(package)_sha256_hash=712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/crate_zip32.mk b/depends/packages/crate_zip32.mk new file mode 100644 index 000000000..e47f1fb94 --- /dev/null +++ b/depends/packages/crate_zip32.mk @@ -0,0 +1,16 @@ +package=crate_zip32 +$(package)_crate_name=zip32 +$(package)_download_path=https://github.com/zcash-hackworks/$($(package)_crate_name)/archive/ +$(package)_file_name=$(package)-$($(package)_git_commit).tar.gz +$(package)_download_file=$($(package)_git_commit).tar.gz +$(package)_sha256_hash=b0b011ea96524f0d918a44c7ab8a3dec6270879d1ff03d7dbda6c676d25caa7e +$(package)_git_commit=176470ef41583b5bd0bd749bd1b61d417aa8ec79 +$(package)_crate_versioned_name=$($(package)_crate_name) + +define $(package)_preprocess_cmds + $(call generate_unpackaged_crate_checksum,$(package)) +endef + +define $(package)_stage_cmds + $(call vendor_crate_source,$(package)) +endef diff --git a/depends/packages/googletest.mk b/depends/packages/googletest.mk index 409c83a1b..00ee3f23b 100644 --- a/depends/packages/googletest.mk +++ b/depends/packages/googletest.mk @@ -5,6 +5,11 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_download_file=release-$($(package)_version).tar.gz $(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 +define $(package)_set_vars +$(package)_cxxflags+=-std=c++11 +$(package)_cxxflags_linux=-fPIC +endef + ifeq ($(build_os),darwin) define $(package)_set_vars $(package)_build_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" CXX="$($(package)_cxx)" CXXFLAGS="$($(package)_cxxflags)" @@ -19,9 +24,10 @@ define $(package)_build_cmds endef else $(package)_install=install + define $(package)_build_cmds - $(MAKE) -C googlemock/make CXXFLAGS=-fPIC gmock.a && \ - $(MAKE) -C googletest/make CXXFLAGS=-fPIC gtest.a + $(MAKE) -C googlemock/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gmock.a && \ + $(MAKE) -C googletest/make CC="$($(package)_cc)" CXX="$($(package)_cxx)" AR="$($(package)_ar)" CXXFLAGS="$($(package)_cxxflags)" gtest.a endef endif diff --git a/depends/packages/librustzcash.mk b/depends/packages/librustzcash.mk index 689082f8f..d520eff60 100644 --- a/depends/packages/librustzcash.mk +++ b/depends/packages/librustzcash.mk @@ -3,9 +3,26 @@ $(package)_version=0.1 $(package)_download_path=https://github.com/zcash/$(package)/archive $(package)_file_name=$(package)-$($(package)_git_commit).tar.gz $(package)_download_file=$($(package)_git_commit).tar.gz -$(package)_sha256_hash=a5760a90d4a1045c8944204f29fa2a3cf2f800afee400f88bf89bbfe2cce1279 -$(package)_git_commit=91348647a86201a9482ad4ad68398152dc3d635e -$(package)_dependencies=rust +$(package)_sha256_hash=e9a488a8bbecf7fb237a32dadd65133211ef61616d44cf55609e029837a41004 +$(package)_git_commit=f5e5cb24e1bd756a02fc4a3fd2b824238ccd15ad +$(package)_dependencies=rust $(rust_crates) +$(package)_patches=cargo.config + +ifeq ($(host_os),mingw32) +$(package)_library_file=target/x86_64-pc-windows-gnu/release/rustzcash.lib +else +$(package)_library_file=target/release/librustzcash.a +endif + +define $(package)_set_vars +$(package)_build_opts=--frozen --release +$(package)_build_opts_mingw32=--target=x86_64-pc-windows-gnu +endef + +define $(package)_preprocess_cmds + mkdir .cargo && \ + cat $($(package)_patch_dir)/cargo.config | sed 's|CRATE_REGISTRY|$(host_prefix)/$(CRATE_REGISTRY)|' > .cargo/config +endef ifeq ($(host_os),mingw32) define $(package)_build_cmds @@ -13,7 +30,7 @@ define $(package)_build_cmds endef else define $(package)_build_cmds - cargo build --release + cargo build $($(package)_build_opts) endef endif @@ -28,7 +45,7 @@ else define $(package)_stage_cmds mkdir $($(package)_staging_dir)$(host_prefix)/lib/ && \ mkdir $($(package)_staging_dir)$(host_prefix)/include/ && \ - cp target/release/librustzcash.a $($(package)_staging_dir)$(host_prefix)/lib/ && \ + cp $($(package)_library_file) $($(package)_staging_dir)$(host_prefix)/lib/ && \ cp include/librustzcash.h $($(package)_staging_dir)$(host_prefix)/include/ endef endif diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index f80cd6d25..dec8ecef6 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,8 +1,8 @@ package=openssl -$(package)_version=1.1.0d +$(package)_version=1.1.0h $(package)_download_path=https://www.openssl.org/source $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=7d5ebb9e89756545c156ff9c13cf2aa6214193b010a468a3bc789c3c28fe60df +$(package)_sha256_hash=5835626cde9e99656585fc7aaa2302a73a7e1340bf8c14fd635a62c66802a517 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 9174db320..a2225f72a 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -7,12 +7,52 @@ else zcash_packages := libgmp libsodium endif +rust_crates := \ + crate_aes \ + crate_aesni \ + crate_aes_soft \ + crate_arrayvec \ + crate_bellman \ + crate_bitflags \ + crate_bit_vec \ + crate_blake2_rfc \ + crate_block_cipher_trait \ + crate_byte_tools \ + crate_byteorder \ + crate_constant_time_eq \ + crate_crossbeam \ + crate_digest \ + crate_fpe \ + crate_fuchsia_zircon \ + crate_fuchsia_zircon_sys \ + crate_futures_cpupool \ + crate_futures \ + crate_generic_array \ + crate_lazy_static \ + crate_libc \ + crate_nodrop \ + crate_num_bigint \ + crate_num_cpus \ + crate_num_integer \ + crate_num_traits \ + crate_opaque_debug \ + crate_pairing \ + crate_rand \ + crate_sapling_crypto \ + crate_stream_cipher \ + crate_typenum \ + crate_winapi_i686_pc_windows_gnu \ + crate_winapi \ + crate_winapi_x86_64_pc_windows_gnu \ + crate_zip32 +rust_packages := rust $(rust_crates) librustzcash +native_packages := native_ccache + +wallet_packages=bdb + ifeq ($(host_os),linux) packages := boost openssl libevent zeromq $(zcash_packages) googletest #googlemock else packages := boost openssl libevent zeromq $(zcash_packages) libcurl googletest #googlemock endif -native_packages := native_ccache - -wallet_packages=bdb diff --git a/depends/packages/rust.mk b/depends/packages/rust.mk index 2e3f0b204..a08ac2747 100644 --- a/depends/packages/rust.mk +++ b/depends/packages/rust.mk @@ -1,17 +1,52 @@ package=rust -$(package)_version=1.16.0 +$(package)_version=1.28.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=2a1390340db1d24a9498036884e6b2748e9b4b057fc5219694e298bdaa37b810 +$(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash_darwin=5d7a70ed4701fe9410041c1eea025c95cad97e5b3d8acc46426f9ac4f9f02393 +$(package)_file_name_mingw32=rust-$($(package)_version)-x86_64-pc-windows-gnu.tar.gz +$(package)_sha256_hash_mingw32=55c07426f791c51c8a2b6934b35784175c4abb4e03f123f3e847109c4dc1ad8b + ifeq ($(build_os),darwin) -$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 +$(package)_file_name=$($(package)_file_name_darwin) +$(package)_sha256_hash=$($(package)_sha256_hash_darwin) else ifeq ($(host_os),mingw32) -$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz -$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 +$(package)_file_name=$($(package)_file_name_mingw32) +$(package)_sha256_hash=$($(package)_sha256_hash_mingw32) else -$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd +$(package)_file_name=$($(package)_file_name_linux) +$(package)_sha256_hash=$($(package)_sha256_hash_linux) endif +ifeq ($(host_os),mingw32) +$(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 mingw32 && \ + tar --strip-components=1 -xf $($(package)_source) -C mingw32 && \ + mkdir buildos && \ + tar --strip-components=1 -xf $($(package)_source_dir)/$($(package)_file_name_$(build_os)) -C buildos +endef + +define $(package)_stage_cmds + ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig && \ + cp -r ../mingw32/rust-std-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu $($(package)_staging_dir)$(host_prefix)/native/lib/rustlib +endef +else + define $(package)_stage_cmds ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig endef +endif diff --git a/depends/patches/boost/deprecated_auto_ptr.patch b/depends/patches/boost/deprecated_auto_ptr.patch deleted file mode 100644 index 5ec38e271..000000000 --- a/depends/patches/boost/deprecated_auto_ptr.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- boost_1_62_0-orig/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp 2016-09-29 14:03:47.317997658 +1300 -+++ boost_1_62_0/boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp 2016-09-29 14:07:41.308726372 +1300 -@@ -13,10 +13,16 @@ - - #if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) - #include -+#include - #include - #include - #include // for std::auto_ptr - #include -+ -+#if defined( BOOST_SP_DISABLE_DEPRECATED ) -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -+#endif - #endif - - #ifdef BOOST_SPIRIT_THREADSAFE -@@ -370,4 +376,10 @@ - - }} // namespace boost::spirit - -+#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) -+#if defined( BOOST_SP_DISABLE_DEPRECATED ) -+#pragma GCC diagnostic pop -+#endif -+#endif -+ - #endif diff --git a/depends/patches/boost/include_poll.patch b/depends/patches/boost/include_poll.patch deleted file mode 100644 index b7e544b5f..000000000 --- a/depends/patches/boost/include_poll.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- boost_1_62_0-orig/boost/asio/detail/socket_types.hpp 2016-09-21 15:33:21.000000000 +0100 -+++ boost_1_62_0/boost/asio/detail/socket_types.hpp 2016-10-18 03:08:41.712254217 +0100 -@@ -58,7 +58,7 @@ - #else - # include - # if !defined(__SYMBIAN32__) --# include -+# include - # endif - # include - # include diff --git a/depends/patches/librustzcash/cargo.config b/depends/patches/librustzcash/cargo.config new file mode 100644 index 000000000..a0252d1c6 --- /dev/null +++ b/depends/patches/librustzcash/cargo.config @@ -0,0 +1,23 @@ +[source.crates-io] +replace-with = "vendored-sources" + +[source."https://github.com/gtank/blake2-rfc"] +git = "https://github.com/gtank/blake2-rfc" +rev = "7a5b5fc99ae483a0043db7547fb79a6fa44b88a9" +replace-with = "vendored-sources" + +[source."https://github.com/zcash-hackworks/sapling-crypto"] +git = "https://github.com/zcash-hackworks/sapling-crypto" +rev = "21084bde2019c04bd34208e63c3560fe2c02fb0e" +replace-with = "vendored-sources" + +[source."https://github.com/zcash-hackworks/zip32"] +git = "https://github.com/zcash-hackworks/zip32" +rev = "176470ef41583b5bd0bd749bd1b61d417aa8ec79" +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "CRATE_REGISTRY" + +[target.x86_64-pc-windows-gnu] +linker = "x86_64-w64-mingw32-gcc" diff --git a/doc/Doxyfile b/doc/Doxyfile index a423a7e9f..84154e6ec 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -870,7 +870,7 @@ HTML_FILE_EXTENSION = .html # 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 adviced to generate a default header using "doxygen -w html +# 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 diff --git a/doc/authors.md b/doc/authors.md index 8f249b1c0..e4dfec076 100644 --- a/doc/authors.md +++ b/doc/authors.md @@ -1,64 +1,80 @@ Zcash Contributors ================== -Jack Grigg (601) -Simon Liu (297) -Sean Bowe (193) -Daira Hopwood (102) -Wladimir J. van der Laan (71) +Jack Grigg (760) +Simon Liu (352) +Sean Bowe (263) +Daira Hopwood (110) +Jay Graber (84) +Wladimir J. van der Laan (81) Taylor Hornby (65) -Jay Graber (61) Nathan Wilcox (56) -Jonas Schnelli (49) +Jonas Schnelli (55) +Pieter Wuille (50) Kevin Gallagher (38) -Cory Fields (30) -Pieter Wuille (24) +Eirik Ogilvie-Wigley (36) +Cory Fields (35) syd (15) +Matt Corallo (13) +Paige Peterson (10) +MarcoFalke (10) nomnombtc (9) -Paige Peterson (9) -Matt Corallo (9) +Jonathan "Duke" Leto (9) +kozyilmaz (8) fanquake (8) -MarcoFalke (7) +Jeff Garzik (7) +Gregory Maxwell (7) +Ariel Gabizon (7) Luke Dashjr (6) +Larry Ruane (6) +Daniel Cousens (6) +Pavel Janík (5) +Karl-Johan Alm (5) Johnathan Corgan (5) -Gregory Maxwell (5) -Ariel Gabizon (5) -kozyilmaz (4) Philip Kaufmann (4) Peter Todd (4) Patrick Strateman (4) -Karl-Johan Alm (4) +João Barbosa (4) Jorge Timón (4) -Jeff Garzik (4) +Duke Leto (4) David Mercer (4) -Daniel Cousens (4) lpescher (3) Suhas Daftuar (3) -Pavel Janík (3) -João Barbosa (3) +Per Grön (3) +Patick Strateman (3) +Jason Davies (3) +James O'Beirne (3) +Daniel Kraft (3) Ariel (3) Alfie John (3) str4d (2) +rofl0r (2) paveljanik (2) +mruddy (2) kpcyrd (2) +ca333 (2) aniemerg (2) +UdjinM6 (2) Scott (2) Robert C. Seacord (2) -Per Grön (2) +Pejvan (2) +Pavol Rusnak (2) Pavel Vasin (2) +Matthew King (2) +Kaz Wesley (2) Joe Turgeon (2) -Jason Davies (2) Jack Gavigan (2) ITH4Coinomia (2) Gavin Andresen (2) -Daniel Kraft (2) +Brad Miller (2) Bjorn Hjortsberg (2) Amgad Abdelhafez (2) +Alex Morcos (2) zathras-crypto (1) unsystemizer (1) practicalswift (1) -mruddy (1) mrbandrews (1) +mdr0id (1) kazcw (1) jc (1) isle2983 (1) @@ -69,10 +85,16 @@ daniel (1) calebogden (1) ayleph (1) Tom Ritter (1) +Tom Harding (1) Stephen (1) S. Matthew English (1) Ross Nicoll (1) +Richard Littauer (1) René Nyffenegger (1) +R E Broadley (1) +Puru (1) +Peter Pratscher (1) +Pedro Branco (1) Paul Georgiou (1) Paragon Initiative Enterprises, LLC (1) Nicolas DORIER (1) @@ -84,10 +106,11 @@ Mark Friedenbach (1) Marius Kjærstad (1) Louis Nyffenegger (1) Leo Arias (1) +Lauda (1) Lars-Magnus Skog (1) Kevin Pan (1) -Jonathan "Duke" Leto (1) Jonas Nick (1) +Jeremy Rubin (1) Jeffrey Walton (1) Ian Kelling (1) Gaurav Rana (1) @@ -95,9 +118,12 @@ Forrest Voight (1) Florian Schmaus (1) Ethan Heilman (1) Eran Tromer (1) -Duke Leto (1) +Dimitris Apostolou (1) +David Llop (1) Christian von Roques (1) Chirag Davé (1) +Charlie OKeefe (1) +Charlie O'Keefe (1) Casey Rodarmor (1) Cameron Boehmer (1) Bryan Stitt (1) @@ -109,7 +135,6 @@ Ashley Holman (1) Anthony Towns (1) Allan Niemerg (1) Alex van der Peet (1) -Alex Morcos (1) Alex (1) Adam Weiss (1) Adam Brown (1) diff --git a/doc/beefy-node-reference-komodo.conf b/doc/beefy-node-reference-komodo.conf new file mode 100644 index 000000000..455f1ee3f --- /dev/null +++ b/doc/beefy-node-reference-komodo.conf @@ -0,0 +1,12 @@ +rpcuser=dontuseweakusernameoryougetrobbed +rpcpassword=dontuseweakpasswordoryougetrobbed +txindex=1 +server=1 +rpcworkqueue=64 +addnode=5.9.102.210 +addnode=78.47.196.146 +addnode=178.63.69.164 +addnode=88.198.65.74 +addnode=5.9.122.241 +addnode=144.76.94.38 +addnode=89.248.166.91 \ No newline at end of file diff --git a/doc/bips.md b/doc/bips.md new file mode 100644 index 000000000..14c7e372f --- /dev/null +++ b/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/doc/imgs/logo.png b/doc/imgs/logo.png new file mode 100644 index 000000000..cf47e69fd Binary files /dev/null and b/doc/imgs/logo.png differ diff --git a/doc/imgs/zcashd_screen.gif b/doc/imgs/zcashd_screen.gif new file mode 100644 index 000000000..2eebc1cba Binary files /dev/null and b/doc/imgs/zcashd_screen.gif differ diff --git a/doc/imgs/zcashd_screenshot.png b/doc/imgs/zcashd_screenshot.png new file mode 100644 index 000000000..cdb8a20b8 Binary files /dev/null and b/doc/imgs/zcashd_screenshot.png differ diff --git a/doc/man/zcash-cli.1 b/doc/man/zcash-cli.1 index a30af6fe6..50a69cbe5 100644 --- a/doc/man/zcash-cli.1 +++ b/doc/man/zcash-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZCASH-CLI "1" "February 2018" "zcash-cli v1.0.15" "User Commands" +.TH ZCASH-CLI "1" "October 2018" "zcash-cli v2.0.1-rc1" "User Commands" .SH NAME -zcash-cli \- manual page for zcash-cli v1.0.15 +zcash-cli \- manual page for zcash-cli v2.0.1-rc1 .SH DESCRIPTION -Zcash RPC client version v1.0.15 +Zcash RPC client version v2.0.1\-rc1 .PP In order to ensure you are adequately protecting your privacy when using Zcash, please see . @@ -65,6 +65,11 @@ Password for JSON\-RPC connections .IP Timeout in seconds during HTTP requests, or 0 for no timeout. (default: 900) +.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) .SH COPYRIGHT In order to ensure you are adequately protecting your privacy when using Zcash, diff --git a/doc/man/zcash-tx.1 b/doc/man/zcash-tx.1 index f5830e6de..1dd3f9ec7 100644 --- a/doc/man/zcash-tx.1 +++ b/doc/man/zcash-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZCASH-TX "1" "February 2018" "zcash-tx v1.0.15" "User Commands" +.TH ZCASH-TX "1" "October 2018" "zcash-tx v2.0.1-rc1" "User Commands" .SH NAME -zcash-tx \- manual page for zcash-tx v1.0.15 +zcash-tx \- manual page for zcash-tx v2.0.1-rc1 .SH DESCRIPTION -Zcash zcash\-tx utility version v1.0.15 +Zcash zcash\-tx utility version v2.0.1\-rc1 .SS "Usage:" .TP zcash\-tx [options] [commands] @@ -48,7 +48,7 @@ delout=N .IP Delete output N from TX .IP -in=TXID:VOUT +in=TXID:VOUT(:SEQUENCE_NUMBER) .IP Add input to TX .IP diff --git a/doc/man/zcashd.1 b/doc/man/zcashd.1 index eaef634c0..6a2b38e22 100644 --- a/doc/man/zcashd.1 +++ b/doc/man/zcashd.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. -.TH ZCASHD "1" "February 2018" "zcashd v1.0.15" "User Commands" +.TH ZCASHD "1" "October 2018" "zcashd v2.0.1-rc1" "User Commands" .SH NAME -zcashd \- manual page for zcashd v1.0.15 +zcashd \- manual page for zcashd v2.0.1-rc1 .SH DESCRIPTION -Zcash Daemon version v1.0.15 +Zcash Daemon version v2.0.1\-rc1 .PP In order to ensure you are adequately protecting your privacy when using Zcash, please see . @@ -51,11 +51,6 @@ Run in the background as a daemon and accept commands .IP Specify data directory .HP -\fB\-disabledeprecation=\fR -.IP -Disable block\-height node deprecation and automatic shutdown (example: -\fB\-disabledeprecation\fR=\fI\,1\/\fR.0.15) -.HP \fB\-exportdir=\fR .IP Specify directory to be used when exporting data @@ -74,12 +69,13 @@ Keep at most unconnectable transactions in memory (default: 100) .HP \fB\-mempooltxinputlimit=\fR .IP -Set the maximum number of transparent inputs in a transaction that the -mempool will accept (default: 0 = no limit applied) +[DEPRECATED FROM OVERWINTER] Set the maximum number of transparent +inputs in a transaction that the mempool will accept (default: 0 = no +limit applied) .HP \fB\-par=\fR .IP -Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = +Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = leave that many cores free, default: 0) .HP \fB\-pid=\fR @@ -187,6 +183,11 @@ Only connect to nodes in network (ipv4, ipv6 or onion) .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) diff --git a/doc/payment-api.md b/doc/payment-api.md index 14732adba..a9be9d08a 100644 --- a/doc/payment-api.md +++ b/doc/payment-api.md @@ -29,10 +29,10 @@ Optional parameters are denoted in [square brackets]. RPC calls by category: * Accounting: z_getbalance, z_gettotalbalance -* Addresses : z_getnewaddress, z_listaddresses, z_validateaddress +* Addresses : z_getnewaddress, z_listaddresses, z_validateaddress, z_exportviewingkey, z_importviewingkey * Keys : z_exportkey, z_importkey, z_exportwallet, z_importwallet * Operation: z_getoperationresult, z_getoperationstatus, z_listoperationids -* Payment : z_listreceivedbyaddress, z_sendmany, z_shieldcoinbase +* Payment : z_listreceivedbyaddress, z_listunspent, z_sendmany, z_shieldcoinbase RPC parameter conventions: @@ -55,7 +55,7 @@ Command | Parameters | Description --- | --- | --- z_getnewaddress | | Return a new zaddr for sending and receiving payments. The spending key for this zaddr will be added to the node’s wallet.

Output:
zN68D8hSs3... z_listaddresses | | Returns a list of all the zaddrs in this node’s wallet for which you have a spending key.

Output:
{ [“z123…”, “z456...”, “z789...”] } -z_validateaddress | zaddr | Return information about a given zaddr.

Output:
{"isvalid" : true,
"address" : "zcWsmq...",
"payingkey" : "f5bb3c...",
"transmissionkey" : "7a58c7...",
"ismine" : true} +z_validateaddress | zaddr | Return information about a given zaddr.

Output:
{"isvalid" : true,
"address" : "zcWsmq...",
"type" : "sprout",
"payingkey" : "f5bb3c...",
"transmissionkey" : "7a58c7...",
"ismine" : true} ### Key Management @@ -64,13 +64,17 @@ Command | Parameters | Description z_exportkey | zaddr | _Requires an unlocked wallet or an unencrypted wallet._

Return a zkey for a given zaddr belonging to the node’s wallet.

The key will be returned as a string formatted using Base58Check as described in the Zcash protocol spec.

Output:AKWUAkypwQjhZ6LLNaMuuuLcmZ6gt5UFyo8m3jGutvALmwZKLdR5 z_importkey | zkey [rescan=true] | _Wallet must be unlocked._

Add a zkey as returned by z_exportkey to a node's wallet.

The key should be formatted using Base58Check as described in the Zcash protocol spec.

Set rescan to true (the default) to rescan the entire local block database for transactions affecting any address or pubkey script in the wallet (including transactions affecting the newly-added address for this spending key). z_exportwallet | filename | _Requires an unlocked wallet or an unencrypted wallet._

Creates or overwrites a file with taddr private keys and zaddr private keys in a human-readable format.

Filename is the file in which the wallet dump will be placed. May be prefaced by an absolute file path. An existing file with that name will be overwritten.

No value is returned but a JSON-RPC error will be reported if a failure occurred. -z_importwallet | filename | _Requires an unlocked wallet or an unencrypted wallet._

Imports private keys from a file in wallet export file format (see z_exportwallet). These keys will be added to the keys currently in the wallet. This call may need to rescan all or parts of the block chain for transactions affecting the newly-added keys, which may take several minutes.

Filename is the file to import. The path is relative to komodod’s working directory.

No value is returned but a JSON-RPC error will be reported if a failure occurred. +z_importwallet | filename | _Requires an unlocked wallet or an unencrypted wallet._

Imports private keys from a file in wallet export file format (see z_exportwallet). These keys will be added to the keys currently in the wallet. This call may need to rescan all or parts of the block chain for transactions affecting the newly-added keys, which may take several minutes.

Filename is the file to import. The path is relative to verusd’s working directory.

No value is returned but a JSON-RPC error will be reported if a failure occurred. +z_exportviewingkey | zaddr | Reveals the viewing key corresponding to 'zaddr'. Then the z_importviewingkey can be used with this output. +z_importviewingkey | vkey [rescan=whenkeyisnew] [startHeight=0] | Adds a viewing key (as returned by z_exportviewingkey) to your wallet. + ### Payment Command | Parameters | Description --- | --- | --- z_listreceivedbyaddress
| zaddr [minconf=1] | Return a list of amounts received by a zaddr belonging to the node’s wallet.

Optionally set the minimum number of confirmations which a received amount must have in order to be included in the result. Use 0 to count unconfirmed transactions.

Output:
[{
“txid”: “4a0f…”,
“amount”: 0.54,
“memo”:”F0FF…”,}, {...}, {...}
] +z_listunspent | [minconf=1] [maxconf=9999999] [includeWatchonly=false] [zaddrs] | Returns array of unspent shielded notes with between minconf and maxconf (inclusive) confirmations.

Optionally filter to only include notes sent to specified addresses.

When minconf is 0, unspent notes with zero confirmations are returned, even though they are not immediately spendable.

Results are an array of Objects, each of which has: {txid, jsindex, jsoutindex, confirmations, address, amount, memo} z_sendmany
| fromaddress amounts [minconf=1] [fee=0.0001] | _This is an Asynchronous RPC call_

Send funds from an address to multiple outputs. The address can be either a taddr or a zaddr.

Amounts is a list containing key/value pairs corresponding to the addresses and amount to pay. Each output address can be in taddr or zaddr format.

When sending to a zaddr, you also have the option of attaching a memo in hexadecimal format.

**NOTE:**When sending coinbase funds to a zaddr, the node's wallet does not allow any change. Put another way, spending a partial amount of a coinbase utxo is not allowed. This is not a consensus rule but a local wallet rule due to the current implementation of z_sendmany. In future, this rule may be removed.

Example of Outputs parameter:
[{“address”:”t123…”, “amount”:0.005},
,{“address”:”z010…”,”amount”:0.03, “memo”:”f508af…”}]

Optionally set the minimum number of confirmations which a private or transparent transaction must have in order to be used as an input. When sending from a zaddr, minconf must be greater than zero.

Optionally set a transaction fee, which by default is 0.0001 ZEC.

Any transparent change will be sent to a new transparent address. Any private change will be sent back to the zaddr being used as the source of funds.

Returns an operationid. You use the operationid value with z_getoperationstatus and z_getoperationresult to obtain the result of sending funds, which if successful, will be a txid. z_shieldcoinbase
| fromaddress toaddress [fee=0.0001] [limit=50] | _This is an Asynchronous RPC call_

Shield transparent coinbase funds by sending to a shielded z address. Utxos selected for shielding will be locked. If there is an error, they are unlocked. The RPC call `listlockunspent` can be used to return a list of locked utxos.

The number of coinbase utxos selected for shielding can be set with the limit parameter, which has a default value of 50. If the parameter is set to 0, the number of utxos selected is limited by the `-mempooltxinputlimit` option. Any limit is constrained by a consensus rule defining a maximum transaction size of 100000 bytes.

The from address is a taddr or "*" for all taddrs belonging to the wallet. The to address is a zaddr. The default fee is 0.0001.

Returns an object containing an operationid which can be used with z_getoperationstatus and z_getoperationresult, along with key-value pairs regarding how many utxos are being shielded in this transaction and what remains to be shielded. diff --git a/doc/release-notes.md b/doc/release-notes.md index a29094b51..0ae3ea63a 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -4,3 +4,32 @@ release-notes at release time) 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 Sapling shielded transactions. + +Minimum Difficulty Blocks allowed on testnet +-------------------------------------------- +Sapling activated on testnet at block 280000. Users running v2.0.1 nodes no longer need to specify `-experimentalfeatures` and `-developersapling` to use Sapling functionality on testnet. 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. + +[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) \ No newline at end of file diff --git a/doc/release-notes/release-notes-1.1.0-rc1.md b/doc/release-notes/release-notes-1.1.0-rc1.md new file mode 100644 index 000000000..a769b97cf --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.0.md b/doc/release-notes/release-notes-1.1.0.md new file mode 100644 index 000000000..37f803e6f --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.1-rc1.md b/doc/release-notes/release-notes-1.1.1-rc1.md new file mode 100644 index 000000000..bc209efc7 --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.1-rc2.md b/doc/release-notes/release-notes-1.1.1-rc2.md new file mode 100644 index 000000000..5d10ede47 --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.1.md b/doc/release-notes/release-notes-1.1.1.md new file mode 100644 index 000000000..90adec943 --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.2-rc1.md b/doc/release-notes/release-notes-1.1.2-rc1.md new file mode 100644 index 000000000..91fdafd5a --- /dev/null +++ b/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/doc/release-notes/release-notes-1.1.2.md b/doc/release-notes/release-notes-1.1.2.md new file mode 100644 index 000000000..9041c1bb2 --- /dev/null +++ b/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/doc/release-notes/release-notes-2.0.0-rc1.md b/doc/release-notes/release-notes-2.0.0-rc1.md new file mode 100644 index 000000000..9033a31a6 --- /dev/null +++ b/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/doc/release-notes/release-notes-2.0.0.md b/doc/release-notes/release-notes-2.0.0.md new file mode 100644 index 000000000..7dcbf5d6a --- /dev/null +++ b/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/doc/release-notes/release-notes-2.0.1-rc1.md b/doc/release-notes/release-notes-2.0.1-rc1.md new file mode 100644 index 000000000..683d5ed22 --- /dev/null +++ b/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/doc/release-process.md b/doc/release-process.md index 93a8e8362..cde355287 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -24,6 +24,8 @@ Check that there are no surprising performance regressions: Ensure that new performance metrics appear on that site. +Update `src/chainparams.cpp` nMinimumChainWork with information from the getblockchaininfo rpc. + ### Protocol Safety Checks: If this release changes the behavior of the protocol or fixes a serious diff --git a/doc/unit-tests.md b/doc/unit-tests.md index 97dcd701e..9410b4407 100644 --- a/doc/unit-tests.md +++ b/doc/unit-tests.md @@ -6,7 +6,7 @@ and tests weren't explicitly disabled. There are two scripts for running tests: -* ``qa/zcash/full-test-suite.sh``, to run the main test suite +* ``qa/zcash/full_test_suite.py``, to run the main test suite * ``qa/pull-tester/rpc-tests.sh``, to run the RPC tests. The main test suite uses two different testing frameworks. Tests using the Boost diff --git a/migratecoin.md b/migratecoin.md deleted file mode 100644 index 7859bdff2..000000000 --- a/migratecoin.md +++ /dev/null @@ -1,61 +0,0 @@ -# MigrateCoin protocol - - - -## ExportCoins tx: - - - -``` - -vin: - - [ any ] - -vout: - - - amount: {burnAmount} - - script: OP_RETURN "send to ledger {id} {voutsHash}" - -``` - - - -* ExportCoin is a standard tx which burns coins in an OP_RETURN - - - -## ImportCoins tx: - - - -``` - -vin: - - - txid: 0000000000000000000000000000000000000000000000000000000000000000 - - idx: 0 - - script: CC_EVAL(EVAL_IMPORTCOINS, {momoProof},{exportCoin}) OP_CHECKCRYPTOCONDITION_UNILATERAL - -vout: - - - [ vouts matching voutsHash in exportCoin ] - -``` - - - -* ImportCoin transaction has no signature - -* ImportCoin is non malleable - -* ImportCoin satisfies tx.IsCoinBase() - -* ImportCoin uses a new opcode which allows a one sided check (no scriptPubKey) - -* ImportCoin must contain CC opcode EVAL_IMPORTCOINS - -* ImportCoin fees are equal to the difference between burnAmount in exportCoins and the sum of outputs. diff --git a/migratecoin.sh b/migratecoin.sh new file mode 100644 index 000000000..6cd09ba04 --- /dev/null +++ b/migratecoin.sh @@ -0,0 +1,43 @@ +#!/usr/bin/bash + +# This script makes the neccesary transactions to migrate +# coin between 2 assetchains on the same -ac_cc id + +set -e + +source=TXSCL +target=TXSCL000 +address="RFw7byY4xZpZCrtkMk3nFuuG1NTs9rSGgQ" +amount=1 + +# Alias for running cli on source chain +cli_source="komodo-cli -ac_name=$source" + +# Raw tx that we will work with +txraw=`$cli_source createrawtransaction "[]" "{\"$address\":$amount}"` + +# Convert to an export tx +exportData=`$cli_source migrate_converttoexport $txraw $target $amount` +exportRaw=`echo $exportData | jq -r .exportTx` +exportPayouts=`echo $exportData | jq -r .payouts` + +# Fund +exportFundedData=`$cli_source fundrawtransaction $exportRaw` +exportFundedTx=`echo $exportFundedData | jq -r .hex` + +# Sign +exportSignedData=`$cli_source signrawtransaction $exportFundedTx` +exportSignedTx=`echo $exportSignedData | jq -r .hex` + +# Send +echo "Sending export tx" +$cli_source sendrawtransaction $exportSignedTx + +read -p "Wait for a notarisation to KMD, and then two more notarisations from the target chain, and then press enter to continue" + +# Create import +importTx=`$cli_source migrate_createimporttransaction $exportSignedTx $payouts` +importTx=`komodo-cli migrate_completeimporttransaction $importTx` + +# Send import +komodo-cli -ac_name=$target sendrawtransaction $importTx diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 50de39f64..af88b019e 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -11,17 +11,26 @@ export BITCOIND=${REAL_BITCOIND} #Run the tests testScripts=( + 'cryptoconditions.py' 'paymentdisclosure.py' 'prioritisetransaction.py' 'wallet_treestate.py' 'wallet_anchorfork.py' + 'wallet_changeindicator.py' + 'wallet_import_export.py' 'wallet_protectcoinbase.py' - 'wallet_shieldcoinbase.py' + 'wallet_shieldcoinbase_sprout.py' + 'wallet_shieldcoinbase_sapling.py' + 'wallet_listreceived.py' 'wallet_mergetoaddress.py' 'wallet.py' 'wallet_overwintertx.py' + 'wallet_persistence.py' 'wallet_nullifiers.py' 'wallet_1941.py' + 'wallet_addresses.py' + 'wallet_sapling.py' + 'wallet_listnotes.py' 'listtransactions.py' 'mempool_resurrect_test.py' 'txn_doublespend.py' @@ -40,6 +49,7 @@ testScripts=( 'merkle_blocks.py' 'fundrawtransaction.py' 'signrawtransactions.py' + 'signrawtransaction_offline.py' 'walletbackup.py' 'key_import_export.py' 'nodehandling.py' @@ -48,6 +58,7 @@ testScripts=( 'timestampindex.py' 'spentindex.py' 'decodescript.py' + 'blockchain.py' 'disablewallet.py' 'zcjoinsplit.py' 'zcjoinsplitdoublespend.py' @@ -56,7 +67,11 @@ testScripts=( 'getblocktemplate.py' 'bip65-cltv-p2p.py' 'bipdersig-p2p.py' - 'overwinter_peer_management.py' + 'p2p_nu_peer_management.py' + 'rewind_index.py' + 'p2p_txexpiry_dos.py' + 'p2p_node_bloom.py' + 'regtest_signrawtransaction.py' ); testScriptsExt=( 'getblocktemplate_longpoll.py' diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in index cc76e8ad8..8d9467f3f 100755 --- a/qa/pull-tester/tests-config.sh.in +++ b/qa/pull-tester/tests-config.sh.in @@ -13,6 +13,6 @@ EXEEXT="@EXEEXT@" @ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 @ENABLE_PROTON_TRUE@ENABLE_PROTON=1 -REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}" -REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}" +REAL_BITCOIND="$BUILDDIR/src/komodod${EXEEXT}" +REAL_BITCOINCLI="$BUILDDIR/src/komodo-cli${EXEEXT}" diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index a0229b56d..17aee1967 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -18,9 +18,9 @@ Possible options: ``` -h, --help show this help message and exit - --nocleanup Leave bitcoinds and test.* datadir on exit or error - --noshutdown Don't stop bitcoinds after the test execution - --srcdir=SRCDIR Source directory containing bitcoind/bitcoin-cli (default: + --nocleanup Leave komodods and test.* datadir on exit or error + --noshutdown Don't stop komodods after the test execution + --srcdir=SRCDIR Source directory containing komodod/komodo-cli (default: ../../src) --tmpdir=TMPDIR Root directory for datadirs --tracerpc Print out all RPC calls as they are made @@ -31,7 +31,7 @@ If you set the environment variable `PYTHON_DEBUG=1` you will get some debug out 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. +subsidy from 25 mature blocks (25*10=250 KMD) in its wallet. After the first run, the cache/ blockchain and wallets are copied into a temporary directory and used as the initial @@ -42,5 +42,5 @@ to recover with: ```bash rm -rf cache -killall zcashd +killall komodod ``` diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py new file mode 100755 index 000000000..c37db8b84 --- /dev/null +++ b/qa/rpc-tests/blockchain.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python2 +# Copyright (c) 2014 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# 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 ( + initialize_chain, + assert_equal, + start_nodes, + connect_nodes_bi, +) + +class BlockchainTest(BitcoinTestFramework): + """ + Test blockchain-related RPC calls: + + - gettxoutsetinfo + + """ + + def setup_chain(self): + print("Initializing test directory " + self.options.tmpdir) + initialize_chain(self.options.tmpdir) + + 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): + node = self.nodes[0] + res = node.gettxoutsetinfo() + + assert_equal(res[u'total_amount'], decimal.Decimal('2181.25000000')) # 150*12.5 + 49*6.25 + assert_equal(res[u'transactions'], 200) + assert_equal(res[u'height'], 200) + assert_equal(res[u'txouts'], 349) # 150*2 + 49 + assert_equal(res[u'bytes_serialized'], 14951), # 32*199 + 48*90 + 49*60 + 27*49 + assert_equal(len(res[u'bestblock']), 64) + assert_equal(len(res[u'hash_serialized']), 64) + + +if __name__ == '__main__': + BlockchainTest().main() diff --git a/qa/rpc-tests/cryptoconditions.py b/qa/rpc-tests/cryptoconditions.py new file mode 100755 index 000000000..e7d3065cc --- /dev/null +++ b/qa/rpc-tests/cryptoconditions.py @@ -0,0 +1,605 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises + +import time +from decimal import Decimal + +def assert_success(result): + assert_equal(result['result'], 'success') + +def assert_error(result): + assert_equal(result['result'], 'error') + +class CryptoConditionsTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 1 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ]] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn): + txid = self.rpc.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + self.rpc.generate(1) + return txid + + def run_faucet_tests(self): + rpc = self.rpc + + # basic sanity tests + result = rpc.getwalletinfo() + assert_greater_than(result['txcount'], 100) + assert_greater_than(result['balance'], 0.0) + balance = result['balance'] + + faucet = rpc.faucetaddress() + assert_equal(faucet['result'], 'success') + # verify all keys look like valid AC addrs, could be better + for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']: + assert_equal(faucet[x][0], 'R') + + result = rpc.faucetaddress(self.pubkey) + assert_success(result) + # test that additional CCaddress key is returned + for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + + # no funds in the faucet yet + result = rpc.faucetget() + assert_error(result) + + result = rpc.faucetinfo() + assert_success(result) + + result = rpc.faucetfund("0") + assert_error(result) + + result = rpc.faucetfund("-1") + assert_error(result) + + # we need at least 1 + txfee to get + result = rpc.faucetfund("2") + assert_success(result) + assert result['hex'], "hex key found" + + # broadcast the xtn + result = rpc.sendrawtransaction(result['hex']) + txid = result[0] + assert txid, "found txid" + + # we need the tx above to be confirmed in the next block + rpc.generate(1) + + result = rpc.getwalletinfo() + balance2 = result['balance'] + # make sure our balance is less now + assert_greater_than(balance, balance2) + + result = rpc.faucetinfo() + assert_success(result) + assert_greater_than( result['funding'], 0 ) + + result = rpc.faucetget() + assert_success(result) + assert result['hex'], "hex key found" + + # try to broadcast the xtn, but we will get 'faucet is only for brand new addresses' + assert_raises(JSONRPCException, rpc.sendrawtransaction, [ result['hex'] ]) + + newaddr = rpc.getnewaddress() + assert newaddr, "got a new address" + result = rpc.validateaddress(newaddr) + newpubkey = result['pubkey'] + assert newpubkey, "got a pubkey for new address" + + def run_dice_tests(self): + rpc = self.nodes[0] + + dice = rpc.diceaddress() + assert_equal(dice['result'], 'success') + for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']: + assert_equal(dice[x][0], 'R') + + dice = rpc.diceaddress(self.pubkey) + assert_equal(dice['result'], 'success') + for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress', 'CCaddress']: + assert_equal(dice[x][0], 'R') + + # no dice created yet + result = rpc.dicelist() + assert_equal(result, []) + + # creating dice plan with too long name (>8 chars) + result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5") + assert_error(result) + + # creating dice plan with < 100 funding + result = rpc.dicefund("LUCKY","10","1","10000","10","5") + assert_error(result) + + # creating dice plan with 0 blocks timeout + result = rpc.dicefund("LUCKY","10","1","10000","10","0") + assert_error(result) + + # creating dice plan + dicefundtx = rpc.dicefund("LUCKY","1000","1","800","10","5") + diceid = self.send_and_mine(dicefundtx['hex']) + + # checking if it in plans list now + result = rpc.dicelist() + assert_equal(result[0], diceid) + + # set dice name for futher usage + dicename = "LUCKY" + + # adding zero funds to plan + result = rpc.diceaddfunds(dicename,diceid,"0") + assert_error(result) + + # adding negative funds to plan + result = rpc.diceaddfunds(dicename,diceid,"-1") + assert_error(result) + + # adding funds to plan + addfundstx = rpc.diceaddfunds(dicename,diceid,"1100") + result = self.send_and_mine(addfundstx['hex']) + + # checking if funds added to plan + result = rpc.diceinfo(diceid) + assert_equal(result["funding"], "2100.00000000") + + # not valid dice info checking + result = rpc.diceinfo("invalid") + assert_error(result) + + # placing 0 amount bet + result = rpc.dicebet(dicename,diceid,"0","1") + assert_error(result) + + # placing negative amount bet + result = rpc.dicebet(dicename,diceid,"-1","1") + assert_error(result) + + # placing bet more than maxbet + result = rpc.dicebet(dicename,diceid,"900","1") + assert_error(result) + + # placing bet with amount more than funding + result = rpc.dicebet(dicename,diceid,"3000","1") + assert_error(result) + + # placing bet with potential won more than funding + result = rpc.dicebet(dicename,diceid,"750","9") + assert_error(result) + + # placing 0 odds bet + result = rpc.dicebet(dicename,diceid,"1","0") + assert_error(result) + + # placing negative odds bet + result = rpc.dicebet(dicename,diceid,"1","-1") + assert_error(result) + + # placing bet with odds more than allowed + result = rpc.dicebet(dicename,diceid,"1","11") + assert_error(result) + + # placing bet with not correct dice name + result = rpc.dicebet("nope",diceid,"100","1") + assert_error(result) + + # placing bet with not correct dice id + result = rpc.dicebet(dicename,self.pubkey,"100","1") + assert_error(result) + + # valid bet placing + placebet = rpc.dicebet(dicename,diceid,"100","1") + betid = self.send_and_mine(placebet["hex"]) + assert result, "bet placed" + + # check bet status + result = rpc.dicestatus(dicename,diceid,betid) + assert_success(result) + + # have to make some entropy for the next test + entropytx = 0 + fundingsum = 1 + while entropytx < 10: + fundingsuminput = str(fundingsum) + fundinghex = rpc.diceaddfunds(dicename,diceid,fundingsuminput) + result = self.send_and_mine(fundinghex['hex']) + entropytx = entropytx + 1 + fundingsum = fundingsum + 1 + + rpc.generate(2) + + # note initial dice funding state at this point. + # TODO: track player balance somehow (hard to do because of mining and fees) + diceinfo = rpc.diceinfo(diceid) + funding = float(diceinfo['funding']) + + # placing same amount bets with amount 1 and odds 1:2, checking if balance changed correct + losscounter = 0 + wincounter = 0 + betcounter = 0 + + while (betcounter < 10): + placebet = rpc.dicebet(dicename,diceid,"1","1") + betid = self.send_and_mine(placebet["hex"]) + finish = rpc.dicefinish(dicename,diceid,betid) + self.send_and_mine(finish["hex"]) + betresult = rpc.dicestatus(dicename,diceid,betid) + betcounter = betcounter + 1 + if betresult["status"] == "loss": + losscounter = losscounter + 1 + elif betresult["status"] == "win": + wincounter = wincounter + 1 + + # funding balance should increase if player loss, decrease if player won + fundbalanceguess = funding + losscounter - wincounter + fundinfoactual = rpc.diceinfo(diceid) + assert_equal(round(fundbalanceguess),round(float(fundinfoactual['funding']))) + + def run_token_tests(self): + rpc = self.nodes[0] + result = rpc.tokenaddress() + assert_success(result) + for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.tokenaddress(self.pubkey) + assert_success(result) + for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + # there are no tokens created yet + result = rpc.tokenlist() + assert_equal(result, []) + + # trying to create token with negaive supply + result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply") + assert_error(result) + + # creating token with name more than 32 chars + result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long") + assert_error(result) + + # creating valid token + result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token") + assert_success(result) + + tokenid = self.send_and_mine(result['hex']) + + result = rpc.tokenlist() + assert_equal(result[0], tokenid) + + # there are no token orders yet + result = rpc.tokenorders() + assert_equal(result, []) + + # getting token balance for pubkey + result = rpc.tokenbalance(self.pubkey) + assert_success(result) + assert_equal(result['balance'], 0) + assert_equal(result['CCaddress'], 'RCRsm3VBXz8kKTsYaXKpy7pSEzrtNNQGJC') + assert_equal(result['tokenid'], self.pubkey) + + # get token balance for token with pubkey + result = rpc.tokenbalance(tokenid, self.pubkey) + assert_success(result) + assert_equal(result['balance'], 198742000000) + assert_equal(result['tokenid'], tokenid) + + # get token balance for token without pubkey + result = rpc.tokenbalance(tokenid) + assert_success(result) + assert_equal(result['balance'], 198742000000) + assert_equal(result['tokenid'], tokenid) + + # this is not a valid assetid + result = rpc.tokeninfo(self.pubkey) + assert_error(result) + + # check tokeninfo for valid token + result = rpc.tokeninfo(tokenid) + assert_success(result) + assert_equal(result['tokenid'], tokenid) + assert_equal(result['owner'], self.pubkey) + assert_equal(result['name'], "DUKE") + assert_equal(result['supply'], 198742000000) + assert_equal(result['description'], "Duke's custom token") + + # invalid numtokens ask + result = rpc.tokenask("-1", tokenid, "1") + assert_error(result) + + # invalid numtokens ask + result = rpc.tokenask("0", tokenid, "1") + assert_error(result) + + # invalid price ask + result = rpc.tokenask("1", tokenid, "-1") + assert_error(result) + + # invalid price ask + result = rpc.tokenask("1", tokenid, "0") + assert_error(result) + + # invalid tokenid ask + result = rpc.tokenask("100", "deadbeef", "1") + assert_error(result) + + # valid ask + tokenask = rpc.tokenask("100", tokenid, "7.77") + tokenaskhex = tokenask['hex'] + tokenaskid = self.send_and_mine(tokenask['hex']) + result = rpc.tokenorders() + order = result[0] + assert order, "found order" + + # invalid ask fillunits + result = rpc.tokenfillask(tokenid, tokenaskid, "0") + assert_error(result) + + # invalid ask fillunits + result = rpc.tokenfillask(tokenid, tokenaskid, "-777") + assert_error(result) + + # valid ask fillunits + fillask = rpc.tokenfillask(tokenid, tokenaskid, "777") + result = self.send_and_mine(fillask['hex']) + txid = result[0] + assert txid, "found txid" + + # should be no token orders + result = rpc.tokenorders() + assert_equal(result, []) + + # checking ask cancellation + testorder = rpc.tokenask("100", tokenid, "7.77") + testorderid = self.send_and_mine(testorder['hex']) + cancel = rpc.tokencancelask(tokenid, testorderid) + self.send_and_mine(cancel["hex"]) + result = rpc.tokenorders() + assert_equal(result, []) + + # invalid numtokens bid + result = rpc.tokenbid("-1", tokenid, "1") + assert_error(result) + + # invalid numtokens bid + result = rpc.tokenbid("0", tokenid, "1") + assert_error(result) + + # invalid price bid + result = rpc.tokenbid("1", tokenid, "-1") + assert_error(result) + + # invalid price bid + result = rpc.tokenbid("1", tokenid, "0") + assert_error(result) + + # invalid tokenid bid + result = rpc.tokenbid("100", "deadbeef", "1") + assert_error(result) + + tokenbid = rpc.tokenbid("100", tokenid, "10") + tokenbidhex = tokenbid['hex'] + tokenbidid = self.send_and_mine(tokenbid['hex']) + result = rpc.tokenorders() + order = result[0] + assert order, "found order" + + # invalid bid fillunits + result = rpc.tokenfillbid(tokenid, tokenbidid, "0") + assert_error(result) + + # invalid bid fillunits + result = rpc.tokenfillbid(tokenid, tokenbidid, "-777") + assert_error(result) + + # valid bid fillunits + fillbid = rpc.tokenfillbid(tokenid, tokenbidid, "1000") + result = self.send_and_mine(fillbid['hex']) + txid = result[0] + assert txid, "found txid" + + # should be no token orders + result = rpc.tokenorders() + assert_equal(result, []) + + # checking bid cancellation + testorder = rpc.tokenbid("100", tokenid, "7.77") + testorderid = self.send_and_mine(testorder['hex']) + cancel = rpc.tokencancelbid(tokenid, testorderid) + self.send_and_mine(cancel["hex"]) + result = rpc.tokenorders() + assert_equal(result, []) + + # invalid token transfer amount (have to add status to CC code!) + randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" + result = rpc.tokentransfer(tokenid,randompubkey,"0") + assert_error(result) + + # invalid token transfer amount (have to add status to CC code!) + result = rpc.tokentransfer(tokenid,randompubkey,"-1") + assert_error(result) + + # valid token transfer + sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1") + self.send_and_mine(sendtokens["hex"]) + result = rpc.tokenbalance(tokenid,randompubkey) + assert_equal(result["balance"], 1) + + + def run_rewards_tests(self): + rpc = self.nodes[0] + result = rpc.rewardsaddress() + for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.rewardsaddress(self.pubkey) + for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + + # no rewards yet + result = rpc.rewardslist() + assert_equal(result, []) + + # looking up non-existent reward should return error + result = rpc.rewardsinfo("none") + assert_error(result) + + # creating rewards plan with name > 8 chars, should return error + result = rpc.rewardscreatefunding("STUFFSTUFF", "7777", "25", "0", "10", "10") + assert_error(result) + + # creating rewards plan with 0 funding + result = rpc.rewardscreatefunding("STUFF", "0", "25", "0", "10", "10") + assert_error(result) + + # creating rewards plan with 0 maxdays + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "0") + assert_error(result) + + # creating rewards plan with > 25% APR + result = rpc.rewardscreatefunding("STUFF", "7777", "30", "0", "10", "10") + assert_error(result) + + # creating valid rewards plan + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10") + assert result['hex'], 'got raw xtn' + fundingtxid = rpc.sendrawtransaction(result['hex']) + assert fundingtxid, 'got txid' + + # confirm the above xtn + rpc.generate(1) + result = rpc.rewardsinfo(fundingtxid) + assert_success(result) + assert_equal(result['name'], 'STUFF') + assert_equal(result['APR'], "25.00000000") + assert_equal(result['minseconds'], 0) + assert_equal(result['maxseconds'], 864000) + assert_equal(result['funding'], "7777.00000000") + assert_equal(result['mindeposit'], "10.00000000") + assert_equal(result['fundingtxid'], fundingtxid) + + # checking if new plan in rewardslist + result = rpc.rewardslist() + assert_equal(result[0], fundingtxid) + + # creating reward plan with already existing name, should return error + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10") + assert_error(result) + + # add funding amount must be positive + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "-1") + assert_error(result) + + # add funding amount must be positive + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "0") + assert_error(result) + + # adding valid funding + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "555") + addfundingtxid = self.send_and_mine(result['hex']) + assert addfundingtxid, 'got funding txid' + + # checking if funding added to rewardsplan + result = rpc.rewardsinfo(fundingtxid) + assert_equal(result['funding'], "8332.00000000") + + # trying to lock funds, locking funds amount must be positive + result = rpc.rewardslock("STUFF", fundingtxid, "-5") + assert_error(result) + + # trying to lock funds, locking funds amount must be positive + result = rpc.rewardslock("STUFF", fundingtxid, "0") + assert_error(result) + + # trying to lock less than the min amount is an error + result = rpc.rewardslock("STUFF", fundingtxid, "7") + assert_error(result) + + # locking funds in rewards plan + result = rpc.rewardslock("STUFF", fundingtxid, "10") + assert_success(result) + locktxid = result['hex'] + assert locktxid, "got lock txid" + + # locktxid has not been broadcast yet + result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid) + assert_error(result) + + # broadcast xtn + txid = rpc.sendrawtransaction(locktxid) + assert txid, 'got txid from sendrawtransaction' + + # confirm the xtn above + rpc.generate(1) + + # will not unlock since reward amount is less than tx fee + result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid) + assert_error(result) + + + def run_test (self): + print("Mining blocks...") + rpc = self.nodes[0] + + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + + # this corresponds to -pubkey above + print("Importing privkey") + rpc.importprivkey(self.privkey) + +# self.run_faucet_tests() + self.run_rewards_tests() + self.run_dice_tests() + self.run_token_tests() + self.run_faucet_tests() + + +if __name__ == '__main__': + CryptoConditionsTest ().main () diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index 89364a840..293fd0ebb 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -6,6 +6,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, initialize_chain_clean, \ start_nodes +from test_framework.mininode import CTransaction +from binascii import hexlify, unhexlify +from cStringIO import StringIO class DecodeScriptTest(BitcoinTestFramework): @@ -109,10 +112,77 @@ class DecodeScriptTest(BitcoinTestFramework): 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(StringIO(unhexlify(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 = hexlify(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 = unhexlify(push_signature) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(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 = unhexlify(push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm']) + + # 2) multisig scriptSig + txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2) + rpc_result = self.nodes[0].decoderawtransaction(hexlify(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 = unhexlify('6a143011020701010101010101020601010101010101') + rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize())) + print(hexlify('636174')) + 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/qa/rpc-tests/getblocktemplate.py b/qa/rpc-tests/getblocktemplate.py index 82082afa9..af050110e 100755 --- a/qa/rpc-tests/getblocktemplate.py +++ b/qa/rpc-tests/getblocktemplate.py @@ -4,8 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import initialize_chain_clean, start_nodes, \ - connect_nodes_bi +from test_framework.util import assert_equal, connect_nodes_bi, \ + initialize_chain_clean, start_nodes class GetBlockTemplateTest(BitcoinTestFramework): @@ -49,11 +49,16 @@ class GetBlockTemplateTest(BitcoinTestFramework): # Test 5: General checks tmpl = node.getblocktemplate() - assert(len(tmpl['noncerange']) == 16) + assert_equal(16, len(tmpl['noncerange'])) # Test 6: coinbasetxn checks assert('foundersreward' in tmpl['coinbasetxn']) assert(tmpl['coinbasetxn']['required']) + # Test 7: hashFinalSaplingRoot checks + assert('finalsaplingroothash' in tmpl) + finalsaplingroothash = '3e49b5f954aa9d3545bc6c37744661eea48d7c34e3000d82b7f0010c30f4c2fb' + assert_equal(finalsaplingroothash, tmpl['finalsaplingroothash']) + if __name__ == '__main__': GetBlockTemplateTest().main() diff --git a/qa/rpc-tests/mempool_nu_activation.py b/qa/rpc-tests/mempool_nu_activation.py index f54095660..28b5e8865 100755 --- a/qa/rpc-tests/mempool_nu_activation.py +++ b/qa/rpc-tests/mempool_nu_activation.py @@ -15,7 +15,10 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework): alert_filename = None # Set by setup_network def setup_network(self): - args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000", "-nuparams=5ba81b19:200"] + args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000", + "-nuparams=5ba81b19:200", # Overwinter + "-nuparams=76b809bb:210", # Sapling + ] self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, args)) self.nodes.append(start_node(1, self.options.tmpdir, args)) @@ -44,76 +47,100 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework): print wait_and_assert_operationid_status(self.nodes[1], myopid) self.sync_all() - # Mine block 198. After this, the mempool expects - # block 199, which is the last Sprout block. - self.nodes[0].generate(1) + # Mempool checks for activation of upgrade Y at height H on base X + def nu_activation_checks(): + # Mine block H - 2. After this, the mempool expects + # block H - 1, which is the last X block. + self.nodes[0].generate(1) + self.sync_all() + + # 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 twice as many transactions as can fit into blocks + node0_taddr = self.nodes[0].getnewaddress() + x_txids = [] + while self.nodes[1].getmempoolinfo()['bytes'] < 2 * 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)) + + # 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() + + # mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Block H - 1 should contain a subset of the original mempool + # (with all other transactions having been dropped) + block_txids = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx'] + assert(len(block_txids) < len(x_txids)) + 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, Decimal('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)) + + # 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 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() + + print('Testing Sprout -> Overwinter activation boundary') + # Current height = 197 + nu_activation_checks() + # Current height = 205 + + self.nodes[0].generate(2) self.sync_all() - # 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 twice as many transactions as can fit into blocks - node0_taddr = self.nodes[0].getnewaddress() - sprout_txids = [] - while self.nodes[1].getmempoolinfo()['bytes'] < 2 * 4000: - sprout_txids.append(self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001'))) - self.sync_all() - - # Spends should be in the mempool - sprout_mempool = set(self.nodes[0].getrawmempool()) - assert_equal(sprout_mempool, set(sprout_txids)) - - # Mine block 199. After this, the mempool expects - # block 200, which is the first Overwinter block. - self.nodes[0].generate(1) - self.sync_all() - - # mempool should be empty. - assert_equal(set(self.nodes[0].getrawmempool()), set()) - - # Block 199 should contain a subset of the original mempool - # (with all other transactions having been dropped) - block_txids = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx'] - assert(len(block_txids) < len(sprout_txids)) - for txid in block_txids[1:]: # Exclude coinbase - assert(txid in sprout_txids) - - # Create some transparent Overwinter transactions - overwinter_txids = [self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001')) for i in range(10)] - self.sync_all() - - # Create a shielded Overwinter transaction - recipients = [{'address': node0_taddr, 'amount': Decimal('10')}] - myopid = self.nodes[0].z_sendmany(node0_zaddr, recipients, 1, Decimal('0')) - shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) - assert(shielded != None) - overwinter_txids.append(shielded) - self.sync_all() - - # Spends should be in the mempool - assert_equal(set(self.nodes[0].getrawmempool()), set(overwinter_txids)) - - # Node 0 note should be unspendable - assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('0')) - - # Invalidate block 199. - self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) - - # BUG: Ideally, the mempool should now only contain the transactions - # that were in block 199, the Overwinter 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 199 transactions to be validated against the Overwinter 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 0 note should be spendable again - assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('10')) + print('Testing Overwinter -> Sapling activation boundary') + # Current height = 207 + nu_activation_checks() + # Current height = 215 if __name__ == '__main__': MempoolUpgradeActivationTest().main() diff --git a/qa/rpc-tests/mempool_tx_expiry.py b/qa/rpc-tests/mempool_tx_expiry.py index 9edf156d2..b5ee4bd2a 100755 --- a/qa/rpc-tests/mempool_tx_expiry.py +++ b/qa/rpc-tests/mempool_tx_expiry.py @@ -20,9 +20,9 @@ class MempoolTxExpiryTest(BitcoinTestFramework): return start_nodes(4, self.options.tmpdir, [["-nuparams=5ba81b19:205", "-txexpirydelta=4", "-debug=mempool"]] * 4) # Test before, at, and after expiry block - # TODO: Test case of dependent txs in reorgs # 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() bob = self.nodes[2].getnewaddress() z_bob = self.nodes[2].z_getnewaddress() @@ -36,6 +36,42 @@ class MempoolTxExpiryTest(BitcoinTestFramework): self.nodes[0].generate(6) self.sync_all() + print "Splitting network..." + self.split_network() + + # When Overwinter is activated, test dependent txs + firstTx = self.nodes[0].sendtoaddress(alice, 0.1) + firstTxInfo = self.nodes[0].getrawtransaction(firstTx, 1) + 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 6 competing blocks on Node 2..." + blocks = self.nodes[2].generate(6) + 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, 0.0001, 1) wait_and_assert_operationid_status(self.nodes[0], res['opid']) @@ -51,6 +87,7 @@ class MempoolTxExpiryTest(BitcoinTestFramework): self.split_network() # Create transactions + blockheight = self.nodes[0].getblockchaininfo()['blocks'] zsendamount = Decimal('1.0') - Decimal('0.0001') recipients = [] recipients.append({"address": z_bob, "amount": zsendamount}) @@ -61,7 +98,7 @@ class MempoolTxExpiryTest(BitcoinTestFramework): rawtx = self.nodes[0].getrawtransaction(persist_transparent, 1) assert_equal(rawtx["version"], 3) assert_equal(rawtx["overwintered"], True) - assert_equal(rawtx["expiryheight"], 212) + assert_equal(rawtx["expiryheight"], blockheight + 5) 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 3 intended for Overwinter branch @@ -69,7 +106,7 @@ class MempoolTxExpiryTest(BitcoinTestFramework): print "Expiryheight of persist_shielded", rawtx['expiryheight'] assert_equal(rawtx["version"], 3) assert_equal(rawtx["overwintered"], True) - assert_equal(rawtx["expiryheight"], 212) + assert_equal(rawtx["expiryheight"], blockheight + 5) print "\n Blockheight advances to less than expiry block height. After reorg, txs should persist in mempool" assert(persist_transparent in self.nodes[0].getrawmempool()) diff --git a/qa/rpc-tests/mempool_tx_input_limit.py b/qa/rpc-tests/mempool_tx_input_limit.py index c48d73be0..9a7131cfe 100755 --- a/qa/rpc-tests/mempool_tx_input_limit.py +++ b/qa/rpc-tests/mempool_tx_input_limit.py @@ -8,7 +8,6 @@ from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, initialize_chain_clean, \ start_node, connect_nodes, wait_and_assert_operationid_status -import time from decimal import Decimal # Test -mempooltxinputlimit @@ -17,7 +16,7 @@ class MempoolTxInputLimitTest(BitcoinTestFramework): alert_filename = None # Set by setup_network def setup_network(self): - args = ["-checkmempool", "-debug=mempool", "-mempooltxinputlimit=2"] + args = ["-checkmempool", "-debug=mempool", "-mempooltxinputlimit=2", "-nuparams=5ba81b19:110"] self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, args)) self.nodes.append(start_node(1, self.options.tmpdir, args)) @@ -49,27 +48,13 @@ class MempoolTxInputLimitTest(BitcoinTestFramework): node0_zaddr = self.nodes[0].z_getnewaddress() # Send three inputs from node 0 taddr to zaddr to get out of coinbase - node0_taddr = self.nodes[0].getnewaddress(); + node0_taddr = self.nodes[0].getnewaddress() recipients = [] recipients.append({"address":node0_zaddr, "amount":Decimal('30.0')-Decimal('0.0001')}) # utxo amount less fee myopid = self.nodes[0].z_sendmany(node0_taddr, recipients) - opids = [] - opids.append(myopid) - # Spend should fail due to -mempooltxinputlimit - timeout = 120 - status = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - msg = results[0]["error"]["message"] - assert_equal("failed", status) - assert_equal("Too many transparent inputs 3 > limit 2", msg) - break + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Too many transparent inputs 3 > limit 2", 120) # Mempool should be empty. assert_equal(set(self.nodes[0].getrawmempool()), set()) @@ -100,6 +85,7 @@ class MempoolTxInputLimitTest(BitcoinTestFramework): myopid = self.nodes[0].z_sendmany(node0_zaddr, recipients) wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -120,5 +106,31 @@ class MempoolTxInputLimitTest(BitcoinTestFramework): # Spend should be in the mempool assert_equal(set(self.nodes[1].getrawmempool()), set([ spend_taddr_id2 ])) + # Mine three blocks + self.nodes[1].generate(3) + self.sync_all() + # The next block to be mined, 109, is the last Sprout block + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '00000000') + + # z_sendmany should be limited by -mempooltxinputlimit + recipients = [] + recipients.append({"address":node0_zaddr, "amount":Decimal('30.0')-Decimal('0.0001')}) # utxo amount less fee + myopid = self.nodes[0].z_sendmany(node0_taddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid, 'failed', 'Too many transparent inputs 3 > limit 2') + + # Mine one block + self.nodes[1].generate(1) + self.sync_all() + # The next block to be mined, 110, is the first Overwinter block + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '5ba81b19') + + # z_sendmany should no longer be limited by -mempooltxinputlimit + myopid = self.nodes[0].z_sendmany(node0_taddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + if __name__ == '__main__': MempoolTxInputLimitTest().main() diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 2c0fcd203..13b98e140 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -7,6 +7,7 @@ # 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, \ @@ -86,5 +87,13 @@ class MerkleBlockTest(BitcoinTestFramework): # ...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 + if __name__ == '__main__': MerkleBlockTest().main() diff --git a/qa/rpc-tests/overwinter_peer_management.py b/qa/rpc-tests/overwinter_peer_management.py deleted file mode 100755 index 6c59e47ba..000000000 --- a/qa/rpc-tests/overwinter_peer_management.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2018 The Zcash developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ - msg_ping, MY_VERSION, OVERWINTER_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 and Overwinter mininodes to a Zcashd node -# which will activate Overwinter at block 10. -# -# 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 nodes can connect to Zcash -# 4. new Sprout nodes cannot connect to Zcash -# -# This test *does not* verify that prior to Overwinter activation, the Zcashd -# node will prefer connections with Overwinter nodes, with an eviction process -# that prioritizes Sprout 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 OverwinterPeerManagementTest(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', '-debug', '-whitelist=127.0.0.1']]) - - def run_test(self): - test = TestManager() - - # Launch 10 Sprout and 10 Overwinter mininodes - nodes = [] - for x in xrange(10): - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", False)) - nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", True)) - - # 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(MY_VERSION)) - assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) - - # Overwinter consensus rules activate at block height 10 - self.nodes[0].generate(1) - assert_equal(10, self.nodes[0].getblockcount()) - - # 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 and Overwinter mininodes are still connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(MY_VERSION)) - assert_equal(10, versions.count(OVERWINTER_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", True)) - time.sleep(3) - assert_equal(11, 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", False) - nodes.append(sprout) - time.sleep(3) - assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) - - # Verify that only Overwinter mininodes are connected. - peerinfo = self.nodes[0].getpeerinfo() - versions = [x["version"] for x in peerinfo] - assert_equal(0, versions.count(MY_VERSION)) - assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) - - for node in nodes: - node.disconnect_node() - -if __name__ == '__main__': - OverwinterPeerManagementTest().main() diff --git a/qa/rpc-tests/p2p_node_bloom.py b/qa/rpc-tests/p2p_node_bloom.py new file mode 100755 index 000000000..18476a981 --- /dev/null +++ b/qa/rpc-tests/p2p_node_bloom.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + msg_filteradd, msg_filterclear, mininode_lock, SPROUT_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(SPROUT_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SPROUT_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(SPROUT_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SPROUT_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(SPROUT_PROTO_VERSION)) + peerinfo = self.nodes[1].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(1, versions.count(SPROUT_PROTO_VERSION)) + + [ c.disconnect_node() for c in connections ] + +if __name__ == '__main__': + NodeBloomTest().main() diff --git a/qa/rpc-tests/p2p_nu_peer_management.py b/qa/rpc-tests/p2p_nu_peer_management.py new file mode 100755 index 000000000..6cedf66bb --- /dev/null +++ b/qa/rpc-tests/p2p_nu_peer_management.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import ( + NodeConn, + NodeConnCB, + NetworkThread, + msg_ping, + SPROUT_PROTO_VERSION, + OVERWINTER_PROTO_VERSION, + SAPLING_PROTO_VERSION, +) +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import initialize_chain_clean, start_nodes, \ + p2p_port, assert_equal + +import time + +# +# In this test we connect Sprout, Overwinter, and Sapling mininodes to a Zcashd +# node which will activate Overwinter at block 10 and Sapling at block 15. +# +# We test: +# 1. the mininodes stay connected to Zcash with Sprout consensus rules +# 2. when Overwinter activates, the Sprout mininodes are dropped +# 3. new Overwinter and Sapling nodes can connect to Zcash +# 4. new Sprout nodes cannot connect to Zcash +# 5. when Sapling activates, the Overwinter mininodes are dropped +# 6. new Sapling nodes can connect to Zcash +# 7. new Sprout and Overwinter nodes cannot connect to Zcash +# +# This test *does not* verify that prior to each activation, the Zcashd +# node will prefer connections with NU-aware nodes, with an eviction process +# that prioritizes non-NU-aware connections. +# + + +class TestManager(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + + def on_close(self, conn): + pass + + def on_reject(self, conn, message): + conn.rejectMessage = message + + +class NUPeerManagementTest(BitcoinTestFramework): + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = start_nodes(1, self.options.tmpdir, extra_args=[[ + '-nuparams=5ba81b19:10', # Overwinter + '-nuparams=76b809bb:15', # Sapling + '-debug', + '-whitelist=127.0.0.1', + ]]) + + def run_test(self): + test = TestManager() + + # Launch Sprout, Overwinter, and Sapling mininodes + nodes = [] + for x in xrange(10): + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", SPROUT_PROTO_VERSION)) + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", OVERWINTER_PROTO_VERSION)) + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test, "regtest", SAPLING_PROTO_VERSION)) + + # Start up network handling in another thread + NetworkThread().start() + + # Sprout consensus rules apply at block height 9 + self.nodes[0].generate(9) + assert_equal(9, self.nodes[0].getblockcount()) + + # Verify mininodes are still connected to zcashd node + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(10, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) + + # Overwinter consensus rules activate at block height 10 + self.nodes[0].generate(1) + assert_equal(10, self.nodes[0].getblockcount()) + print('Overwinter active') + + # Mininodes send ping message to zcashd node. + pingCounter = 1 + for node in nodes: + node.send_message(msg_ping(pingCounter)) + pingCounter = pingCounter + 1 + + time.sleep(3) + + # Verify Sprout mininodes have been dropped, while Overwinter and + # Sapling mininodes are still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(10, versions.count(SAPLING_PROTO_VERSION)) + + # Extend the Overwinter chain with another block. + self.nodes[0].generate(1) + + # Connect a new Overwinter mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION)) + time.sleep(3) + assert_equal(21, len(self.nodes[0].getpeerinfo())) + + # Connect a new Sapling mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) + time.sleep(3) + assert_equal(22, len(self.nodes[0].getpeerinfo())) + + # Try to connect a new Sprout mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) + + # Verify that only Overwinter and Sapling mininodes are connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) + + # Sapling consensus rules activate at block height 15 + self.nodes[0].generate(4) + assert_equal(15, self.nodes[0].getblockcount()) + print('Sapling active') + + # Mininodes send ping message to zcashd node. + pingCounter = 1 + for node in nodes: + node.send_message(msg_ping(pingCounter)) + pingCounter = pingCounter + 1 + + time.sleep(3) + + # Verify Sprout and Overwinter mininodes have been dropped, while + # Sapling mininodes are still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(11, versions.count(SAPLING_PROTO_VERSION)) + + # Extend the Sapling chain with another block. + self.nodes[0].generate(1) + + # Connect a new Sapling mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SAPLING_PROTO_VERSION)) + time.sleep(3) + assert_equal(12, len(self.nodes[0].getpeerinfo())) + + # Try to connect a new Sprout mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", SPROUT_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) + + # Try to connect a new Overwinter mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", OVERWINTER_PROTO_VERSION) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170006 or greater" in str(sprout.rejectMessage)) + + # Verify that only Sapling mininodes are connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(SPROUT_PROTO_VERSION)) + assert_equal(0, versions.count(OVERWINTER_PROTO_VERSION)) + assert_equal(12, versions.count(SAPLING_PROTO_VERSION)) + + for node in nodes: + node.disconnect_node() + +if __name__ == '__main__': + NUPeerManagementTest().main() diff --git a/qa/rpc-tests/p2p_txexpiry_dos.py b/qa/rpc-tests/p2p_txexpiry_dos.py new file mode 100755 index 000000000..ec970435a --- /dev/null +++ b/qa/rpc-tests/p2p_txexpiry_dos.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + CTransaction, msg_tx, mininode_lock, OVERWINTER_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, cStringIO +from binascii import hexlify, unhexlify + + +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 TxExpiryDoSTest(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']]) + + def create_transaction(self, node, coinbase, to_address, amount, txModifier=None): + from_txid = node.getblock(coinbase)['tx'][0] + inputs = [{ "txid" : from_txid, "vout" : 0}] + outputs = { to_address : amount } + rawtx = node.createrawtransaction(inputs, outputs) + tx = CTransaction() + + if txModifier: + f = cStringIO.StringIO(unhexlify(rawtx)) + tx.deserialize(f) + txModifier(tx) + rawtx = hexlify(tx.serialize()) + + signresult = node.signrawtransaction(rawtx) + f = cStringIO.StringIO(unhexlify(signresult['hex'])) + tx.deserialize(f) + return tx + + def run_test(self): + test_node = TestNode() + + connections = [] + connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], + test_node, "regtest", OVERWINTER_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(OVERWINTER_PROTO_VERSION)) + assert_equal(0, peerinfo[0]["banscore"]) + + self.coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) + self.nodeaddress = self.nodes[0].getnewaddress() + + # Mininodes send transaction to zcashd node. + def setExpiryHeight(tx): + tx.nExpiryHeight = 101 + + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, 1.0, + txModifier=setExpiryHeight) + 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(OVERWINTER_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(OVERWINTER_PROTO_VERSION)) + assert_equal(10, peerinfo[0]["banscore"]) + + [ c.disconnect_node() for c in connections ] + +if __name__ == '__main__': + TxExpiryDoSTest().main() diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index dc919f028..182f87f08 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -145,5 +145,11 @@ class RawTransactionsTest(BitcoinTestFramework): 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/qa/rpc-tests/regtest_signrawtransaction.py b/qa/rpc-tests/regtest_signrawtransaction.py new file mode 100755 index 000000000..2e0273677 --- /dev/null +++ b/qa/rpc-tests/regtest_signrawtransaction.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import start_nodes, wait_and_assert_operationid_status + +class RegtestSignrawtransactionTest (BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + "-nuparams=5ba81b19:200", # Overwinter + "-nuparams=76b809bb:204", # Sapling + ]] * 4) + + def run_test(self): + self.nodes[0].generate(1) + self.sync_all() + taddr = self.nodes[1].getnewaddress() + zaddr1 = self.nodes[1].z_getnewaddress('sprout') + + self.nodes[0].sendtoaddress(taddr, 2.0) + self.nodes[0].generate(1) + self.sync_all() + + # Create and sign Overwinter 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}]) + wait_and_assert_operationid_status(self.nodes[1], opid) + +if __name__ == '__main__': + RegtestSignrawtransactionTest().main() diff --git a/qa/rpc-tests/rewind_index.py b/qa/rpc-tests/rewind_index.py new file mode 100755 index 000000000..8c5c606df --- /dev/null +++ b/qa/rpc-tests/rewind_index.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, start_node, connect_nodes_bi, bitcoind_processes + +import time + + +class RewindBlockIndexTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self, split=False): + # Node 0 - Overwinter, then Sprout, then Overwinter again + # Node 1 - Sprout + # Node 2 - Overwinter + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-nuparams=5ba81b19:10'], [], ['-nuparams=5ba81b19:10']]) + 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): + # Bring all nodes to just before the activation block + print("Mining blocks...") + self.nodes[0].generate(8) + block9 = self.nodes[0].generate(1)[0] + self.sync_all() + + assert_equal(self.nodes[0].getbestblockhash(), block9) + assert_equal(self.nodes[1].getbestblockhash(), block9) + + print("Mining diverging blocks") + block10s = self.nodes[1].generate(1)[0] + block10o = self.nodes[2].generate(1)[0] + self.sync_all() + + assert_equal(self.nodes[0].getbestblockhash(), block10o) + assert_equal(self.nodes[1].getbestblockhash(), block10s) + assert_equal(self.nodes[2].getbestblockhash(), block10o) + + # Restart node 0 using Sprout instead of Overwinter + print("Switching node 0 from Overwinter to Sprout") + self.nodes[0].stop() + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0,self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + + # Assume node 1 will send block10s to node 0 quickly + # (if we used self.sync_all() here and there was a bug, the test would hang) + time.sleep(2) + + # Node 0 has rewound and is now on the Sprout chain + assert_equal(self.nodes[0].getblockcount(), 10) + assert_equal(self.nodes[0].getbestblockhash(), block10s) + + # Restart node 0 using Overwinter instead of Sprout + print("Switching node 0 from Sprout to Overwinter") + self.nodes[0].stop() + bitcoind_processes[0].wait() + self.nodes[0] = start_node(0,self.options.tmpdir, extra_args=['-nuparams=5ba81b19:10']) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + + # Assume node 2 will send block10o to node 0 quickly + # (if we used self.sync_all() here and there was a bug, the test would hang) + time.sleep(2) + + # Node 0 has rewound and is now on the Overwinter chain again + assert_equal(self.nodes[0].getblockcount(), 10) + assert_equal(self.nodes[0].getbestblockhash(), block10o) + + +if __name__ == '__main__': + RewindBlockIndexTest().main() diff --git a/qa/rpc-tests/signrawtransaction_offline.py b/qa/rpc-tests/signrawtransaction_offline.py new file mode 100755 index 000000000..0d7def43b --- /dev/null +++ b/qa/rpc-tests/signrawtransaction_offline.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python2 + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, initialize_chain_clean, start_node +from test_framework.authproxy import JSONRPCException + +class SignOfflineTest (BitcoinTestFramework): + # Setup Methods + 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_node(0, self.options.tmpdir, ["-nuparams=5ba81b19:10"]) ] + self.is_network_split = False + self.sync_all() + + # Tests + def run_test(self): + print "Mining blocks..." + self.nodes[0].generate(101) + + offline_node = start_node(1, self.options.tmpdir, ["-maxconnections=0", "-nuparams=5ba81b19:10"]) + self.nodes.append(offline_node) + + assert_equal(0, len(offline_node.getpeerinfo())) # make sure node 1 has no peers + + privkeys = [self.nodes[0].dumpprivkey(self.nodes[0].getnewaddress())] + taddr = self.nodes[0].getnewaddress() + + tx = self.nodes[0].listunspent()[0] + txid = tx['txid'] + scriptpubkey = tx['scriptPubKey'] + + create_inputs = [{'txid': txid, 'vout': 0}] + sign_inputs = [{'txid': txid, 'vout': 0, 'scriptPubKey': scriptpubkey, 'amount': 10}] + + create_hex = self.nodes[0].createrawtransaction(create_inputs, {taddr: 9.9999}) + + # An offline regtest node does not rely on the approx release height of the software + # to determine the consensus rules to be used for signing. + try: + signed_tx = offline_node.signrawtransaction(create_hex, sign_inputs, privkeys) + self.nodes[0].sendrawtransaction(signed_tx['hex']) + assert(False) + except JSONRPCException: + pass + + # Passing in the consensus branch id resolves the issue for offline regtest nodes. + signed_tx = offline_node.signrawtransaction(create_hex, sign_inputs, privkeys, "ALL", "5ba81b19") + + # If we return the transaction hash, then we have have not thrown an error (success) + online_tx_hash = self.nodes[0].sendrawtransaction(signed_tx['hex']) + assert_true(len(online_tx_hash) > 0) + +if __name__ == '__main__': + SignOfflineTest().main() \ No newline at end of file diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index 3c9821259..cd29c1791 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -41,9 +41,12 @@ from .equihash import ( OVERWINTER_PROTO_VERSION = 170003 BIP0031_VERSION = 60000 -MY_VERSION = 170002 # past bip-31 for ping/pong +SPROUT_PROTO_VERSION = 170002 # past bip-31 for ping/pong +SAPLING_PROTO_VERSION = 170006 MY_SUBVERSION = "/python-mininode-tester:0.0.1/" +OVERWINTER_VERSION_GROUP_ID = 0x03C48270 + MAX_INV_SZ = 50000 @@ -328,7 +331,7 @@ class CInv(object): class CBlockLocator(object): def __init__(self): - self.nVersion = MY_VERSION + self.nVersion = SPROUT_PROTO_VERSION self.vHave = [] def deserialize(self, f): @@ -565,20 +568,26 @@ class CTxOut(object): class CTransaction(object): def __init__(self, tx=None): if tx is None: + self.fOverwintered = False self.nVersion = 1 + self.nVersionGroupId = 0 self.vin = [] self.vout = [] self.nLockTime = 0 + self.nExpiryHeight = 0 self.vjoinsplit = [] self.joinSplitPubKey = None self.joinSplitSig = None self.sha256 = None self.hash = None else: + self.fOverwintered = tx.fOverwintered self.nVersion = tx.nVersion + self.nVersionGroupId = tx.nVersionGroupId self.vin = copy.deepcopy(tx.vin) self.vout = copy.deepcopy(tx.vout) self.nLockTime = tx.nLockTime + self.nExpiryHeight = tx.nExpiryHeight self.vjoinsplit = copy.deepcopy(tx.vjoinsplit) self.joinSplitPubKey = tx.joinSplitPubKey self.joinSplitSig = tx.joinSplitSig @@ -586,24 +595,46 @@ class CTransaction(object): self.hash = None def deserialize(self, f): - self.nVersion = 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) + 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) + r = "" - r += struct.pack("= 2: r += ser_vector(self.vjoinsplit) if len(self.vjoinsplit) > 0: @@ -628,8 +659,10 @@ class CTransaction(object): return True def __repr__(self): - r = "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i" \ - % (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime) + r = ("CTransaction(fOverwintered=%r nVersion=%i nVersionGroupId=0x%08x " + "vin=%s vout=%s nLockTime=%i nExpiryHeight=%i" + % (self.fOverwintered, self.nVersion, self.nVersionGroupId, + repr(self.vin), repr(self.vout), self.nLockTime, self.nExpiryHeight)) if self.nVersion >= 2: r += " vjoinsplit=%s" % repr(self.vjoinsplit) if len(self.vjoinsplit) > 0: @@ -869,12 +902,8 @@ class CAlert(object): class msg_version(object): command = "version" - def __init__(self, overwintered=False): - if overwintered: - self.nVersion = OVERWINTER_PROTO_VERSION - else: - self.nVersion = MY_VERSION - + def __init__(self, protocol_version=SPROUT_PROTO_VERSION): + self.nVersion = protocol_version self.nServices = 1 self.nTime = time.time() self.addrTo = CAddress() @@ -1231,6 +1260,38 @@ class msg_reject(object): % (self.message, self.code, self.reason, self.data) +class msg_filteradd(object): + command = "filteradd" + + def __init__(self): + self.data = "" + + def deserialize(self, f): + self.data = deser_string(f) + + def serialize(self): + return ser_string(self.data) + + def __repr__(self): + return "msg_filteradd(data=%s)" % (repr(self.data)) + + +class msg_filterclear(object): + command = "filterclear" + + def __init__(self): + pass + + def deserialize(self, f): + pass + + def serialize(self): + return "" + + def __repr__(self): + return "msg_filterclear()" + + # This is what a callback should look like for NodeConn # Reimplement the on_* functions to provide handling for events class NodeConnCB(object): @@ -1270,7 +1331,7 @@ class NodeConnCB(object): def on_version(self, conn, message): if message.nVersion >= 209: conn.send_message(msg_verack()) - conn.ver_send = min(MY_VERSION, message.nVersion) + conn.ver_send = min(SPROUT_PROTO_VERSION, message.nVersion) if message.nVersion < 209: conn.ver_recv = conn.ver_send @@ -1331,7 +1392,7 @@ class NodeConn(asyncore.dispatcher): "regtest": "\xaa\xe8\x3f\x5f" # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", overwintered=False): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", protocol_version=SPROUT_PROTO_VERSION): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1348,14 +1409,14 @@ class NodeConn(asyncore.dispatcher): self.disconnect = False # stuff version msg into sendbuf - vt = msg_version(overwintered) + 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) + + str(dstport) + ' using version ' + str(protocol_version) try: self.connect((dstaddr, dstport)) diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index 56151bb3e..f545b4246 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -90,11 +90,11 @@ class BitcoinTestFramework(object): 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") + help="Leave komodods 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") + help="Don't stop komodods after the test execution") parser.add_option("--srcdir", dest="srcdir", default="../../src", - help="Source directory containing bitcoind/bitcoin-cli (default: %default)") + help="Source directory containing komodod/komodo-cli (default: %default)") 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", @@ -137,7 +137,7 @@ class BitcoinTestFramework(object): stop_nodes(self.nodes) wait_bitcoinds() else: - print("Note: bitcoinds were not stopped and may still be running") + print("Note: komodods were not stopped and may still be running") if not self.options.nocleanup and not self.options.noshutdown: print("Cleaning up") @@ -151,7 +151,7 @@ class BitcoinTestFramework(object): sys.exit(1) -# Test framework for doing p2p comparison testing, which sets up some bitcoind +# Test framework for doing p2p comparison testing, which sets up some komodod # binaries: # 1 binary: test binary # 2 binaries: 1 test binary, 1 ref binary @@ -165,10 +165,10 @@ class ComparisonTestFramework(BitcoinTestFramework): def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", - default=os.getenv("BITCOIND", "bitcoind"), + default=os.getenv("BITCOIND", "komodod"), help="bitcoind binary to test") parser.add_option("--refbinary", dest="refbinary", - default=os.getenv("BITCOIND", "bitcoind"), + default=os.getenv("BITCOIND", "komodod"), help="bitcoind binary to use for reference nodes (if any)") def setup_chain(self): diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index f3ea481ee..661075955 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -1,4 +1,5 @@ # Copyright (c) 2014 The Bitcoin Core developers +# Copyright (c) 2018 The SuperNET developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -75,38 +76,55 @@ def initialize_datadir(dirname, n): datadir = os.path.join(dirname, "node"+str(n)) if not os.path.isdir(datadir): os.makedirs(datadir) - with open(os.path.join(datadir, "zcash.conf"), 'w') as f: + # kmd AC's don't use this, they use the conf auto-created when the AC is created + # plus CLI arguments. This is for komodod tests + print("Writing to " + os.path.join(datadir,"komodo.conf")) + with open(os.path.join(datadir, "komodo.conf"), 'w') as f: f.write("regtest=1\n"); + f.write("txindex=1\n"); + f.write("server=1\n"); f.write("showmetrics=0\n"); f.write("rpcuser=rt\n"); f.write("rpcpassword=rt\n"); - f.write("port="+str(p2p_port(n))+"\n"); - f.write("rpcport="+str(rpc_port(n))+"\n"); + #f.write("port="+str(p2p_port(n))+"\n"); + #rpcport = str(rpc_port(n)) + #f.write("rpcport="+rpcport+"\n"); + #print "RPC port=" + rpcport f.write("listenonion=0\n"); + # TODO: maybe make these optional, defaulted to on for now + f.write("addressindex=1\n"); + f.write("spentindex=1\n"); + f.write("timestampindex=1\n"); return datadir def initialize_chain(test_dir): """ Create (or copy from cache) a 200-block-long chain and 4 wallets. - bitcoind and bitcoin-cli must be in search path. + komodod and komodo-cli must be in search path. """ + print("initialize_chain") if not os.path.isdir(os.path.join("cache", "node0")): devnull = open("/dev/null", "w+") - # Create cache directories, run bitcoinds: + # Create cache directories, run komodods: for i in range(4): datadir=initialize_datadir("cache", i) - args = [ os.getenv("BITCOIND", "bitcoind"), "-keypool=1", "-datadir="+datadir, "-discover=0" ] + args = [ os.getenv("BITCOIND", "komodod"), "-keypool=1", "-datadir="+datadir, "-discover=0" ] if i > 0: args.append("-connect=127.0.0.1:"+str(p2p_port(0))) bitcoind_processes[i] = subprocess.Popen(args) + cmd = os.getenv("BITCOINCLI", "komodo-cli") + cmd_args = cmd + " -datadir="+datadir + " -rpcwait getblockcount" if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: bitcoind started, calling bitcoin-cli -rpcwait getblockcount" - subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir, - "-rpcwait", "getblockcount"], stdout=devnull) + print "initialize_chain: komodod started, calling: " + cmd_args + strcmd = cmd + " " + "-datadir="+datadir + " -rpcwait getblockcount" + + print("Running " + strcmd) + subprocess.check_call(strcmd, shell=True); + #subprocess.check_call([ cmd, "-rpcwait", "getblockcount"], stdout=devnull) if os.getenv("PYTHON_DEBUG", ""): - print "initialize_chain: bitcoin-cli -rpcwait getblockcount completed" + print "initialize_chain: komodo-cli -rpcwait getblockcount completed" devnull.close() rpcs = [] for i in range(4): @@ -144,7 +162,7 @@ def initialize_chain(test_dir): from_dir = os.path.join("cache", "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 + initialize_datadir(test_dir, i) # Overwrite port/rpcport in komodo.conf def initialize_chain_clean(test_dir, num_nodes): """ @@ -177,34 +195,50 @@ def _rpchost_to_args(rpchost): def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): """ - Start a bitcoind and return RPC connection to it + Start a komodod and return RPC connection to it """ datadir = os.path.join(dirname, "node"+str(i)) if binary is None: - binary = os.getenv("BITCOIND", "bitcoind") + binary = os.getenv("BITCOIND", "komodod") args = [ binary, "-datadir="+datadir, "-keypool=1", "-discover=0", "-rest" ] if extra_args is not None: args.extend(extra_args) + #print("args=" + ' '.join(args)) bitcoind_processes[i] = subprocess.Popen(args) devnull = open("/dev/null", "w+") + + cmd = os.getenv("BITCOINCLI", "komodo-cli") + print("cmd=" + cmd) + cmd_args = ' '.join(extra_args) + " -rpcwait getblockcount " if os.getenv("PYTHON_DEBUG", ""): - print "start_node: bitcoind started, calling bitcoin-cli -rpcwait getblockcount" - subprocess.check_call([ os.getenv("BITCOINCLI", "bitcoin-cli"), "-datadir="+datadir] + - _rpchost_to_args(rpchost) + - ["-rpcwait", "getblockcount"], stdout=devnull) + print "start_node: komodod started, calling : " + cmd + " " + cmd_args + strcmd = cmd + " " + cmd_args + + print("Running " + strcmd) + import time + time.sleep(2) + subprocess.check_call(strcmd, shell=True); + #subprocess.check_call([ os.getenv("BITCOINCLI", "komodo-cli"), "-datadir="+datadir] + + # _rpchost_to_args(rpchost) + + # ["-rpcwait", "-rpcport=6438", "getblockcount"], stdout=devnull) if os.getenv("PYTHON_DEBUG", ""): - print "start_node: calling bitcoin-cli -rpcwait getblockcount returned" + print "start_node: calling komodo-cli -rpcwait getblockcount returned" devnull.close() - url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + if extra_args[0] == '-ac_name=REGTEST': + url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', 64368) + else: + url = "http://rt:rt@%s:%d" % (rpchost or '127.0.0.1', rpc_port(i)) + print("connecting to " + url) if timewait is not None: proxy = AuthServiceProxy(url, timeout=timewait) else: proxy = AuthServiceProxy(url) + print("created proxy") proxy.url = url # store URL on proxy for info return proxy def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): """ - Start multiple bitcoinds, return RPC connections to them + Start multiple komodods, return RPC connections to them """ if extra_args is None: extra_args = [ None for i in range(num_nodes) ] if binary is None: binary = [ None for i in range(num_nodes) ] @@ -355,9 +389,18 @@ def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants): return (txid, signresult["hex"], fee) -def assert_equal(thing1, thing2): - if thing1 != thing2: - raise AssertionError("%s != %s"%(str(thing1),str(thing2))) +def assert_equal(expected, actual, message = ""): + if expected != actual: + if message: + message = "%s; " % message + raise AssertionError("%sexpected: <%s> but was: <%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: @@ -374,31 +417,36 @@ def assert_raises(exc, fun, *args, **kwds): raise AssertionError("No exception raised") # Returns txid if operation was a success or None -def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None): +def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None, timeout=300): print('waiting for async operation {}'.format(myopid)) - opids = [] - opids.append(myopid) - timeout = 300 - status = None - errormsg = None - txid = None - for x in xrange(1, timeout): - results = node.z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - if status == "failed": - errormsg = results[0]['error']['message'] - elif status == "success": - txid = results[0]['result']['txid'] + result = None + for _ in xrange(1, timeout): + results = node.z_getoperationresult([myopid]) + if len(results) > 0: + result = results[0] break - assert_equal(in_status, status) - if errormsg is not None: - assert(in_errormsg is not None) - assert_equal(in_errormsg in errormsg, True) + time.sleep(1) + + assert_true(result is not None, "timeout occured") + status = result['status'] + + txid = None + errormsg = None + if status == "failed": + errormsg = result['error']['message'] + elif status == "success": + txid = result['result']['txid'] + if os.getenv("PYTHON_DEBUG", ""): print('...returned status: {}'.format(status)) if errormsg is not None: print('...returned error: {}'.format(errormsg)) - return txid + + assert_equal(in_status, status, "Operation returned mismatched status. Error Message: {}".format(errormsg)) + + if errormsg is not None: + assert_true(in_errormsg is not None, "No error retured. Expected: {}".format(errormsg)) + assert_true(in_errormsg in errormsg, "Error returned: {}. Error expected: {}".format(errormsg, in_errormsg)) + return result # if there was an error return the result + else: + return txid # otherwise return the txid diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index 12dfac0e4..5d221a28c 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -8,9 +8,9 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, assert_greater_than, \ initialize_chain_clean, start_nodes, start_node, connect_nodes_bi, \ - stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds + stop_nodes, sync_blocks, sync_mempools, wait_and_assert_operationid_status, \ + wait_bitcoinds -import time from decimal import Decimal class WalletTest (BitcoinTestFramework): @@ -89,6 +89,26 @@ class WalletTest (BitcoinTestFramework): 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 from an utxo of value 10.0 but don't specify a change output, so then + # the change of 9.0 becomes the fee, which is greater than estimated fee of 0.0019. + 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,e: + errorString = e.error['message'] + assert("absurdly high fees" in errorString) + assert("900000000 > 190000" in errorString) + # create both transactions txns_to_send = [] for utxo in node0utxos: @@ -199,7 +219,7 @@ class WalletTest (BitcoinTestFramework): for uTx in unspentTxs: if uTx['txid'] == zeroValueTxid: found = True - assert_equal(uTx['amount'], Decimal('0.00000000')); + assert_equal(uTx['amount'], Decimal('0.00000000')) assert(found) #do some -walletbroadcast tests @@ -211,13 +231,13 @@ class WalletTest (BitcoinTestFramework): connect_nodes_bi(self.nodes,0,2) self.sync_all() - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + 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('9.99800000')); #should not be changed because tx was not broadcasted - assert_equal(self.nodes[2].getbalance("*"), Decimal('9.99800000')); #should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance(), Decimal('9.99800000')) #should not be changed because tx was not broadcasted + assert_equal(self.nodes[2].getbalance("*"), Decimal('9.99800000')) #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']) @@ -225,11 +245,11 @@ class WalletTest (BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted) - assert_equal(self.nodes[2].getbalance(), Decimal('11.99800000')); #should not be - assert_equal(self.nodes[2].getbalance("*"), Decimal('11.99800000')); #should not be + assert_equal(self.nodes[2].getbalance(), Decimal('11.99800000')) #should not be + assert_equal(self.nodes[2].getbalance("*"), Decimal('11.99800000')) #should not be #create another tx - txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2); + txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2) #restart the nodes with -walletbroadcast=1 stop_nodes(self.nodes) @@ -244,18 +264,18 @@ class WalletTest (BitcoinTestFramework): sync_blocks(self.nodes) #tx should be added to balance because after restarting the nodes tx should be broadcastet - assert_equal(self.nodes[2].getbalance(), Decimal('13.99800000')); #should not be - assert_equal(self.nodes[2].getbalance("*"), Decimal('13.99800000')); #should not be + assert_equal(self.nodes[2].getbalance(), Decimal('13.99800000')) #should not be + assert_equal(self.nodes[2].getbalance("*"), Decimal('13.99800000')) #should not be # send from node 0 to node 2 taddr - mytaddr = self.nodes[2].getnewaddress(); - mytxid = self.nodes[0].sendtoaddress(mytaddr, 10.0); + 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')); + assert_equal(mybalance, Decimal('10.0')) mytxdetails = self.nodes[2].gettransaction(mytxid) myvjoinsplits = mytxdetails["vjoinsplit"] @@ -328,23 +348,9 @@ class WalletTest (BitcoinTestFramework): # send node 2 taddr to zaddr recipients = [] recipients.append({"address":myzaddr, "amount":7}) - myopid = self.nodes[2].z_sendmany(mytaddr, recipients) - opids = [] - opids.append(myopid) + mytxid = wait_and_assert_operationid_status(self.nodes[2], self.nodes[2].z_sendmany(mytaddr, recipients)) - timeout = 300 - status = None - for x in xrange(1, timeout): - results = self.nodes[2].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - mytxid = results[0]["result"]["txid"] - break - - assert_equal("success", status) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -358,7 +364,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[2].getbalance("*"), node2utxobalance) # check zaddr balance - assert_equal(self.nodes[2].z_getbalance(myzaddr), zsendmanynotevalue); + assert_equal(self.nodes[2].z_getbalance(myzaddr), zsendmanynotevalue) # check via z_gettotalbalance resp = self.nodes[2].z_gettotalbalance() @@ -379,7 +385,6 @@ class WalletTest (BitcoinTestFramework): assert("randomSeed" in myjoinsplit.keys()) assert("ciphertexts" in myjoinsplit.keys()) - # send from private note to node 0 and node 2 node0balance = self.nodes[0].getbalance() # 25.99794745 node2balance = self.nodes[2].getbalance() # 16.99790000 @@ -387,20 +392,9 @@ class WalletTest (BitcoinTestFramework): recipients = [] recipients.append({"address":self.nodes[0].getnewaddress(), "amount":1}) recipients.append({"address":self.nodes[2].getnewaddress(), "amount":1.0}) - myopid = self.nodes[2].z_sendmany(myzaddr, recipients) + + wait_and_assert_operationid_status(self.nodes[2], self.nodes[2].z_sendmany(myzaddr, recipients)) - status = None - opids = [] - opids.append(myopid) - for x in xrange(1, timeout): - results = self.nodes[2].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - break - - assert_equal("success", status) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -433,7 +427,7 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("Invalid amount" in errorString, True); + assert_equal("Invalid amount" in errorString, True) errorString = "" try: @@ -441,7 +435,63 @@ class WalletTest (BitcoinTestFramework): except JSONRPCException,e: errorString = e.error['message'] - assert_equal("not an integer" in errorString, True); + 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,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,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,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,e: + errorString = e.error['message'] + print errorString + assert(False) if __name__ == '__main__': diff --git a/qa/rpc-tests/wallet_addresses.py b/qa/rpc-tests/wallet_addresses.py new file mode 100755 index 000000000..0b9669972 --- /dev/null +++ b/qa/rpc-tests/wallet_addresses.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, start_nodes + +# Test wallet address behaviour across network upgradesa\ +class WalletAddressesTest(BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + '-nuparams=5ba81b19:202', # Overwinter + '-nuparams=76b809bb:204', # Sapling + ]] * 4) + + def run_test(self): + def addr_checks(default_type): + # Check default type, as well as explicit types + types_and_addresses = [ + (default_type, self.nodes[0].z_getnewaddress()), + ('sprout', self.nodes[0].z_getnewaddress('sprout')), + ('sapling', self.nodes[0].z_getnewaddress('sapling')), + ] + + all_addresses = self.nodes[0].z_listaddresses() + + for addr_type, addr in types_and_addresses: + res = self.nodes[0].z_validateaddress(addr) + assert(res['isvalid']) + assert(res['ismine']) + assert_equal(res['type'], addr_type) + assert(addr in all_addresses) + + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Current height = 200 -> Sprout + # Default address type is Sprout + print "Testing height 200 (Sprout)" + addr_checks('sprout') + + self.nodes[0].generate(1) + self.sync_all() + + # Current height = 201 -> Sprout + # Default address type is Sprout + print "Testing height 201 (Sprout)" + addr_checks('sprout') + + self.nodes[0].generate(1) + self.sync_all() + + # Current height = 202 -> Overwinter + # Default address type is Sprout + print "Testing height 202 (Overwinter)" + addr_checks('sprout') + + self.nodes[0].generate(1) + self.sync_all() + + # Current height = 203 -> Overwinter + # Default address type is Sprout + print "Testing height 203 (Overwinter)" + addr_checks('sprout') + + self.nodes[0].generate(1) + self.sync_all() + + # Current height = 204 -> Sapling + # Default address type is Sprout + print "Testing height 204 (Sapling)" + addr_checks('sprout') + +if __name__ == '__main__': + WalletAddressesTest().main() diff --git a/qa/rpc-tests/wallet_anchorfork.py b/qa/rpc-tests/wallet_anchorfork.py index a4df66daf..0e2d19385 100755 --- a/qa/rpc-tests/wallet_anchorfork.py +++ b/qa/rpc-tests/wallet_anchorfork.py @@ -4,7 +4,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import assert_equal, initialize_chain_clean, \ start_nodes, stop_nodes, connect_nodes_bi, \ wait_and_assert_operationid_status, wait_bitcoinds diff --git a/qa/rpc-tests/wallet_changeindicator.py b/qa/rpc-tests/wallet_changeindicator.py new file mode 100755 index 000000000..d26381064 --- /dev/null +++ b/qa/rpc-tests/wallet_changeindicator.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.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) + assert_equal(2, 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]) + assert_false('change' in unspent_node0[1]) + +if __name__ == '__main__': + WalletChangeIndicatorTest().main() diff --git a/qa/rpc-tests/wallet_import_export.py b/qa/rpc-tests/wallet_import_export.py new file mode 100755 index 000000000..cdcc01d1f --- /dev/null +++ b/qa/rpc-tests/wallet_import_export.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.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)] 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) + + 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 perserved 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").readlines() + # We expect information about the HDSeed and fingerpring in the header + assert_true("HDSeed" in file_lines[4], "Expected HDSeed") + assert_true("fingerprint" in file_lines[4], "Expected fingerprint") + seed_comment_line = file_lines[4][2:].split() # ["HDSeed=...", "fingerprint=..."] + assert_true(seed_comment_line[0].split("=")[1] != seed_comment_line[1].split("=")[1], "The seed should not equal the fingerprint") + (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 (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() \ No newline at end of file diff --git a/qa/rpc-tests/wallet_listnotes.py b/qa/rpc-tests/wallet_listnotes.py new file mode 100755 index 000000000..5cd89c661 --- /dev/null +++ b/qa/rpc-tests/wallet_listnotes.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, start_nodes, wait_and_assert_operationid_status + +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=5ba81b19:202', # Overwinter + '-nuparams=76b809bb:204', # Sapling + ]] * 4) + + def run_test(self): + # Current height = 200 -> Sprout + assert_equal(200, self.nodes[0].getblockcount()) + sproutzaddr = self.nodes[0].z_getnewaddress('sprout') + + # test that we can create a sapling zaddr before sapling activates + saplingzaddr = self.nodes[0].z_getnewaddress('sapling') + + # we've got lots of coinbase (taddr) but no shielded funds yet + assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private'])) + + # Set current height to 201 -> Sprout + self.nodes[0].generate(1) + self.sync_all() + assert_equal(201, self.nodes[0].getblockcount()) + + mining_addr = self.nodes[0].listunspent()[0]['address'] + + # Shield coinbase funds (must be a multiple of 10, no change allowed pre-sapling) + receive_amount_10 = Decimal('10.0') - Decimal('0.0001') + recipients = [{"address":sproutzaddr, "amount":receive_amount_10}] + myopid = self.nodes[0].z_sendmany(mining_addr, recipients) + txid_1 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + + # No funds (with (default) one or more confirmations) in sproutzaddr yet + assert_equal(0, len(self.nodes[0].z_listunspent())) + assert_equal(0, len(self.nodes[0].z_listunspent(1))) + + # no private balance because no confirmations yet + assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private'])) + + # list private unspent, this time allowing 0 confirmations + unspent_cb = self.nodes[0].z_listunspent(0) + assert_equal(1, len(unspent_cb)) + assert_equal(False, unspent_cb[0]['change']) + assert_equal(txid_1, unspent_cb[0]['txid']) + assert_equal(True, unspent_cb[0]['spendable']) + assert_equal(sproutzaddr, unspent_cb[0]['address']) + assert_equal(receive_amount_10, unspent_cb[0]['amount']) + + # list unspent, filtering by address, should produce same result + unspent_cb_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr]) + assert_equal(unspent_cb, unspent_cb_filter) + + # Generate a block to confirm shield coinbase tx + self.nodes[0].generate(1) + self.sync_all() + + # Current height = 202 -> Overwinter. Default address type remains Sprout + assert_equal(202, self.nodes[0].getblockcount()) + + # Send 1.0 (actually 0.9999) from sproutzaddr to a new zaddr + sproutzaddr2 = self.nodes[0].z_getnewaddress() + receive_amount_1 = Decimal('1.0') - Decimal('0.0001') + change_amount_9 = receive_amount_10 - Decimal('1.0') + assert_equal('sprout', self.nodes[0].z_validateaddress(sproutzaddr2)['type']) + recipients = [{"address": sproutzaddr2, "amount":receive_amount_1}] + myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients) + txid_2 = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + + # list unspent, allowing 0conf txs + unspent_tx = self.nodes[0].z_listunspent(0) + assert_equal(len(unspent_tx), 2) + # sort low-to-high by amount (order of returned entries is not guaranteed) + unspent_tx = sorted(unspent_tx, key=lambda k: k['amount']) + assert_equal(False, unspent_tx[0]['change']) + assert_equal(txid_2, unspent_tx[0]['txid']) + assert_equal(True, unspent_tx[0]['spendable']) + assert_equal(sproutzaddr2, unspent_tx[0]['address']) + assert_equal(receive_amount_1, unspent_tx[0]['amount']) + + assert_equal(True, unspent_tx[1]['change']) + assert_equal(txid_2, unspent_tx[1]['txid']) + assert_equal(True, unspent_tx[1]['spendable']) + assert_equal(sproutzaddr, unspent_tx[1]['address']) + assert_equal(change_amount_9, unspent_tx[1]['amount']) + + unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr2]) + assert_equal(1, len(unspent_tx_filter)) + assert_equal(unspent_tx[0], unspent_tx_filter[0]) + + unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr]) + assert_equal(1, len(unspent_tx_filter)) + assert_equal(unspent_tx[1], unspent_tx_filter[0]) + + # Set current height to 204 -> Sapling + self.nodes[0].generate(2) + self.sync_all() + assert_equal(204, self.nodes[0].getblockcount()) + + # No funds in saplingzaddr yet + assert_equal(0, len(self.nodes[0].z_listunspent(0, 9999, False, [saplingzaddr]))) + + # Send 0.9999 to our sapling zaddr + # (sending from a sprout zaddr to a sapling zaddr is disallowed, + # so send from coin base) + receive_amount_2 = Decimal('2.0') - Decimal('0.0001') + recipients = [{"address": saplingzaddr, "amount":receive_amount_2}] + myopid = self.nodes[0].z_sendmany(mining_addr, recipients) + 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(True, unspent_tx[0]['spendable']) + assert_equal(sproutzaddr2, unspent_tx[0]['address']) + assert_equal(receive_amount_1, unspent_tx[0]['amount']) + + assert_equal(False, unspent_tx[1]['change']) + assert_equal(txid_3, unspent_tx[1]['txid']) + assert_equal(True, unspent_tx[1]['spendable']) + assert_equal(saplingzaddr, unspent_tx[1]['address']) + assert_equal(receive_amount_2, unspent_tx[1]['amount']) + + assert_equal(True, unspent_tx[2]['change']) + assert_equal(txid_2, unspent_tx[2]['txid']) + assert_equal(True, unspent_tx[2]['spendable']) + assert_equal(sproutzaddr, unspent_tx[2]['address']) + assert_equal(change_amount_9, 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[1], 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[1], 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 + +if __name__ == '__main__': + WalletListNotes().main() diff --git a/qa/rpc-tests/wallet_listreceived.py b/qa/rpc-tests/wallet_listreceived.py new file mode 100755 index 000000000..9ece27772 --- /dev/null +++ b/qa/rpc-tests/wallet_listreceived.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_true, assert_false +from test_framework.util import start_nodes, wait_and_assert_operationid_status +from decimal import Decimal + +my_memo = 'c0ffee' # stay awake +my_memo = my_memo + '0'*(1024-len(my_memo)) + +no_memo = 'f6' + ('0'*1022) # see section 5.5 of the protocol spec + +fee = Decimal('0.0001') + +class ListReceivedTest (BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + "-nuparams=5ba81b19:201", # Overwinter + "-nuparams=76b809bb:204", # Sapling + ]] * 4) + + def generate_and_sync(self, new_height): + self.nodes[0].generate(1) + self.sync_all() + assert_equal(new_height, self.nodes[0].getblockcount()) + + def run_test_release(self, release, expected_memo, height): + self.generate_and_sync(height+1) + taddr = self.nodes[1].getnewaddress() + zaddr1 = self.nodes[1].z_getnewaddress(release) + + self.nodes[0].sendtoaddress(taddr, 2.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}]) + txid = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + r = self.nodes[1].z_listreceivedbyaddress(zaddr1) + assert_equal(0, len(r), "Should have received no confirmed note") + + # 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_false(r[0]['change'], "Note should not be change") + assert_equal(my_memo, r[0]['memo']) + + # Confirm transaction (1 ZEC from taddr to zaddr1) + self.generate_and_sync(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 + zaddr2 = self.nodes[1].z_getnewaddress(release) + opid = self.nodes[1].z_sendmany(zaddr1, + [{'address': zaddr2, 'amount': 0.6, 'memo': my_memo}]) + txid = wait_and_assert_operationid_status(self.nodes[1], opid) + self.sync_all() + self.generate_and_sync(height+4) + + # zaddr1 should have a note with change + r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0) + r = sorted(r, key = lambda received: received['amount']) + assert_equal(2, len(r), "zaddr1 Should have received 2 notes") + + assert_equal(txid, r[0]['txid']) + assert_equal(Decimal('0.4')-fee, r[0]['amount']) + assert_true(r[0]['change'], "Note valued at (0.4-fee) should be change") + assert_equal(expected_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_false(r[1]['change'], "Note valued at 1.0 should not be change") + assert_equal(expected_memo, r[0]['memo']) + + # zaddr2 should not have change + r = self.nodes[1].z_listreceivedbyaddress(zaddr2, 0) + r = sorted(r, key = lambda received: received['amount']) + assert_equal(1, len(r), "zaddr2 Should have received 1 notes") + assert_equal(txid, r[0]['txid']) + assert_equal(Decimal('0.6'), r[0]['amount']) + assert_false(r[0]['change'], "Note valued at 0.6 should not be change") + assert_equal(my_memo, r[0]['memo']) + + def run_test(self): + self.run_test_release('sprout', no_memo, 200) + self.run_test_release('sapling', no_memo, 204) + +if __name__ == '__main__': + ListReceivedTest().main() diff --git a/qa/rpc-tests/wallet_nullifiers.py b/qa/rpc-tests/wallet_nullifiers.py index 207631efb..9b4e5649c 100755 --- a/qa/rpc-tests/wallet_nullifiers.py +++ b/qa/rpc-tests/wallet_nullifiers.py @@ -5,10 +5,9 @@ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, start_node, \ - start_nodes, connect_nodes_bi, bitcoind_processes +from test_framework.util import assert_equal, assert_true, bitcoind_processes, \ + connect_nodes_bi, start_node, start_nodes, wait_and_assert_operationid_status -import time from decimal import Decimal class WalletNullifiersTest (BitcoinTestFramework): @@ -22,25 +21,11 @@ class WalletNullifiersTest (BitcoinTestFramework): myzaddr0 = self.nodes[0].z_getnewaddress() # send node 0 taddr to zaddr to get out of coinbase - mytaddr = self.nodes[0].getnewaddress(); + mytaddr = self.nodes[0].getnewaddress() recipients = [] recipients.append({"address":myzaddr0, "amount":Decimal('10.0')-Decimal('0.0001')}) # utxo amount less fee - myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - - opids = [] - opids.append(myopid) - - timeout = 120 - status = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - assert_equal("success", status) - mytxid = results[0]["result"]["txid"] - break + + 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) @@ -66,22 +51,8 @@ class WalletNullifiersTest (BitcoinTestFramework): # send node 0 zaddr to note 2 zaddr recipients = [] recipients.append({"address":myzaddr, "amount":7.0}) - myopid = self.nodes[0].z_sendmany(myzaddr0, recipients) - - opids = [] - opids.append(myopid) - - timeout = 120 - status = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - assert_equal("success", status) - mytxid = results[0]["result"]["txid"] - break + + wait_and_assert_operationid_status(self.nodes[0], self.nodes[0].z_sendmany(myzaddr0, recipients), timeout=120) self.sync_all() self.nodes[0].generate(1) @@ -98,22 +69,8 @@ class WalletNullifiersTest (BitcoinTestFramework): # send node 2 zaddr to note 3 zaddr recipients = [] recipients.append({"address":myzaddr3, "amount":2.0}) - myopid = self.nodes[2].z_sendmany(myzaddr, recipients) - opids = [] - opids.append(myopid) - - timeout = 120 - status = None - for x in xrange(1, timeout): - results = self.nodes[2].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - assert_equal("success", status) - mytxid = results[0]["result"]["txid"] - break + wait_and_assert_operationid_status(self.nodes[2], self.nodes[2].z_sendmany(myzaddr, recipients), timeout=120) self.sync_all() self.nodes[2].generate(1) @@ -136,26 +93,11 @@ class WalletNullifiersTest (BitcoinTestFramework): # This requires that node 1 be unlocked, which triggers caching of # uncached nullifiers. self.nodes[1].walletpassphrase("test", 600) - mytaddr1 = self.nodes[1].getnewaddress(); + mytaddr1 = self.nodes[1].getnewaddress() recipients = [] recipients.append({"address":mytaddr1, "amount":1.0}) - myopid = self.nodes[1].z_sendmany(myzaddr, recipients) - - opids = [] - opids.append(myopid) - - timeout = 120 - status = None - for x in xrange(1, timeout): - results = self.nodes[1].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - assert_equal("success", status) - mytxid = results[0]["result"]["txid"] - [mytxid] # hush pyflakes - break + + wait_and_assert_operationid_status(self.nodes[1], self.nodes[1].z_sendmany(myzaddr, recipients), timeout=120) self.sync_all() self.nodes[1].generate(1) @@ -188,10 +130,23 @@ class WalletNullifiersTest (BitcoinTestFramework): 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 - assert_equal( - self.nodes[2].z_listreceivedbyaddress(myzaddr), - self.nodes[3].z_listreceivedbyaddress(myzaddr)) + # Node 3 should see the same received notes as node 2; however, + # some of the notes were change for node 2 but not for node 3. + # Aside from that the recieved 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 + if key != 'change': + assert_equal(received2[key], received3[key]) # Node 3's balances should be unchanged without explicitly requesting # to include watch-only balances diff --git a/qa/rpc-tests/wallet_overwintertx.py b/qa/rpc-tests/wallet_overwintertx.py index 61932fece..d77a114db 100755 --- a/qa/rpc-tests/wallet_overwintertx.py +++ b/qa/rpc-tests/wallet_overwintertx.py @@ -6,6 +6,7 @@ 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 +from test_framework.authproxy import JSONRPCException from decimal import Decimal @@ -46,6 +47,13 @@ class WalletOverwinterTxTest (BitcoinTestFramework): assert_equal(bci['consensus']['nextblock'], '00000000') assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') + # Cannot use the expiryheight parameter of createrawtransaction if Overwinter is not active in the next block + try: + self.nodes[0].createrawtransaction([], {}, 0, 99) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Invalid parameter, expiryheight can only be used if Overwinter is active when the transaction is mined" in errorString, True) + # Node 0 sends transparent funds to Node 2 tsendamount = Decimal('1.0') txid_transparent = self.nodes[0].sendtoaddress(taddr2, tsendamount) @@ -92,6 +100,24 @@ class WalletOverwinterTxTest (BitcoinTestFramework): assert_equal(bci['consensus']['nextblock'], '5ba81b19') assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') + # Test using expiryheight parameter of createrawtransaction when Overwinter is active in the next block + errorString = "" + try: + self.nodes[0].createrawtransaction([], {}, 0, 499999999) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("", errorString) + try: + self.nodes[0].createrawtransaction([], {}, 0, -1) + except JSONRPCException,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,e: + errorString = e.error['message'] + assert_equal("Invalid parameter, expiryheight must be nonnegative and less than 500000000" in errorString, True) + # Node 0 sends transparent funds to Node 3 tsendamount = Decimal('1.0') txid_transparent = self.nodes[0].sendtoaddress(taddr3, tsendamount) diff --git a/qa/rpc-tests/wallet_persistence.py b/qa/rpc-tests/wallet_persistence.py new file mode 100755 index 000000000..f6c227d2a --- /dev/null +++ b/qa/rpc-tests/wallet_persistence.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, assert_true, + 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, 3) + + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir, + extra_args=[[ + '-nuparams=5ba81b19:100', # Overwinter + '-nuparams=76b809bb:201', # Sapling + ]] * 3) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + 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 (even when Sapling is not yet active) + sapling_addr = self.nodes[0].z_getnewaddress('sapling') + + # Make sure the node has the addresss + 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") + + # Activate Sapling + self.nodes[0].generate(1) + self.sync_all() + + # Node 0 shields funds to Sapling address + taddr0 = self.nodes[0].getnewaddress() + 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')) + + # Restart the nodes + stop_nodes(self.nodes) + wait_bitcoinds() + self.setup_network() + + # 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')) + + # 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')) + + # 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/qa/rpc-tests/wallet_protectcoinbase.py b/qa/rpc-tests/wallet_protectcoinbase.py index afe851a16..71512840d 100755 --- a/qa/rpc-tests/wallet_protectcoinbase.py +++ b/qa/rpc-tests/wallet_protectcoinbase.py @@ -8,10 +8,9 @@ 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, stop_node, wait_and_assert_operationid_status + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status import sys -import time import timeit from decimal import Decimal @@ -82,52 +81,29 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): self.nodes[3].importaddress(mytaddr) recipients= [{"address":myzaddr, "amount": Decimal('1')}] myopid = self.nodes[3].z_sendmany(mytaddr, recipients) - errorString="" - status = None - opids = [myopid] - timeout = 10 - for x in xrange(1, timeout): - results = self.nodes[3].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - errorString = results[0]["error"]["message"] - break - assert_equal("failed", status) - assert_equal("no UTXOs found for taddr from address" in errorString, True) - stop_node(self.nodes[3], 3) - self.nodes.pop() + + wait_and_assert_operationid_status(self.nodes[3], myopid, "failed", "no UTXOs found for taddr from address", 10) # This send will fail because our wallet does not allow any change when protecting a coinbase utxo, # as it's currently not possible to specify a change address in z_sendmany. recipients = [] recipients.append({"address":myzaddr, "amount":Decimal('1.23456789')}) - errorString = "" + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - opids = [] - opids.append(myopid) - timeout = 10 - status = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - time.sleep(1) - else: - status = results[0]["status"] - errorString = results[0]["error"]["message"] + error_result = wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "wallet does not allow any change", 10) - # Test that the returned status object contains a params field with the operation's input parameters - assert_equal(results[0]["method"], "z_sendmany") - params =results[0]["params"] - assert_equal(params["fee"], Decimal('0.0001')) # default - assert_equal(params["minconf"], Decimal('1')) # default - assert_equal(params["fromaddress"], mytaddr) - assert_equal(params["amounts"][0]["address"], myzaddr) - assert_equal(params["amounts"][0]["amount"], Decimal('1.23456789')) - break - assert_equal("failed", status) - assert_equal("wallet does not allow any change" in errorString, True) + # 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"], Decimal('0.0001')) # default + assert_equal(params["minconf"], Decimal('1')) # 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 fee of 0.00010000, with no change. shieldvalue = Decimal('20.0') - Decimal('0.0001') @@ -136,9 +112,43 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): 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]["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]["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]["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 address does not belong to wallet" in errorString, True) + # Verify that debug=zrpcunsafe logs params, and that full txid is associated with opid logpath = self.options.tmpdir+"/node0/regtest/debug.log" logcounter = 0 @@ -226,7 +236,7 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): myopid = self.nodes[0].z_sendmany(mytaddr, recipients) wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient transparent funds, have 10.00, need 10000.0001") myopid = self.nodes[0].z_sendmany(myzaddr, recipients) - wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient protected funds, have 9.9998, need 10000.0001") + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient shielded funds, have 9.9998, need 10000.0001") # Send will fail because of insufficient funds unless sender uses coinbase utxos try: @@ -333,13 +343,22 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() - # check balances + # 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) sproutvalue -= custom_fee check_value_pool(self.nodes[0], 'sprout', sproutvalue) + 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__': WalletProtectCoinbaseTest().main() diff --git a/qa/rpc-tests/wallet_sapling.py b/qa/rpc-tests/wallet_sapling.py new file mode 100755 index 000000000..1abb1e8dc --- /dev/null +++ b/qa/rpc-tests/wallet_sapling.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import ( + assert_equal, + start_nodes, + wait_and_assert_operationid_status, +) + +from decimal import Decimal + +# Test wallet behaviour with Sapling addresses +class WalletSaplingTest(BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [[ + '-nuparams=5ba81b19:201', # Overwinter + '-nuparams=76b809bb:203', # Sapling + '-experimentalfeatures', '-zmergetoaddress', + ]] * 4) + + def run_test(self): + # Sanity-check the test harness + assert_equal(self.nodes[0].getblockcount(), 200) + + # Activate Overwinter + self.nodes[2].generate(1) + self.sync_all() + + # Verify RPCs disallow Sapling value transfer if Sapling is not active + tmp_taddr = self.nodes[3].getnewaddress() + tmp_zaddr = self.nodes[3].z_getnewaddress('sapling') + try: + recipients = [] + recipients.append({"address": tmp_zaddr, "amount": Decimal('20')}) + self.nodes[3].z_sendmany(tmp_taddr, recipients, 1, 0) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Invalid parameter, Sapling has not activated", e.error['message']) + try: + recipients = [] + recipients.append({"address": tmp_taddr, "amount": Decimal('20')}) + self.nodes[3].z_sendmany(tmp_zaddr, recipients, 1, 0) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Invalid parameter, Sapling has not activated", e.error['message']) + try: + self.nodes[3].z_shieldcoinbase(tmp_taddr, tmp_zaddr) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Invalid parameter, Sapling has not activated", e.error['message']) + + # Verify z_mergetoaddress RPC does not support Sapling yet + try: + self.nodes[3].z_mergetoaddress([tmp_taddr], tmp_zaddr) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Invalid parameter, Sapling is not supported yet by z_mergetoadress", e.error['message']) + try: + self.nodes[3].z_mergetoaddress([tmp_zaddr], tmp_taddr) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Invalid parameter, Sapling is not supported yet by z_mergetoadress", e.error['message']) + + # Activate Sapling + self.nodes[2].generate(2) + self.sync_all() + + taddr0 = self.nodes[0].getnewaddress() + # Skip over the address containing node 1's coinbase + self.nodes[1].getnewaddress() + 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 + # -> taddr (change) + 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() + + # 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('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) + self.nodes[2].z_importkey(sk0, "yes") + assert_equal(self.nodes[2].z_getbalance(saplingAddr0), Decimal('10')) + sk1 = self.nodes[1].z_exportkey(saplingAddr1) + self.nodes[2].z_importkey(sk1, "yes") + assert_equal(self.nodes[2].z_getbalance(saplingAddr1), Decimal('5')) + + # 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': 2.5}, {'address': node4_saplingaddr, 'amount': 2.4999}], + 1, 0.0001 + ) + raise AssertionError("Should have thrown an exception") + except JSONRPCException as e: + assert_equal("Cannot send to both Sprout and Sapling addresses using z_sendmany", e.error['message']) + +if __name__ == '__main__': + WalletSaplingTest().main() diff --git a/qa/rpc-tests/wallet_shieldcoinbase.py b/qa/rpc-tests/wallet_shieldcoinbase.py index b77fedcf0..d8366c81d 100755 --- a/qa/rpc-tests/wallet_shieldcoinbase.py +++ b/qa/rpc-tests/wallet_shieldcoinbase.py @@ -12,6 +12,9 @@ from test_framework.util import assert_equal, initialize_chain_clean, \ from decimal import Decimal class WalletShieldCoinbaseTest (BitcoinTestFramework): + def __init__(self, addr_type): + super(WalletShieldCoinbaseTest, self).__init__() + self.addr_type = addr_type def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) @@ -19,10 +22,17 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): def setup_network(self, split=False): args = ['-regtestprotectcoinbase', '-debug=zrpcunsafe'] + args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"] + if self.addr_type != 'sprout': + nu = [ + '-nuparams=5ba81b19:0', # Overwinter + '-nuparams=76b809bb:1', # Sapling + ] + args.extend(nu) + args2 = args self.nodes = [] self.nodes.append(start_node(0, self.options.tmpdir, args)) self.nodes.append(start_node(1, self.options.tmpdir, args)) - args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"] self.nodes.append(start_node(2, self.options.tmpdir, args2)) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) @@ -55,7 +65,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): # Prepare to send taddr->zaddr mytaddr = self.nodes[0].getnewaddress() - myzaddr = self.nodes[0].z_getnewaddress() + myzaddr = self.nodes[0].z_getnewaddress(self.addr_type) # Shielding will fail when trying to spend from watch-only address self.nodes[2].importaddress(mytaddr) @@ -135,26 +145,33 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): self.sync_all() mytaddr = self.nodes[0].getnewaddress() - # Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes. - # We don't verify shieldingValue 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 = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 99999) - assert_equal(result["shieldingUTXOs"], Decimal('662')) - assert_equal(result["remainingUTXOs"], Decimal('138')) - remainingValue = result["remainingValue"] - opid1 = result['opid'] + 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('138')) - assert_equal(result["remainingValue"], Decimal('0')) - assert_equal(result["remainingUTXOs"], Decimal('0')) - opid2 = 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 aysnc operations to complete - wait_and_assert_operationid_status(self.nodes[0], opid1) - wait_and_assert_operationid_status(self.nodes[0], opid2) + # wait for both aysnc operations to complete + wait_and_assert_operationid_status(self.nodes[0], opid1) + wait_and_assert_operationid_status(self.nodes[0], opid2) + + if self.addr_type == 'sprout': + # Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes. + # We don't verify shieldingValue 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. + verify_locking('662', '138', 99999) + else: + # 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 @@ -164,16 +181,17 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): self.nodes[1].generate(1) self.sync_all() - # Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit - # This option is used when the limit parameter is set to 0. - mytaddr = self.nodes[2].getnewaddress() - result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0) - assert_equal(result["shieldingUTXOs"], Decimal('7')) - assert_equal(result["remainingUTXOs"], Decimal('13')) - wait_and_assert_operationid_status(self.nodes[2], result['opid']) - self.sync_all() - self.nodes[1].generate(1) - self.sync_all() + if self.addr_type == 'sprout': + # Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit + # This option is used when the limit parameter is set to 0. + mytaddr = self.nodes[2].getnewaddress() + result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0) + assert_equal(result["shieldingUTXOs"], Decimal('7')) + assert_equal(result["remainingUTXOs"], Decimal('13')) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + 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) @@ -194,6 +212,3 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework): sync_mempools(self.nodes[:2]) self.nodes[1].generate(1) self.sync_all() - -if __name__ == '__main__': - WalletShieldCoinbaseTest().main() diff --git a/qa/rpc-tests/wallet_shieldcoinbase_sapling.py b/qa/rpc-tests/wallet_shieldcoinbase_sapling.py new file mode 100755 index 000000000..d5d130329 --- /dev/null +++ b/qa/rpc-tests/wallet_shieldcoinbase_sapling.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python2 +import inspect +import os + +# To keep pyflakes happy +WalletShieldCoinbaseTest = object + +cwd = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +execfile(os.path.join(cwd, 'wallet_shieldcoinbase.py')) + +class WalletShieldCoinbaseSapling(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseSapling, self).__init__('sapling') + +if __name__ == '__main__': + WalletShieldCoinbaseSapling().main() diff --git a/qa/rpc-tests/wallet_shieldcoinbase_sprout.py b/qa/rpc-tests/wallet_shieldcoinbase_sprout.py new file mode 100755 index 000000000..619ae7caf --- /dev/null +++ b/qa/rpc-tests/wallet_shieldcoinbase_sprout.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python2 +import inspect +import os + +# To keep pyflakes happy +WalletShieldCoinbaseTest = object + +cwd = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +execfile(os.path.join(cwd, 'wallet_shieldcoinbase.py')) + +class WalletShieldCoinbaseSprout(WalletShieldCoinbaseTest): + def __init__(self): + super(WalletShieldCoinbaseSprout, self).__init__('sprout') + +if __name__ == '__main__': + WalletShieldCoinbaseSprout().main() diff --git a/qa/rpc-tests/zkey_import_export.py b/qa/rpc-tests/zkey_import_export.py index 323debe31..dc35937df 100755 --- a/qa/rpc-tests/zkey_import_export.py +++ b/qa/rpc-tests/zkey_import_export.py @@ -9,11 +9,10 @@ from test_framework.util import assert_equal, assert_greater_than, start_nodes,\ initialize_chain_clean, connect_nodes_bi, wait_and_assert_operationid_status import logging -import time -import math logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) +fee = Decimal('0.0001') # constant (but can be changed within reason) class ZkeyImportExportTest (BitcoinTestFramework): @@ -22,7 +21,7 @@ class ZkeyImportExportTest (BitcoinTestFramework): initialize_chain_clean(self.options.tmpdir, 5) def setup_network(self, split=False): - self.nodes = start_nodes(5, self.options.tmpdir ) + 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) @@ -34,19 +33,16 @@ class ZkeyImportExportTest (BitcoinTestFramework): 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): - opid = from_node.z_sendmany(from_addr, [{"address": to_addr, "amount": Decimal(amount)}]) + global fee + opid = from_node.z_sendmany(from_addr, + [{"address": to_addr, "amount": Decimal(amount)}], 1, fee) wait_and_assert_operationid_status(from_node, opid) self.sync_all() miner.generate(1) self.sync_all() - def z_getbalance(node, zaddr): - bal = node.z_getbalance(zaddr) - # Ignore fees for sake of comparison - round_balance = math.ceil(bal*100)/100 - return round_balance - def verify_utxos(node, amts, zaddr): amts.sort(reverse=True) txs = node.z_listreceivedbyaddress(zaddr) @@ -60,6 +56,12 @@ class ZkeyImportExportTest (BitcoinTestFramework): try: assert_equal(amts, [tx["amount"] for tx in txs]) + for tx in txs: + # make sure JoinSplit keys exist and have valid values + assert_equal("jsindex" in tx, True) + assert_equal("jsoutindex" in tx, True) + assert_greater_than(tx["jsindex"], -1) + assert_greater_than(tx["jsoutindex"], -1) except AssertionError: logging.error( 'Expected amounts: %r; txs: %r', @@ -107,27 +109,27 @@ class ZkeyImportExportTest (BitcoinTestFramework): z_send(alice, alice_zaddr, bob_zaddr, amount) logging.info("Exporting privkey from bob...") - privkey = bob.z_exportkey(bob_zaddr) + 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) - print("Bob amounts:", amounts[:4]) verify_utxos(bob, amounts[:4], bob_zaddr) # verify_utxos(charlie, []) - logging.info("Importing privkey into charlie...") + logging.info("Importing bob_privkey into charlie...") # z_importkey rescan defaults to "whenkeyisnew", so should rescan here - charlie.z_importkey(privkey) + charlie.z_importkey(bob_privkey) ipk_zaddr = find_imported_key(charlie, bob_zaddr) # z_importkey should have rescanned for new key, so this should pass: verify_utxos(charlie, amounts[:4], ipk_zaddr) # Verify idempotent behavior: - charlie.z_importkey(privkey) + charlie.z_importkey(bob_privkey) ipk_zaddr2 = find_imported_key(charlie, bob_zaddr) + assert_equal(ipk_zaddr, ipk_zaddr2) # amounts should be unchanged verify_utxos(charlie, amounts[:4], ipk_zaddr2) @@ -140,22 +142,26 @@ class ZkeyImportExportTest (BitcoinTestFramework): verify_utxos(charlie, amounts, ipk_zaddr) verify_utxos(charlie, amounts, ipk_zaddr2) + # 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 - balance = float(sum(amounts) - sum(amounts[:2])) - assert_equal(z_getbalance(bob, bob_zaddr), balance) + bob_balance = sum(amounts[2:]) - bob_fee + assert_equal(bob.z_getbalance(bob_zaddr), bob_balance) # z_import onto new node "david" (blockchain rescan, default or True?) - david.z_importkey(privkey) + david.z_importkey(bob_privkey) d_ipk_zaddr = find_imported_key(david, bob_zaddr) # Check if amt bob spent is deducted for charlie and david - assert_equal(z_getbalance(charlie, ipk_zaddr), balance) - assert_equal(z_getbalance(david, d_ipk_zaddr), balance) + assert_equal(charlie.z_getbalance(ipk_zaddr), bob_balance) + assert_equal(david.z_getbalance(d_ipk_zaddr), bob_balance) if __name__ == '__main__': ZkeyImportExportTest().main() diff --git a/qa/zcash/create_benchmark_archive.py b/qa/zcash/create_benchmark_archive.py index 67ad5b101..84bd236de 100644 --- a/qa/zcash/create_benchmark_archive.py +++ b/qa/zcash/create_benchmark_archive.py @@ -5,7 +5,6 @@ import plyvel import progressbar import os import stat -import struct import subprocess import sys import tarfile diff --git a/qa/zcash/full_test_suite.py b/qa/zcash/full_test_suite.py index d8a076420..0e8605cc3 100755 --- a/qa/zcash/full_test_suite.py +++ b/qa/zcash/full_test_suite.py @@ -4,6 +4,7 @@ # import argparse +from glob import glob import os import re import subprocess @@ -62,12 +63,18 @@ def check_security_hardening(): # PIE, RELRO, Canary, and NX are tested by make check-security. ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 + # 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 + ret &= test_rpath_runpath('src/zcashd') ret &= test_rpath_runpath('src/zcash-cli') ret &= test_rpath_runpath('src/zcash-gtest') ret &= test_rpath_runpath('src/zcash-tx') ret &= test_rpath_runpath('src/test/test_bitcoin') - ret &= test_rpath_runpath('src/zcash/GenerateParams') # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE # is enabled for the entire binary. See issue #915. @@ -76,16 +83,18 @@ def check_security_hardening(): ret &= test_fortify_source('src/zcash-gtest') ret &= test_fortify_source('src/zcash-tx') ret &= test_fortify_source('src/test/test_bitcoin') - ret &= test_fortify_source('src/zcash/GenerateParams') return ret def ensure_no_dot_so_in_depends(): - arch_dir = os.path.join( - REPOROOT, - 'depends', - 'x86_64-unknown-linux-gnu', - ) + depends_dir = os.path.join(REPOROOT, 'depends') + arch_dir = os.path.join(depends_dir, 'x86_64-unknown-linux-gnu') + if not os.path.isdir(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 on in CI + arch_dir = arch_dirs[0] exit_code = 0 @@ -99,7 +108,7 @@ def ensure_no_dot_so_in_depends(): exit_code = 1 else: exit_code = 2 - print "arch-specific build dir not present: {}".format(arch_dir) + print "arch-specific build dir not present" print "Did you build the ./depends tree?" print "Are you on a currently unsupported architecture?" diff --git a/src/Makefile.am b/src/Makefile.am index e1115d860..508ccecf9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,6 +3,7 @@ DIST_SUBDIRS = secp256k1 univalue cryptoconditions AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) AM_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) AM_CPPFLAGS = $(HARDENED_CPPFLAGS) +EXTRA_LIBRARIES = if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include @@ -20,10 +21,12 @@ $(LIBLEVELDB) $(LIBMEMENV): endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config -BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) +BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include +BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src +BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/src/asn BITCOIN_INCLUDES += -I$(srcdir)/snark BITCOIN_INCLUDES += -I$(srcdir)/snark/libsnark BITCOIN_INCLUDES += -I$(srcdir)/univalue/include @@ -34,7 +37,7 @@ endif if TARGET_DARWIN LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl else -LIBBITCOIN_SERVER=libbitcoin_server.a +LIBBITCOIN_SERVER=libbitcoin_server.a -lcurl endif LIBBITCOIN_WALLET=libbitcoin_wallet.a @@ -48,57 +51,68 @@ LIBSECP256K1=secp256k1/libsecp256k1.la LIBCRYPTOCONDITIONS=cryptoconditions/libcryptoconditions_core.la LIBSNARK=snark/libsnark.a LIBUNIVALUE=univalue/libunivalue.la -LIBZCASH=libzcash.a -lcurl +LIBZCASH=libzcash.a + +if ENABLE_ZMQ +LIBBITCOIN_ZMQ=libbitcoin_zmq.a +endif +if ENABLE_PROTON +LIBBITCOIN_PROTON=libbitcoin_proton.a +endif +if BUILD_BITCOIN_LIBS +LIBZCASH_CONSENSUS=libzcashconsensus.la +endif +if ENABLE_WALLET +LIBBITCOIN_WALLET=libbitcoin_wallet.a +endif $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " -LIBSNARK_CXXFLAGS = -fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all +LIBSNARK_CXXFLAGS = $(AM_CXXFLAGS) $(PIC_FLAGS) -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all LIBSNARK_CONFIG_FLAGS = CURVE=ALT_BN128 NO_PROCPS=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT NO_COPY_DEPINST=1 NO_COMPILE_LIBGTEST=1 if HAVE_OPENMP LIBSNARK_CONFIG_FLAGS += MULTICORE=1 endif +if TARGET_DARWIN +LIBSNARK_CONFIG_FLAGS += PLATFORM=darwin +endif $(LIBSNARK): $(wildcard snark/src/*) - $(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" libsnark-tests: $(wildcard snark/src/*) - $(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" $(LIBUNIVALUE): $(wildcard univalue/lib/*) - $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/ OPTFLAGS="-O2 -march=x86-64 -g " + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " $(LIBCRYPTOCONDITIONS): $(wildcard cryptoconditions/src/*) $(wildcard cryptoconditions/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) OPTFLAGS="-O2 -march=x86-64 -g " # Make is not made aware of per-object dependencies to avoid limiting building parallelization # But to build the less dependent modules first, we manually select their order here: -EXTRA_LIBRARIES = \ - crypto/libbitcoin_crypto.a \ - crypto/libverus_crypto.a \ - crypto/libverus_portable_crypto.a \ - libbitcoin_util.a \ - libbitcoin_common.a \ - libbitcoin_server.a \ - libbitcoin_cli.a \ +EXTRA_LIBRARIES += \ + $(LIBBITCOIN_CRYPTO) \ + $(LIBVERUS_CRYPTO) \ + $(LIBVERUS_PORTABLE_CRYPTO) \ + $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_COMMON) \ + $(LIBBITCOIN_SERVER) \ + $(LIBBITCOIN_CLI) \ libzcash.a if ENABLE_WALLET BITCOIN_INCLUDES += $(BDB_CPPFLAGS) -EXTRA_LIBRARIES += libbitcoin_wallet.a +EXTRA_LIBRARIES += $(LIBBITCOIN_WALLET) endif if ENABLE_ZMQ -EXTRA_LIBRARIES += libbitcoin_zmq.a +EXTRA_LIBRARIES += $(LIBBITCOIN_ZMQ) endif if ENABLE_PROTON -EXTRA_LIBRARIES += libbitcoin_proton.a +EXTRA_LIBRARIES += $(LIBBITCOIN_PROTON) endif -if BUILD_BITCOIN_LIBS -lib_LTLIBRARIES = libzcashconsensus.la -LIBZCASH_CONSENSUS=libzcashconsensus.la -else -LIBZCASH_CONSENSUS= -endif +lib_LTLIBRARIES = $(LIBZCASH_CONSENSUS) bin_PROGRAMS = noinst_PROGRAMS = @@ -125,7 +139,8 @@ LIBZCASH_H = \ zcash/prf.h \ zcash/Proof.hpp \ zcash/util.h \ - zcash/Zcash.h + zcash/Zcash.h \ + zcash/zip32.h .PHONY: FORCE collate-libsnark check-symbols check-security # bitcoin core # @@ -144,6 +159,7 @@ BITCOIN_CORE_H = \ asyncrpcoperation.h \ asyncrpcqueue.h \ base58.h \ + bech32.h \ bloom.h \ cc/eval.h \ chain.h \ @@ -175,8 +191,9 @@ BITCOIN_CORE_H = \ httpserver.h \ init.h \ key.h \ + key_io.h \ keystore.h \ - leveldbwrapper.h \ + dbwrapper.h \ limitedmap.h \ main.h \ memusage.h \ @@ -191,6 +208,7 @@ BITCOIN_CORE_H = \ paymentdisclosuredb.h \ policy/fees.h \ pow.h \ + prevector.h \ primitives/block.h \ primitives/transaction.h \ primitives/nonce.h \ @@ -198,9 +216,10 @@ BITCOIN_CORE_H = \ pubkey.h \ random.h \ reverselock.h \ - rpcclient.h \ - rpcprotocol.h \ - rpcserver.h \ + rpc/client.h \ + rpc/protocol.h \ + rpc/server.h \ + rpc/register.h \ scheduler.h \ script/interpreter.h \ script/script.h \ @@ -220,6 +239,7 @@ BITCOIN_CORE_H = \ timedata.h \ tinyformat.h \ torcontrol.h \ + transaction_builder.h \ txdb.h \ txmempool.h \ ui_interface.h \ @@ -237,6 +257,7 @@ BITCOIN_CORE_H = \ wallet/asyncrpcoperation_shieldcoinbase.h \ wallet/crypter.h \ wallet/db.h \ + wallet/rpcwallet.h \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ @@ -270,15 +291,27 @@ libbitcoin_server_a_SOURCES = \ cc/CCcustom.cpp \ cc/CCtx.cpp \ cc/CCutils.cpp \ + cc/StakeGuard.cpp \ + cc/StakeGuard.h \ cc/assets.cpp \ cc/faucet.cpp \ cc/rewards.cpp \ cc/dice.cpp \ cc/lotto.cpp \ - cc/ponzi.cpp \ + cc/fsm.cpp \ + cc/MofN.cpp \ + cc/oracles.cpp \ + cc/prices.cpp \ + cc/pegs.cpp \ + cc/triggers.cpp \ + cc/payments.cpp \ + cc/gateways.cpp \ + cc/channels.cpp \ cc/auction.cpp \ cc/betprotocol.cpp \ chain.cpp \ + cheatcatcher.h \ + cheatcatcher.cpp \ checkpoints.cpp \ crosschain.cpp \ crypto/haraka.h \ @@ -289,10 +322,10 @@ libbitcoin_server_a_SOURCES = \ httprpc.cpp \ httpserver.cpp \ init.cpp \ - leveldbwrapper.cpp \ + dbwrapper.cpp \ main.cpp \ merkleblock.cpp \ - metrics.cpp \ + metrics.h \ miner.cpp \ net.cpp \ noui.cpp \ @@ -302,14 +335,15 @@ libbitcoin_server_a_SOURCES = \ policy/fees.cpp \ pow.cpp \ rest.cpp \ - rpcblockchain.cpp \ - rpccrosschain.cpp \ - rpcmining.cpp \ - rpcmisc.cpp \ - rpcnet.cpp \ - rpcrawtransaction.cpp \ - rpcserver.cpp \ + rpc/blockchain.cpp \ + rpc/crosschain.cpp \ + rpc/mining.cpp \ + rpc/misc.cpp \ + rpc/net.cpp \ + rpc/rawtransaction.cpp \ + rpc/server.cpp \ script/serverchecker.cpp \ + script/sigcache.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ @@ -319,8 +353,6 @@ libbitcoin_server_a_SOURCES = \ $(LIBZCASH_H) if ENABLE_ZMQ -LIBBITCOIN_ZMQ=libbitcoin_zmq.a - libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ @@ -330,8 +362,6 @@ libbitcoin_zmq_a_SOURCES = \ endif if ENABLE_PROTON -LIBBITCOIN_PROTON=libbitcoin_proton.a - libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_proton_a_SOURCES = \ @@ -355,6 +385,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/db.cpp \ paymentdisclosure.cpp \ paymentdisclosuredb.cpp \ + transaction_builder.cpp \ wallet/rpcdisclosure.cpp \ wallet/rpcdump.cpp \ cc/CCassetstx.cpp \ @@ -363,6 +394,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/wallet.cpp \ wallet/wallet_ismine.cpp \ wallet/walletdb.cpp \ + zcash/zip32.cpp \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) @@ -424,6 +456,7 @@ libbitcoin_common_a_SOURCES = \ amount.cpp \ arith_uint256.cpp \ base58.cpp \ + bech32.cpp \ chainparams.cpp \ coins.cpp \ compressor.cpp \ @@ -437,8 +470,10 @@ libbitcoin_common_a_SOURCES = \ hash.cpp \ importcoin.cpp \ key.cpp \ + key_io.cpp \ keystore.cpp \ netbase.cpp \ + metrics.cpp \ primitives/block.cpp \ primitives/transaction.cpp \ primitives/nonce.cpp \ @@ -453,6 +488,7 @@ libbitcoin_common_a_SOURCES = \ script/sign.cpp \ script/standard.cpp \ veruslaunch.cpp \ + transaction_builder.cpp \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) @@ -462,23 +498,23 @@ libbitcoin_common_a_SOURCES = \ libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ - support/pagelocker.cpp \ - chainparamsbase.cpp \ - clientversion.cpp \ - compat/glibc_sanity.cpp \ - compat/glibcxx_sanity.cpp \ - compat/strnlen.cpp \ - random.cpp \ - rpcprotocol.cpp \ - support/cleanse.cpp \ - sync.cpp \ - uint256.cpp \ - util.cpp \ - utilmoneystr.cpp \ - utilstrencodings.cpp \ - utiltime.cpp \ - $(BITCOIN_CORE_H) \ - $(LIBZCASH_H) + support/pagelocker.cpp \ + chainparamsbase.cpp \ + clientversion.cpp \ + compat/glibc_sanity.cpp \ + compat/glibcxx_sanity.cpp \ + compat/strnlen.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 @@ -488,9 +524,9 @@ endif libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ - rpcclient.cpp \ - $(BITCOIN_CORE_H) \ - $(LIBZCASH_H) + rpc/client.cpp \ + $(BITCOIN_CORE_H) \ + $(LIBZCASH_H) nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # @@ -510,6 +546,8 @@ komodod_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBUNIVALUE) \ $(LIBBITCOIN_UTIL) \ + $(LIBBITCOIN_ZMQ) \ + $(LIBBITCOIN_PROTON) \ $(LIBBITCOIN_CRYPTO) \ $(LIBVERUS_CRYPTO) \ $(LIBVERUS_PORTABLE_CRYPTO) \ @@ -520,12 +558,8 @@ komodod_LDADD = \ $(LIBSECP256K1) \ $(LIBCRYPTOCONDITIONS) -if ENABLE_ZMQ -komodod_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) -endif - if ENABLE_WALLET -komodod_LDADD += libbitcoin_wallet.a +komodod_LDADD += $(LIBBITCOIN_WALLET) endif komodod_LDADD += \ @@ -535,6 +569,8 @@ komodod_LDADD += \ $(CRYPTO_LIBS) \ $(EVENT_PTHREADS_LIBS) \ $(EVENT_LIBS) \ + $(ZMQ_LIBS) \ + $(PROTON_LIBS) \ $(LIBBITCOIN_CRYPTO) \ $(LIBVERUS_CRYPTO) \ $(LIBVERUS_PORTABLE_CRYPTO) \ @@ -631,6 +667,7 @@ libzcash_a_SOURCES = \ zcash/Note.cpp \ zcash/prf.cpp \ zcash/util.cpp \ + zcash/zip32.cpp \ zcash/circuit/commitment.tcc \ zcash/circuit/gadget.tcc \ zcash/circuit/merkle.tcc \ @@ -640,6 +677,10 @@ libzcash_a_SOURCES = \ libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) +#libzcash_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +#libzcash_a_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +#libzcash_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DMONTGOMERY_OUTPUT + libzcash_a_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) -fwrapv -fno-strict-aliasing libzcash_a_LDFLAGS = $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) libzcash_a_CPPFLAGS += -DMONTGOMERY_OUTPUT @@ -686,6 +727,7 @@ clean-local: -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean -$(MAKE) -C snark clean + -$(MAKE) -C univalue clean rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno -rm -f config.h @@ -718,5 +760,3 @@ include Makefile.ktest.include #include Makefile.test.include #include Makefile.gtest.include endif - -include Makefile.zcash.include diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index b424fd41f..ec3a4a12e 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -23,6 +23,7 @@ zcash_gtest_SOURCES += \ gtest/test_equihash.cpp \ gtest/test_httprpc.cpp \ gtest/test_joinsplit.cpp \ + gtest/test_keys.cpp \ gtest/test_keystore.cpp \ gtest/test_noteencryption.cpp \ gtest/test_mempool.cpp \ @@ -32,7 +33,9 @@ zcash_gtest_SOURCES += \ gtest/test_pow.cpp \ gtest/test_random.cpp \ gtest/test_rpc.cpp \ + gtest/test_sapling_note.cpp \ gtest/test_transaction.cpp \ + gtest/test_transaction_builder.cpp \ gtest/test_upgrades.cpp \ gtest/test_validation.cpp \ gtest/test_circuit.cpp \ @@ -40,7 +43,9 @@ zcash_gtest_SOURCES += \ gtest/test_libzcash_utils.cpp \ gtest/test_proofs.cpp \ gtest/test_paymentdisclosure.cpp \ - gtest/test_checkblock.cpp + gtest/test_pedersen_hash.cpp \ + gtest/test_checkblock.cpp \ + gtest/test_zip32.cpp if ENABLE_WALLET zcash_gtest_SOURCES += \ wallet/gtest/test_wallet.cpp diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 2769e120c..1f9f9ac1e 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -20,78 +20,89 @@ EXTRA_DIST += \ test/data/wallet.dat JSON_TEST_FILES = \ - test/data/script_valid.json \ - test/data/base58_keys_valid.json \ - test/data/base58_encode_decode.json \ - test/data/base58_keys_invalid.json \ - test/data/script_invalid.json \ - test/data/tx_invalid.json \ - test/data/tx_valid.json \ - test/data/sighash.json \ - test/data/merkle_roots.json \ - test/data/merkle_roots_empty.json \ - test/data/merkle_serialization.json \ - test/data/merkle_witness_serialization.json \ - test/data/merkle_path.json \ - test/data/merkle_commitments.json \ - test/data/g1_compressed.json \ - test/data/g2_compressed.json + test/data/script_valid.json \ + test/data/base58_keys_valid.json \ + test/data/base58_encode_decode.json \ + test/data/base58_keys_invalid.json \ + test/data/script_invalid.json \ + test/data/tx_invalid.json \ + test/data/tx_valid.json \ + test/data/sighash.json \ + test/data/merkle_roots.json \ + test/data/merkle_roots_empty.json \ + test/data/merkle_serialization.json \ + test/data/merkle_witness_serialization.json \ + test/data/merkle_path.json \ + test/data/merkle_commitments.json \ + test/data/merkle_roots_sapling.json \ + test/data/merkle_roots_empty_sapling.json \ + test/data/merkle_serialization_sapling.json \ + test/data/merkle_witness_serialization_sapling.json \ + test/data/merkle_path_sapling.json \ + test/data/merkle_commitments_sapling.json \ + test/data/g1_compressed.json \ + test/data/g2_compressed.json \ + test/data/sapling_key_components.json RAW_TEST_FILES = test/data/alertTests.raw GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) BITCOIN_TESTS =\ - test/arith_uint256_tests.cpp \ - test/bignum.h \ - test/addrman_tests.cpp \ - test/allocator_tests.cpp \ - test/base32_tests.cpp \ - test/base58_tests.cpp \ - test/base64_tests.cpp \ - test/bip32_tests.cpp \ - test/bloom_tests.cpp \ - test/checkblock_tests.cpp \ - test/Checkpoints_tests.cpp \ - test/coins_tests.cpp \ - test/compress_tests.cpp \ - test/crypto_tests.cpp \ - test/DoS_tests.cpp \ - test/equihash_tests.cpp \ - test/getarg_tests.cpp \ - test/hash_tests.cpp \ - test/key_tests.cpp \ - test/main_tests.cpp \ - test/mempool_tests.cpp \ - test/miner_tests.cpp \ - test/mruset_tests.cpp \ - test/multisig_tests.cpp \ - test/netbase_tests.cpp \ - test/pmt_tests.cpp \ - test/policyestimator_tests.cpp \ - test/pow_tests.cpp \ - test/raii_event_tests.cpp \ - test/reverselock_tests.cpp \ - test/rpc_tests.cpp \ - test/sanity_tests.cpp \ - test/scheduler_tests.cpp \ - test/script_P2SH_tests.cpp \ - test/script_P2PKH_tests.cpp \ - test/script_tests.cpp \ - test/scriptnum_tests.cpp \ - test/serialize_tests.cpp \ - test/sighash_tests.cpp \ - test/sigopcount_tests.cpp \ - test/skiplist_tests.cpp \ - test/test_bitcoin.cpp \ - test/test_bitcoin.h \ - test/timedata_tests.cpp \ - test/torcontrol_tests.cpp \ - test/transaction_tests.cpp \ - test/uint256_tests.cpp \ - test/univalue_tests.cpp \ - test/util_tests.cpp \ - test/sha256compress_tests.cpp + test/arith_uint256_tests.cpp \ + test/bignum.h \ + test/addrman_tests.cpp \ + test/alert_tests.cpp \ + test/allocator_tests.cpp \ + test/base32_tests.cpp \ + test/base58_tests.cpp \ + test/base64_tests.cpp \ + test/bech32_tests.cpp \ + test/bip32_tests.cpp \ + test/bloom_tests.cpp \ + test/checkblock_tests.cpp \ + test/Checkpoints_tests.cpp \ + test/coins_tests.cpp \ + test/compress_tests.cpp \ + test/convertbits_tests.cpp \ + test/crypto_tests.cpp \ + test/DoS_tests.cpp \ + test/equihash_tests.cpp \ + test/getarg_tests.cpp \ + test/hash_tests.cpp \ + test/key_tests.cpp \ + test/dbwrapper_tests.cpp \ + test/main_tests.cpp \ + test/mempool_tests.cpp \ + test/miner_tests.cpp \ + test/mruset_tests.cpp \ + test/multisig_tests.cpp \ + test/netbase_tests.cpp \ + test/pmt_tests.cpp \ + test/policyestimator_tests.cpp \ + test/pow_tests.cpp \ + test/prevector_tests.cpp \ + test/raii_event_tests.cpp \ + test/reverselock_tests.cpp \ + test/rpc_tests.cpp \ + test/sanity_tests.cpp \ + test/scheduler_tests.cpp \ + test/script_P2SH_tests.cpp \ + test/script_tests.cpp \ + test/scriptnum_tests.cpp \ + test/serialize_tests.cpp \ + test/sighash_tests.cpp \ + test/sigopcount_tests.cpp \ + test/skiplist_tests.cpp \ + test/test_bitcoin.cpp \ + test/test_bitcoin.h \ + test/timedata_tests.cpp \ + test/torcontrol_tests.cpp \ + test/transaction_tests.cpp \ + test/uint256_tests.cpp \ + test/univalue_tests.cpp \ + test/util_tests.cpp \ + test/sha256compress_tests.cpp if ENABLE_WALLET BITCOIN_TESTS += \ @@ -108,6 +119,9 @@ test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif +test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ + $(LIBLEVELDB) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) +test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static diff --git a/src/ac/ccl b/src/ac/ccl new file mode 100755 index 000000000..c3d03a0a4 --- /dev/null +++ b/src/ac/ccl @@ -0,0 +1,2 @@ +#!/bin/bash +./komodo-cli -ac_name=CCL $1 $2 $3 $4 $5 $6 diff --git a/src/addrman.h b/src/addrman.h index 0483e8bdb..5c77a4fdb 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -54,7 +54,7 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(*(CAddress*)this); READWRITE(source); READWRITE(nLastSuccess); @@ -279,7 +279,7 @@ public: * very little in common. */ template - void Serialize(Stream &s, int nType, int nVersionDummy) const + void Serialize(Stream &s) const { LOCK(cs); @@ -329,7 +329,7 @@ public: } template - void Unserialize(Stream& s, int nType, int nVersionDummy) + void Unserialize(Stream& s) { LOCK(cs); @@ -434,11 +434,6 @@ public: Check(); } - unsigned int GetSerializeSize(int nType, int nVersion) const - { - return (CSizeComputer(nType, nVersion) << *this).size(); - } - void Clear() { std::vector().swap(vRandom); diff --git a/src/alert.h b/src/alert.h index 76d8d916e..4e3b88775 100644 --- a/src/alert.h +++ b/src/alert.h @@ -49,9 +49,8 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(this->nVersion); - nVersion = this->nVersion; READWRITE(nRelayUntil); READWRITE(nExpiration); READWRITE(nID); @@ -87,7 +86,7 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(vchMsg); READWRITE(vchSig); } diff --git a/src/amount.h b/src/amount.h index 9b62f7663..7423fdaa1 100644 --- a/src/amount.h +++ b/src/amount.h @@ -58,7 +58,7 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(nSatoshisPerK); } }; diff --git a/src/assetchains.json b/src/assetchains.json index 9c521aab6..ceda4cce1 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -45,7 +45,8 @@ }, { "ac_name": "COQUI", - "ac_supply": "72000000" + "ac_supply": "72000000", + "ac_ccactivate": "200000" }, { "ac_name": "WLC", @@ -130,6 +131,19 @@ }, { "ac_name": "SEC", - "ac_supply": "1000000000" + "ac_supply": "1000000000", + "ac_cc": "333" + }, + { + "ac_name": "CCL", + "ac_supply": "200000000", + "ac_end": "1", + "ac_cc": "2", + "addressindex": "1", + "spentindex": "1", + "addnode": [ + "142.93.136.89", + "195.201.22.89" + ] } ] diff --git a/src/assetchains.old b/src/assetchains.old index cbf976dd9..158e62cad 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -15,7 +15,7 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=MSHARK -ac_supply=1400000 -addnode=78.47.196.146 $1 & ./komodod -pubkey=$pubkey -ac_name=BOTS -ac_supply=999999 -addnode=78.47.196.146 $1 & ./komodod -pubkey=$pubkey -ac_name=MGW -ac_supply=999999 -addnode=78.47.196.146 $1 & -./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -addnode=78.47.196.146 $1 & +./komodod -pubkey=$pubkey -ac_name=COQUI -ac_supply=72000000 -ac_ccactivate=200000 -addnode=78.47.196.146 $1 & ./komodod -pubkey=$pubkey -ac_name=WLC -ac_supply=210000000 -addnode=148.251.190.89 $1 & ./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 & ./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 & @@ -38,3 +38,4 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=RFOX -ac_supply=1000000000 -ac_reward=100000000 -addnode=78.47.196.146 & ~/VerusCoin/src/komodod -pubkey=$pubkey -ac_name=VRSC -ac_algo=verushash -ac_cc=1 -ac_veruspos=50 -ac_supply=0 -ac_eras=3 -ac_reward=0,38400000000,2400000000 -ac_halving=1,43200,1051920 -ac_decay=100000000,0,0 -ac_end=10080,226080,0 -ac_timelockgte=19200000000 -ac_timeunlockfrom=129600 -ac_timeunlockto=1180800 -addnode=185.25.48.236 -addnode=185.64.105.111 & ./komodod -pubkey=$pubkey -ac_name=SEC -ac_cc=333 -ac_supply=1000000000 -addnode=185.148.145.43 & +./komodod -pubkey=$pubkey -ac_name=CCL -ac_supply=200000000 -ac_end=1 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=142.93.136.89 -addnode=195.201.22.89 & diff --git a/src/asyncrpcoperation.cpp b/src/asyncrpcoperation.cpp index f32e8d716..ff5c4cb9f 100644 --- a/src/asyncrpcoperation.cpp +++ b/src/asyncrpcoperation.cpp @@ -16,7 +16,7 @@ using namespace std; static boost::uuids::random_generator uuidgen; -std::map OperationStatusMap = { +static std::map OperationStatusMap = { {OperationStatus::READY, "queued"}, {OperationStatus::EXECUTING, "executing"}, {OperationStatus::CANCELLED, "cancelled"}, diff --git a/src/base58.cpp b/src/base58.cpp index b85803569..12978fa1c 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -4,15 +4,12 @@ #include "base58.h" -#include "hash.h" -#include "uint256.h" - -#include "version.h" -#include "streams.h" +#include +#include #include -#include #include +#include #include #include #include @@ -104,7 +101,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) std::string EncodeBase58(const std::vector& vch) { - return EncodeBase58(&vch[0], &vch[0] + vch.size()); + return EncodeBase58(vch.data(), vch.data() + vch.size()); } bool DecodeBase58(const std::string& str, std::vector& vchRet) @@ -143,6 +140,7 @@ bool DecodeBase58Check(const std::string& str, std::vector& vchRe return DecodeBase58Check(str.c_str(), vchRet); } + CBase58Data::CBase58Data() { vchVersion.clear(); @@ -215,6 +213,7 @@ public: CBitcoinAddressVisitor(CBitcoinAddress* addrIn) : addr(addrIn) {} bool operator()(const CKeyID& id) const { return addr->Set(id); } + bool operator()(const CPubKey& key) const { return addr->Set(key); } bool operator()(const CScriptID& id) const { return addr->Set(id); } bool operator()(const CNoDestination& no) const { return false; } }; @@ -227,6 +226,13 @@ bool CBitcoinAddress::Set(const CKeyID& id) return true; } +bool CBitcoinAddress::Set(const CPubKey& key) +{ + CKeyID id = key.GetID(); + SetData(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS), &id, 20); + return true; +} + bool CBitcoinAddress::Set(const CScriptID& id) { SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20); @@ -381,27 +387,3 @@ DATA_TYPE CZCEncoding::Get() const ss >> ret; return ret; } - -// Explicit instantiations for libzcash::PaymentAddress -template bool CZCEncoding::Set(const libzcash::PaymentAddress& addr); -template libzcash::PaymentAddress CZCEncoding::Get() const; - -// Explicit instantiations for libzcash::ViewingKey -template bool CZCEncoding::Set(const libzcash::ViewingKey& vk); -template libzcash::ViewingKey CZCEncoding::Get() const; - -// Explicit instantiations for libzcash::SpendingKey -template bool CZCEncoding::Set(const libzcash::SpendingKey& sk); -template libzcash::SpendingKey CZCEncoding::Get() const; diff --git a/src/base58.h b/src/base58.h index 4e8b2c3ce..66cb7e7a0 100644 --- a/src/base58.h +++ b/src/base58.h @@ -58,13 +58,13 @@ 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 */ -inline bool DecodeBase58Check(const char* psz, std::vector& vchRet); +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 */ -inline bool DecodeBase58Check(const std::string& str, std::vector& vchRet); +bool DecodeBase58Check(const std::string& str, std::vector& vchRet); /** * Base class for all base58-encoded data @@ -107,39 +107,6 @@ public: DATA_TYPE Get() const; }; -class CZCPaymentAddress : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "payment address" + s; } - -public: - CZCPaymentAddress() {} - - CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } - CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); } -}; - -class CZCViewingKey : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "viewing key" + s; } - -public: - CZCViewingKey() {} - - CZCViewingKey(const std::string& strViewingKey) { SetString(strViewingKey.c_str(), 3); } - CZCViewingKey(const libzcash::ViewingKey& vk) { Set(vk); } -}; - -class CZCSpendingKey : public CZCEncoding { -protected: - std::string PrependName(const std::string& s) const { return "spending key" + s; } - -public: - CZCSpendingKey() {} - - CZCSpendingKey(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } - CZCSpendingKey(const libzcash::SpendingKey& addr) { Set(addr); } -}; - /** base58-encoded Bitcoin addresses. * Public-key-hash-addresses have version 0 (or 111 testnet). * The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. @@ -149,6 +116,7 @@ public: class CBitcoinAddress : public CBase58Data { public: bool Set(const CKeyID &id); + bool Set(const CPubKey &key); bool Set(const CScriptID &id); bool Set(const CTxDestination &dest); bool IsValid() const; diff --git a/src/bech32.cpp b/src/bech32.cpp new file mode 100644 index 000000000..78c35b976 --- /dev/null +++ b/src/bech32.cpp @@ -0,0 +1,194 @@ +// Copyright (c) 2017 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://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/src/bech32.h b/src/bech32.h new file mode 100644 index 000000000..2e2823e97 --- /dev/null +++ b/src/bech32.h @@ -0,0 +1,30 @@ +// Copyright (c) 2017 Pieter Wuille +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://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/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index bf189e483..5d818eb5b 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -5,8 +5,8 @@ #include "chainparamsbase.h" #include "clientversion.h" -#include "rpcclient.h" -#include "rpcprotocol.h" +#include "rpc/client.h" +#include "rpc/protocol.h" #include "util.h" #include "utilstrencodings.h" @@ -21,14 +21,12 @@ using namespace std; -int64_t MAX_MONEY = 200000000 * 100000000LL; -uint64_t komodo_maxallowed(int32_t baseid) { return(100000000LL * 1000000); } // stub - static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; +static const int CONTINUE_EXECUTION=-1; std::string HelpMessageCli() { - string strUsage; + std::string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "komodo.conf")); @@ -42,6 +40,7 @@ std::string HelpMessageCli() 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)); + strUsage += HelpMessageOpt("-stdin", _("Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases)")); return strUsage; } @@ -86,8 +85,16 @@ uint32_t komodo_heightstamp(int32_t height) return(0); } -static bool AppInitRPC(int argc, char* argv[]) +// +// 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 // @@ -107,29 +114,33 @@ static bool AppInitRPC(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); - return false; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); - return false; + return EXIT_FAILURE; } // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) if (!SelectBaseParamsFromCommandLine()) { fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n"); - return false; + return EXIT_FAILURE; } if (GetBoolArg("-rpcssl", false)) { fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return false; + return EXIT_FAILURE; } - return true; + return CONTINUE_EXECUTION; } @@ -198,7 +209,7 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx) } #endif -UniValue CallRPC(const string& strMethod, const UniValue& params) +UniValue CallRPC(const std::string& strMethod, const UniValue& params) { std::string host = GetArg("-rpcconnect", "127.0.0.1"); int port = GetArg("-rpcport", BaseParams().RPCPort()); @@ -213,7 +224,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) HTTPReply response; raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response); if (req == NULL) - throw runtime_error("create http request failed"); + throw std::runtime_error("create http request failed"); #if LIBEVENT_VERSION_NUMBER >= 0x02010300 evhttp_request_set_error_cb(req.get(), http_error_cb); #endif @@ -223,7 +234,7 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) if (mapArgs["-rpcpassword"] == "") { // Try fall back to cookie-based authentication if no password is provided if (!GetAuthCookie(&strRPCUserColonPass)) { - throw runtime_error(strprintf( + 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().string().c_str())); @@ -256,26 +267,26 @@ UniValue CallRPC(const string& strMethod, const UniValue& params) 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 runtime_error("incorrect rpcuser or rpcpassword (authorization failed)"); + 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 runtime_error(strprintf("server returned HTTP error %d", response.status)); + throw std::runtime_error(strprintf("server returned HTTP error %d", response.status)); else if (response.body.empty()) - throw runtime_error("no response from server"); + throw std::runtime_error("no response from server"); // Parse reply UniValue valReply(UniValue::VSTR); if (!valReply.read(response.body)) - throw runtime_error("couldn't parse reply from server"); + throw std::runtime_error("couldn't parse reply from server"); const UniValue& reply = valReply.get_obj(); if (reply.empty()) - throw runtime_error("expected reply to have result, error and id properties"); + throw std::runtime_error("expected reply to have result, error and id properties"); return reply; } int CommandLineRPC(int argc, char *argv[]) { - string strPrint; + std::string strPrint; int nRet = 0; try { // Skip switches @@ -283,15 +294,17 @@ int CommandLineRPC(int argc, char *argv[]) argc--; argv++; } - - // Method - if (argc < 2) - throw runtime_error("too few parameters"); - string strMethod = argv[1]; - - // Parameters default to strings - std::vector strParams(&argv[2], &argv[argc]); - UniValue params = RPCConvertValues(strMethod, strParams); + std::vector args = std::vector(&argv[1], &argv[argc]); + if (GetBoolArg("-stdin", false)) { + // Read one arg per line from stdin and append + std::string line; + while (std::getline(std::cin,line)) + args.push_back(line); + } + 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); @@ -343,7 +356,7 @@ int CommandLineRPC(int argc, char *argv[]) throw; } catch (const std::exception& e) { - strPrint = string("error: ") + e.what(); + strPrint = std::string("error: ") + e.what(); nRet = EXIT_FAILURE; } catch (...) { @@ -362,12 +375,13 @@ int main(int argc, char* argv[]) SetupEnvironment(); if (!SetupNetworking()) { fprintf(stderr, "Error: Initializing networking failed\n"); - exit(1); + return EXIT_FAILURE; } try { - if(!AppInitRPC(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRPC(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 36fea57bf..793697631 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -4,7 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "clientversion.h" -#include "rpcserver.h" +#include "rpc/server.h" #include "init.h" #include "main.h" #include "noui.h" @@ -12,7 +12,6 @@ #include "util.h" #include "httpserver.h" #include "httprpc.h" -#include "rpcserver.h" #include #include @@ -115,7 +114,7 @@ bool AppInit(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + return true; } try @@ -179,7 +178,7 @@ bool AppInit(int argc, char* argv[]) if (fCommandLine) { fprintf(stderr, "Error: There is no RPC client functionality in komodod. Use the komodo-cli utility instead.\n"); - exit(1); + exit(EXIT_FAILURE); } #ifndef _WIN32 @@ -236,5 +235,5 @@ int main(int argc, char* argv[]) // Connect bitcoind signal handlers noui_connect(); - return (AppInit(argc, argv) ? 0 : 1); + return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/bloom.h b/src/bloom.h index a4dba8cb4..df5c30b1e 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -73,7 +73,7 @@ public: ADD_SERIALIZE_METHODS; template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(vData); READWRITE(nHashFuncs); READWRITE(nTweak); diff --git a/src/cc/CC made easy.md b/src/cc/CC made easy.md new file mode 100644 index 000000000..4158e061e --- /dev/null +++ b/src/cc/CC made easy.md @@ -0,0 +1,589 @@ +/****************************************************************************** + * Copyright © 2014-2018 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +How to write utxo based CryptoConditions contracts for KMD chains +by jl777 + +This is not the only smart contracts methodology that is possible to build on top of OP_CHECKCRYPTOCONDITION, just the first one. All the credit for getting OP_CHECKCRYPTOCONDITION working in the Komodo codebase goes to @libscott. I am just hooking into the code that he made and tried to make it just a little easier to make new contracts. + +There is probably some fancy marketing name to use, but for now, I will just call it "CC contract" for short, knowing that it is not 100% technically accurate as the CryptoConditions aspect is not really the main attribute. However, the KMD contracts were built to make the CryptoConditions codebase that was integrated into it to be more accessible. + +Since CC contracts run native C/C++ code, it is turing complete and that means that any contract that is possible to do on any other platform will be possible to create via CC contract. + +utxo based contracts are a bit harder to start writing than for balance based contracts. However, they are much more secure as they leverage the existing bitcoin utxo system. That makes it much harder to have bugs that issue a zillion new coins from a bug, since all the CC contract operations needs to also obey the existing bitcoin utxo protocol. + +This document will be heavily example based so it will utilize many of the existing reference CC contracts. After understanding this document, you should be in a good position to start creating either a new CC contract to be integrated into komodod or to make rpc based dapps directly. + +Chapter 0 - Bitcoin Protocol Basics +There are many aspects of the bitcoin protocol that isnt needed to understand the CC contracts dependence on it. Such details will not be discussed. The primary aspect is the utxo, unspent transaction output. Just a fancy name for txid/vout, so when you sendtoaddress some coins, it creates a txid and the first output is vout.0, combine it and txid/0 is a specific utxo. + +Of course, to understand even this level of detail requires that you understand what a txid is, but there are plenty of reference materials on that. It is basically the 64 char long set of letters and numbers that you get when you send funds. + +Implicit with the utxo is that it prevents double spends. Once you spend a utxo, you cant spend it again. This is quite an important characteristic and while advanced readers will point out chain reorgs can allow a double spend, we will not confuse the issue with such details. The important thing is that given a blockchain at a specific height's blockhash, you can know if a txid/vout has been spent or not. + +There are also the transactions that are in memory waiting to be mined, the mempool. And it is possible for the utxo to be spent by a tx in the mempool. However since it isnt confirmed yet, it is still unspent at the current height, even if we are pretty sure it will be spent in the next block. + +A useful example is to think about a queue of people lined up to get into an event. They need to have a valid ticket and also to get into the queue. After some time passes, they get their ticket stamped and allowed into the event. + +In the utxo case, the ticket is the spending transaction and the event is the confirmed blockchain. The queue is the mempool. + + +Chapter 1 - OP_CHECKCRYPTOCONDITION +In the prior chapter the utxo was explained. However, the specific mechanism used to send a payment was not explained. Contrary to what most people might think, on the blockchain there are not entries that say "pay X amount to address". Instead what exists is a bitcoin script that must be satisfied in order for the funds to be able to be spent. + +Originally, there was the pay to pubkey script: + + +About as simple of a payment script that you can get. Basically the pubkey's signature is checked and if it is valid, you get to spend it. One problem satoshi realized was that with Quantum Computers such payment scripts are vulnerable! So, he made a way to have a cold address, ie. an address whose pubkey isnt known. At least it isnt known until it is spent, so it is only Quantum resistant prior to the first spend. This line of reasoning is why we have one time use addresses and a new change address for each transaction. Maybe in some ways, this is too forward thinking as it makes things a lot more confusing to use and easier to lose track of all the required private keys. + +However, it is here to stay and its script is: + + +With this, the blockchain has what maps to "pay to address", just that the address is actually a base58 encoded (prefix + pubkeyhash). Hey, if it wasnt complicated, it would be easy! + +In order to spend a p2pkh (pay to pubkey hash) utxo, you need to divulge the pubkey in addition to having a valid signature. After the first spend from an address, its security is degraded to p2pk (pay to pubkey) as its pubkey is now known. The net result is that each reused address takes 25 extra bytes on the blockchain, and that is why for addresses that are expected to be reused, I just use the p2pk script. + +Originally, bitcoin allowed any type of script opcodes to be used directly. The problem was some of them caused problems and satoshi decided to disable them and only allow standard forms of payments. Thus the p2pk and p2pkh became 99%+ of bitcoin transactions. However, going from having a fully scriptable language that can create countless payment scripts (and bugs!), to having just 2... well it was a "short term" limitation. It did last for some years but eventually a compromise p2sh script was allowed to be standard. This is a pay to script hash, so it can have a standard format as the normal p2pkh, but have infinitely more flexibility. + +